Changelog

Unreleased

Enhancements

  • Refactor the mermaid diagram generation. Change screenshot.py -> diagram.py and added test coverage

v0.10.2 - 2026-04-21

Enhancements

  • Added changelog to the documentation to better track and explain changes in the project.
  • Support len(tree.inputs) and len(tree.outputs) to get the number of inputs and outputs in the tree. (#43)
  • Added the GPLv3 license to the project.

v0.10.1 — 2026-04-20

Bug fixes

  • Fixed CaptureAttribute.capture() not correctly linking the captured input socket. (#41)

v0.10.0 — 2026-04-19

The biggest release yet. The headline change is a new typed socket accessor API — node.i.x / node.o.x — that replaces the old node.o_position-style properties and brings full IDE auto-complete and type narrowing to socket access.

Enhancements

node.i / node.o socket accessors (#39)

Sockets are now accessed through .i (inputs) and .o (outputs) accessor objects. Attribute names are the normalised socket identifier, so spaces become underscores and the first letter is lowercased.

node.o.position >> node.i.offset   # pipe position into offset
node.o.position.y * 0.2            # operate on the y component

In node definitions, _Inputs / _Outputs inner classes declare the available sockets and their types so IDEs can provide auto-complete:

class SetPosition(NodeBuilder):
    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        position: VectorSocket
        offset:   VectorSocket

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket

NodeGroupBuilder — custom node groups as Python classes (#31)

Define reusable node groups as plain Python classes. The group tree is built once and cached; subsequent uses insert a Group node pointing at that tree.

class Jitter(NodeGroupBuilder):
    _name = "Jitter"
    _color_tag = "geometry"

    def __init__(self, geometry=None, amount=0.2, seed=0):
        super().__init__(Geometry=geometry, Amount=amount, Seed=seed)

    @classmethod
    def _build_group(cls, tree):
        geom   = tree.inputs.geometry("Geometry")
        amount = tree.inputs.float("Amount", 0.2)
        seed   = tree.inputs.integer("Seed", 0)

        offset = g.RandomValue.vector(min=-1, seed=seed) * amount
        _ = g.SetPosition(geom, offset=offset) >> tree.outputs.geometry()

# Composes identically with built-in nodes
g.IcoSphere(subdivisions=4) >> Jitter(amount=0.15) >> out

g.tree() module-level helper (#36)

Eliminates the need to import TreeBuilder directly when working with a single editor type.

# Before
from nodebpy import TreeBuilder
with TreeBuilder.geometry("My Group") as tree: ...

# After
from nodebpy import geometry as g
with g.tree("My Group") as tree: ...

Simplified interface socket definition (#37)

Interface sockets can now be defined directly on the tree object without a context manager:

with g.tree() as tree:
    geo = tree.inputs.geometry("Points")
    g.SetPosition(geo)

The previous context-manager form still works.

Other changes

  • Auto-detection of nodes requiring data-type class methods (e.g. .float(), .vector()) is now more robust. (#38)
  • builder.py was split into a builder/ package for maintainability; VectorSocketLinker was renamed to VectorSocket. (#35)
  • Internal type aliases cleaned up — InputFloat replaces TYPE_INPUT_VALUE etc. (#34)

v0.9.1 — 2026-03-27

Enhancements

== / != comparison operators (#28)

NodeBuilder objects now support Python equality operators, returning a Compare node. Chain .switch() to immediately branch on the result:

# Creates a Compare node then routes into a Switch
(g.Value(5.0) > 2.0).switch(false=g.Cube(), true=g.IcoSphere())

Data-type-specific socket linkers (#29)

VectorSocket, ColorSocket, FloatSocket, and IntegerSocket carry type-specific operations (e.g. .x, .y, .z on vectors) so arithmetic stays typed all the way through a chain.

Other changes

  • Documentation styling improvements. (#27)

v0.8.0 — 2026-03-16

Enhancements

networkx is now an optional dependency (#24)

nodebpy now has no hard dependencies outside of bpy, making it easier to vendor into add-ons. A built-in simple arranger is used when networkx is absent; the Sugiyama layout remains the default when it is installed.


v0.7.2 — 2026-03-15

Enhancements

matrix @ vector creates a TransformPoint node (#22)

matrix @ g.Position()  # → TransformPoint node

Bug fixes

  • Fixed ... (ellipsis) handling in >> chains — type-aware output selection now works correctly when skipping intermediate nodes. (#23)

v0.7.1 — 2026-03-14

Enhancements

Color >> Shader linking (#21)

Piping a color socket into a shader input is now handled automatically, matching the way Blender promotes color connections in the node editor.


v0.7.0 — 2026-03-13

Enhancements

Panels for tree interfaces (#20)

Group interface sockets can be organised into named panels:

with tree.inputs.panel("Settings"):
    s.SocketFloat("Amount", 0.2)
    s.SocketInt("Seed", 0)

Integer math is now handled correctly in Shader and Compositor editors (mapped to float math, as Blender does not expose integer math there).


v0.6.0 — 2026-03-13

Bug fixes

  • Fixed MenuSwitch node creation and socket wiring. (#18)

Other changes

  • Mermaid diagram generation improvements: math node operators are now shown, and socket connections use -> instead of >>. (#19)

v0.5.0 — 2026-03-13

Enhancements

Compositor and Material (Shader) node editors (#12)

nodebpy now supports building Compositor and Shader/Material node trees in addition to Geometry Nodes.

Remaining Python math operators (#15, #16)

** (power), % (modulo), // (floor divide), abs(), and unary - are all wired up. Operator order for vector math was also corrected.

Literal type hints for menu sockets (#17)

Enum choices on menu sockets are exposed as Literal type hints, giving IDE auto-complete on string arguments like data_type="FLOAT".