SuperAPI AI Directory

sverchok-syntax-scripting

Design & creation

View repository

Updated 10-15 22:17

About this skill

sverchok-syntax-scripting

Quick Reference

Script Node Overview

Sverchok provides 4 primary scripting nodes for embedding custom Python logic in node trees:

Node ID Menu Purpose
Script Node Lite (SNLite) SvScriptNodeLite snl Inline scripting with text-based socket declarations
SN Functor B SvSNFunctorB functorB Structured scripting with init/process/draw functions
Formula Mk5 SvFormulaNodeMk5 — Safe math expression evaluation (up to 4 formulas)
Profile Mk3 SvProfileNodeMK3 — SVG-like DSL for 2D parametric profiles

Critical Warnings

NEVER use import os, import subprocess, or file-system operations inside Formula Mk5 — the safe_eval system blocks all builtins and ONLY allows whitelisted functions.

NEVER store mutable state in SNLite script-body variables across evaluations — use get_user_dict() for persistent per-node storage.

NEVER define sockets manually in SNLite (via self.inputs.new(...)) — ALWAYS use the text-based declaration syntax in the docstring header.

ALWAYS wrap SNLite output data in the correct nesting level — verts = [[(x,y,z), ...]] not verts = [(x,y,z), ...].

ALWAYS use functor_init() (not __init__) to create sockets in SN Functor B scripts.

ALWAYS end Profile Mk3 H and V commands with a semicolon ;.

Decision Tree

Need custom Python logic in a node tree?
├── Quick prototype / simple transform → SNLite
├── Need custom UI + multiple properties → SN Functor B
├── Math expression only (no logic) → Formula Mk5
└── 2D parametric shape / architectural profile → Profile Mk3

Writing an SNLite script?
├── Need persistent storage → get_user_dict()
├── Need one-time init → setup() function
├── Need custom UI → ui(self, context, layout) function
├── Need BMesh operations → bmesh_from_pydata / pydata_from_bmesh aliases
└── Need NumPy performance → np alias (pre-imported)

Choosing SNLite vs Functor B?
├── Simple I/O, few properties → SNLite
├── Need > 2 enums or typed properties → Functor B (5x int/float/bool)
├── Need full self access in process() → Functor B
└── Learning / quick iteration → SNLite

SNLite: Socket Declaration Syntax

Declaration Format

Socket declarations go in the script's opening docstring:

"""
in  socket_name  type  [default=value]  [nested=level]  [required=True]
out socket_name  type
"""

Socket Type Identifiers

ID Socket Class Data Type
s SvStringsSocket Scalars, integers, generic numeric
v SvVerticesSocket 3D coordinates (x, y, z)
m SvMatrixSocket 4x4 transformation matrices
o SvObjectSocket Blender object references
C SvCurveSocket Curve objects
S SvSurfaceSocket Surface objects
So SvSolidSocket Solid objects (FreeCAD)
SF SvScalarFieldSocket Scalar field functions
VF SvVectorFieldSocket Vector field functions
D SvDictionarySocket Python dictionaries
FP SvFilePathSocket File path strings

Declaration Options

Option Syntax Effect
Default value default=1.0 or ;=1.0 Value when socket unconnected
Nesting level nested=2 or n=2 0=raw, 1=list, 2=list of lists
Required required=True Node skips processing if unconnected
Display name 5th positional element Custom label in UI

Built-in Aliases

These names are pre-imported and available in every SNLite script:

vectorize           # sverchok.utils.snlite_utils — auto-vectorize functions
bpy                 # Blender Python API
np                  # NumPy
bmesh_from_pydata   # Build BMesh from verts/edges/faces lists
pydata_from_bmesh   # Extract verts/edges/faces from BMesh
get_user_dict       # Persistent per-node dict storage
reset_user_dict     # Clear per-node storage (hard=True clears all)
cprint              # Console output (alias: console_print)
ddir                # Filtered dir() utility
sv_njit             # Numba JIT compilation wrapper
sv_njit_clear       # Clear Numba JIT cache

Special Functions

setup() — Runs once on script load. Return values persist via return locals():

def setup():
    import random
    seed_data = [random.random() for _ in range(100)]
    return locals()
# seed_data is now available in the main script body

ui(self, context, layout) — Custom node panel UI:

def ui(self, context, layout):
    layout.label(text="My Custom Node")
    layout.prop(self, "custom_enum")

sv_internal_links(self) — Controls pass-through when node is muted:

def sv_internal_links(self):
    return [(self.inputs[0], self.outputs[0])]

Additional Features

Custom enums (maximum 2 per script):

"""
enum mode = Add Subtract Multiply
in  value s  default=1.0
out result s
"""
if mode == "Add":
    result = [[v + 1 for v in value]]

File handler — adds a text datablock selector to the UI:

"""
display_file_handler
in  scale s  default=1.0
out verts v
"""

Includes — import other Blender text datablocks:

"""
includes: helper_functions.py, config.py
in  data s
out result s
"""

Persistent storage via get_user_dict():

"""
in  trigger s  default=0
out count   s
"""
storage = get_user_dict()
if 'counter' not in storage:
    storage['counter'] = 0
storage['counter'] += 1
count = [[storage['counter']]]

Template System

SNLite templates are located in node_scripts/SNLite_templates/ with categories:

Category Content
demo Spirals, voronoi, genetic algorithms
bpy_stuff Blender API interaction
bmesh BMesh geometry manipulation
utils DXF export, IFC export, SVG import
templates Reusable script patterns

SN Functor B: Structured Scripting

Three-Function Architecture

import bpy
from sverchok.data_structure import updateNode

def functor_init(self, context):
    """Called once when script is loaded. Define sockets here."""
    self.inputs.new('SvStringsSocket', 'radius')
    self.inputs.new('SvStringsSocket', 'segments')
    self.outputs.new('SvVerticesSocket', 'verts')
    self.outputs.new('SvStringsSocket', 'edges')

def process(self):
    """Called on each evaluation. Read inputs, write outputs."""
    if not self.inputs['radius'].is_linked:
        return
    radius_data = self.inputs['radius'].sv_get()
    # ... processing logic ...
    self.outputs['verts'].sv_set(all_verts)

def draw_buttons(self, context, layout):
    """Optional custom UI in the node body."""
    layout.prop(self, 'float_00', text='Scale')
    layout.prop(self, 'int_00', text='Count')

Pre-defined Properties

Functor B provides 15 pre-defined properties (5 of each type), all with update=updateNode:

Property Type Range
int_00 — int_04 IntProperty 0–4 index
float_00 — float_04 FloatProperty 0–4 index
bool_00 — bool_04 BoolProperty 0–4 index

Access in draw_buttons: layout.prop(self, 'float_00', text='My Label') Access in process: scale = self.float_00

SNLite vs Functor B

Feature SNLite Functor B
Socket definition Docstring declarations functor_init()
Process logic Script body process(self)
UI customization ui() draw_buttons()
Properties 2 custom enums 5x int + 5x float + 5x bool
Self access Limited (via aliases) Full self reference
Initialization setup() functor_init()
Best for Quick prototyping Complex custom nodes

Formula Mk5: Expression Evaluation

Basic Usage

The Formula node evaluates Python math expressions with safety restrictions. Supports 4 simultaneous formulas. Variables in expressions automatically become input sockets.

Formula 1: x + 1
Formula 2: R * sin(phi)
Formula 3: 0.75 * X + 0.25 * Y
Formula 4: [v**2 for v in range(n)]

Safe Evaluation Environment

The safe_eval() system blocks ALL Python builtins and ONLY allows:

Math functions: acos, acosh, asin, asinh, atan, atan2, atanh, ceil, copysign, cos, cosh, degrees, erf, erfc, exp, expm1, fabs, factorial, floor, fmod, frexp, fsum, gamma, hypot, isfinite, isinf, isnan, ldexp, lgamma, log, log10, log1p, log2, modf, pow, radians, sin, sinh, sqrt, tan, tanh, trunc

Constants: pi, e

Utility functions: abs, sign, max, min, len, sum, zip, any, all, dir

Type constructors: int, float, str, list, tuple, dict, set

Objects: Vector, Matrix, np (NumPy), bpy

Output Configuration

Property Values Purpose
output_dimensions 1–4 Number of active formula slots
output_type Number/Generic, Vertices, Matrices Output socket type
wrapping -1, 0, +1 Output nesting level adjustment

NumPy Mode

When enabled, math functions use NumPy array variants (sin → np.sin), enabling vectorized computation on arrays instead of scalar-by-scalar evaluation.


Profile Mk3: SVG-like 2D Profiles

DSL Command Reference

Command Syntax Description
M / m M x y Move to (absolute / relative)
L / l L x y [n=segments] [z] Line to
H / h H x [n=segments] ; Horizontal line (semicolon required)
V / v V y [n=segments] ; Vertical line (semicolon required)
C / c C x1 y1 x2 y2 x y [n=verts] [z] Cubic Bezier
S / s S x2 y2 x y [n=verts] [z] Smooth cubic Bezier
Q / q Q x1 y1 x y [n=segments] [z] Quadratic Bezier
T / t T x y [n=segments] [z] Smooth quadratic Bezier
A / a A rx ry rot flag1 flag2 x y [n=verts] [z] Arc
@I / @i @I [@smooth] degree p1 p2 ... [n=segments] [z] ; NURBS interpolation
X X Close path cyclically
# # comment text Single-line comment

Variable System

default width = 0.3          # Becomes input socket with default value
default height = 2.7         # Becomes input socket with default value
let half_width = {width / 2} # Computed variable, does NOT become socket
let ft = {flange_thickness}  # Reusable shorthand

M -{half_width} 0            # Use variables in commands
L {width + margin} {height}  # Expressions in curly braces
  • default variables become input sockets (auto-created)
  • let variables are computed internally — NEVER become sockets
  • Expressions use {curly braces} for inline math
  • close_threshold property (default 0.0005) detects overlapping start/end vertices

Architectural Profile Example: I-Beam

default width = 0.2
default height = 0.4
default flange_thickness = 0.02
default web_thickness = 0.01

let hw = {width / 2}
let hh = {height / 2}
let ft = {flange_thickness}
let wt = {web_thickness / 2}

M -{hw} -{hh}
L {hw} -{hh}
L {hw} {-hh + ft}
L {wt} {-hh + ft}
L {wt} {hh - ft}
L {hw} {hh - ft}
L {hw} {hh}
L -{hw} {hh}
L -{hw} {hh - ft}
L -{wt} {hh - ft}
L -{wt} {-hh + ft}
L -{hw} {-hh + ft}
X

Other Script Nodes

Node Source Purpose
Generative Art generative_art.py L-System generative art via XML rules
Formula Interpolate formula_interpolate.py Interpolated formulas over ranges
Mesh Expression mesh_eval.py Mesh generation from JSON structures
Multi Exec multi_exec.py Multiple sequential Python expressions
NumExpr numexpr_node.py Accelerated expressions via numexpr library

Reference Links

Official Sources