Skip to content

ScriptNode RX cookbook

Dealga McArdle edited this page Feb 9, 2017 · 15 revisions

Icosphere

import bmesh
from svrx.util.geom import generator
from svrx.util.mesh import rxdata_from_bm

def make_icosphere(subdiv, diam):
    bm = bmesh.new()
    bmesh.ops.create_icosphere(bm, subdivisions=subdiv, diameter=diam, calc_uvs=False)
    return rxdata_from_bm(bm)

@node_script
@generator
def sn_icosphere(subdiv: Int(min=0, max=5) = 2, diam: Float = 1.0) -> ([Vertices], [Edges], [Faces]):
    return make_icosphere(min(subdiv, 5), diam)  

Torus

version 1

This demonstrates how you might chain / compose a number of bmesh.ops together to produce a more complex mesh than you started with.

from math import radians

import bmesh
from mathutils import Matrix

from svrx.util.geom import generator
from svrx.util.mesh import rxdata_from_bm

def make_torus(maj_segs, min_segs, maj_rad, min_rad):
    matrix_rotate = Matrix.Rotation(radians(90.0), 3, 'Y')
    axis = (0,0,1)
    dvec = cent = (0,0,0)
    angle = radians(360)

    bm = bmesh.new()
    bmesh.ops.create_circle(bm, cap_ends=False, diameter=min_rad*2, segments=min_segs)
    bmesh.ops.rotate(bm, cent=cent, matrix=matrix_rotate, verts=bm.verts[:])
    bmesh.ops.translate(bm, vec=(0,maj_rad,0), verts=bm.verts[:])
    bmesh.ops.spin(
        bm, geom=bm.verts[:]+bm.edges[:],
        cent=cent, axis=axis, dvec=dvec, angle=radians(360),
        steps=maj_segs, use_duplicate=0
    )
    bmesh.ops.remove_doubles(bm, verts=bm.verts[:], dist=0.0001)

    return rxdata_from_bm(bm)

@node_script
@generator
def sn_make_torus(
    maj_segs: Int = 10,
    min_segs: Int = 6,
    maj_rad: Float = 1.0,
    min_rad: Float = 0.2) ->  ([Vertices], [Edges], [Faces]):
    return make_torus(maj_segs, min_segs, maj_rad, min_rad)  

version 2

here's an example of importing functions from sverchok 0.5.9 and using them in rx:

from sverchok.nodes.generator.torus import torus_verts, torus_edges, torus_polygons

from svrx.util.geom import generator
from svrx.util.smesh import SMesh

def make_torus(R, r, N1, N2, rPhase, sPhase):
    v = torus_verts(R, r, N1, N2, rPhase, sPhase, False)[0]
    e = torus_edges(N1, N2)
    f = torus_polygons(N1, N2)
    return SMesh.from_pydata(v, e, f).as_rxdata

@node_script
@generator
def sn_torus(
    R: Float = 2.0, r: Float = 0.6, 
    N1: Int = 22, N2: Int = 15, 
    rPhase: Float = 0.0,
    sPhase: Float = 0.0) -> ([Vertices], [Edges], [Faces]):
    return make_torus(R, r, N1, N2, rPhase, sPhase)

From script to node

Below is a script for doing linear interpolation.

import numpy as np

from svrx.util.geom import LinearSpline

@node_script
def linear_spline(verts: Vertices = Required,
                  t: Float = 0.5,
                  ) -> Vertices:
    spl = LinearSpline(verts[:,:3])
    points_out = np.ones((len(t), 4), dtype=np.float64)
    points_out[:, :3] = spl.eval(t)
    return points_out

To turn this into a node the following changes need to be implemented.

  1. Import needs to be explicit
  2. node_script changes to node_func
  3. A bl_idname needs to be set. It must start with SvRx.
  4. Place into a file in nodes/<subdir>
  5. Note that the function itself is unchanged.
  6. It will automatically appear in the menu when you restart blender.

Full node below

import numpy as np

from svrx.typing import Vertices, Float, Required
from svrx.util.geom import LinearSpline
from svrx.nodes.node_base import node_func


@node_func(bl_idname='SvRxMyInterpolNode')
def linear_spline(verts: Vertices = Required,
                  t: Float = 0.5,
                  ) -> Vertices:
    spl = LinearSpline(verts[:,:3])
    points_out = np.ones((len(t), 4), dtype=np.float64)
    points_out[:, :3] = spl.eval(t)
    return points_out
Clone this wiki locally