SkillAgentSearch skills...

Geonodes

Create Blender geometry nodes with python script

Install / Use

/learn @al1brn/Geonodes
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

geonodes

Scripting Geometry Nodes for Blender

Short

Last Blender version supported: Blender V5

Geometry Nodes is a powerful Blender feature allowing the creation of amazing 3D models. However, nodes trees can rapidly look like a spaghetti plate difficult to understand and to maintain; complex formulas are not easy to build; and debugging can be a headache.<br>

The purpose of geonodes is to to create geometry nodes with python scripts.<br>

You keep the full power of Blender Geometry Nodes but with the elegance of Python.

Table of contents

Better a demo than long words

The following script creates a surface from a grid by computing z = sin(d)/d where d=sqrt(x^2 + y^2) is the vertex distance to the center.

<img src="doc/images/hello_world_black.png" width="600" class="center">
from geonodes import *

# Create the Geometry Nodes named "Hello World"

with GeoNodes("Hello World"):
    
    height = 3
    omega  = 2

    # The surface is basically a grid 20 x 20 with a resolution 200 x 200
    grid = Mesh.Grid(vertices_x=200, vertices_y=200, size_x=20, size_y=20)
    

    # z is computed using gnmath library and operators as in pure python
    with Layout("Computing the wave"):
        pos = nd.position
        distance = gnmath.sqrt(pos.x**2 + pos.y**2)
        z = height*gnmath.sin(distance*omega)/distance

    # Let's change the z coordinate of our vertices
    with Layout("Point offset and smoothness"):
        grid.offset = (0, 0, z)
        grid.faces.smooth = True

    # We are done: plugging the deformed grid as the modified geometry
    grid.out()

The generated nodes are shown below:

<img src="doc/images/hello_world_nodes.png" width="600" class="center">

Installation

geonodes is a python package. To install it, copy the package folder geonodes in scripts/modules.

The Blender scripts folder is defined in Blender preferences, see: Blender File Paths settings.

Note that geonodes is a python module, not an Blender addon

After the install, the Blender scripts hierarchy should look like:

.../scripts/
       modules/
           geonodes/
               __init__.py
               core
               demos
               ...

To make the module available in your script, use import in your script:

from geonodes import *

Scripting nodes overview

All nodes belong to a tree. Two tree types are available:

Tutorial

[!IMPORTANT] Geometry Nodes modifiers and groups scripted by geonodes don't overwrite existing modifier or groups.

[!CAUTION] But shaders scripted by geonodes can overwrite an existing material.

Prerequisites

To get the maximum benefit of GeoNodes, you must be familiar with both python and Blender Geometry Nodes.

How it works

Each Geometry Nodes output socket is wrapped by a class:

  • A Float instance keeps a reference to an output socket of type VALUE
  • A Geometry instance keeps a reference to an output socket of type GEOMETRY

Geometry Nodes are methods, functions or operators working on the GeoNodes classes. The arguments of a method are connected to the input sockets of the node. The method returns a class refering to one of its output socket, or, rarely, to the node itself.

from geonodes import *

with GeoNodes("Socket Init"):

    # Get the Group Input geometry
    geometry = Geometry()

    # Plug the geometry to the Group output node
    geometry.out()

    # Create sockets from their node primitives
    with Layout("Primitives"):
        i = Integer(123)
        f = Float(3.14)
        s = String("A string")
        b = Boolean(True)
        v = Vector((1, 2, 3))
        red = Color("Red")
        green = Color("#00FF00")
        blue = Color((0, 0, 1))
        r = Rotation((pi, pi, pi/2))

    # The key word argument name indicates the following are Group input sockets
    # The value is the default value
    i = Integer(123, name = "Integer")
    f = Float(3.14, name = "Float")
    s = String("A string", name = "String")
    b = Boolean(True, name = "Boolean")
    v = Vector((1, 2, 3), name = "Vector")
    red = Color("Red", name = "Color 0")
    green = Color("#00FF00", name = "Color 1")
    blue = Color((0, 0, 1), name = "Color 2")
    r = Rotation((pi, pi, pi/2), name = "Rotation")

    # If the initial value is a string, the value is a named attribute
    # Named Attribute 'Integer'
    with Layout("Named Attributes"):
        i = Integer("Integer")
        # Named Attribute 'Float'
        f = Float("Float")

    # Creating Geometries
    with Layout("Creating geometries"):
        cube = Mesh.Cube()
        curve = Curve.Spiral()

Blender Setup

Create a new script in Scripting tab in Blender. You can setup this tab in order to display:

  • A Text editor for python scripting
  • A 3D Viewport to view the progress
  • A Python Console to dump variables
  • A Geometry Node Editor to view the generated nodes

Here after is an example of the recommanded setup:

<img src="doc/images/blender_setup.png" width="600" class="center">

'Do Nothing' Modifier

Copy / paste the following piece of code to check that everything is properly setup:

from geonodes import *

with GeoNodes("Do Nothing"):
    Geometry().out()

A Geometry Nodes modifier has been created with the name "Do Nothing". You can use it on any object.

[!NOTE] All scripts are supposed to start with from geonodes import *. Then, nodes must be created only in the sccope of with context.

All the code samples must be placed after the following lines:

from geonodes import *

with GeoNodes("Tutorial"):
    pass

Modules and Classes

'gnmath' module

gnmath provides the mathematical functions, basically the operations performed by Math, Integer Math, Vector Math and Boolean Math nodes.

Math functions are named after their standard name in python math module.

[!NOTE] Vector functions having the same name as their Float equivalent are prefixed with the letter v Integer functions having the same name as their Float equivalent are prefixed with the letter i All bitwise Integer operations are prefixed with bw_

    with GeoNodes("gnmath"):
        a = Float(1)
        b = gnmath.sin(a)
        
        # Add between two Floats
        c = gnmath.add(b, 7.5)

        i = Integer(123)
        # Greater Common Divisor exists only for Integers
        j = gnmath.gcd(i, 17) 
        
        # Add exists also for Floats
        k = gnmath.iadd(j, 7)
        
        u = Vector((1, 2, 3))
        # Cross product exists only for vectors
        v = gnmath.cross(u, (7, 8, 9))
        # Add axists also for Floats
        w = gnmath.vadd(v, (5, 6,7))

        # Bitwise functions
        j = gnmath.bw_and(i, 7)        

[!NOTE] Similarly Boolean functions and, or and not are prefixed by the letter b

    a = Boolean(True)
    b = gnmath.xor(a, False)
    c = gnmath.band(b, False)
    d = gnmath.band(b, False)

[!NOTE] Math functions are also available as methods and some of them as operators.

The following example gives the same result as the two previous ones:

    a = Float(1)
    b = a.sin()
    c = b + 7.5

    i = Integer(123)
    j = i.gcd(17) 
    k = j + 7
    
    u = Vector((1, 2, 3))
    v = u.cross((7, 8, 9))
    w = v + (5, 6,7)
    
    
    a = Boolean(True)
    b = a.xor(False)
    # and operator is implemented with & 
    c = b & False
    # or operator is implemented with |
    d = b | False

'nd' Class

nd class (shortcut for nodes) exposes all the nodes as class methods. This class is particuliarly usefull for input nodes such as Position or Radius:

cube = Mesh.Cube() # or nd.cube()
new_pos = nd.position + (1, 2, 3)
cube.set_position(new_pos)

Data Classes

Each Geometry Nodes socket type is wrapped in a dedicated class. The available classes are the following:

  • Basic sockets
    • Attributes : Boolean, Integer, Float, Vector, Color, Rotation, Matrix,
    • String
  • Blender Resources
    • Material, Object, Texture, Collection, Image
  • Geometry
    • Geometry
    • Geometry subclasses : Mesh, Curve, GreasePencil, Cloud, Instances, Volume
  • Special
    • Menu, Closure, Bundle

Blender Nodes are implemented as methods, properties and operators working on these classes. For instance, if a and b are two Floats, the script a + b will generate a Math node with operation ADD. The result of this operation is the Output Socket of the node.

Domains

Geometry classes have one or several Domain attributes following Blender data structure. The domains are the following:

  • Mesh
    • points
    • faces
    • edges
    • corners
  • Curve
    • points
    • splines
  • GreasePencil
    • layers
  • Cloud
    • points
  • Instances
    • insts
  • Volume

The Domain attribute is used in nodes having a Domain parameter. In the following example, the node 'Store Named Attribute' is setup with the domain calling the method:

      # Create a Cube
      mesh = Mesh.Cube()

      # Store on domain POINT
      mesh.points.store_named_attribute("Point Value", 0.)

      # Store on domain FACE
      mesh.faces.store_named_attribute("Face Value", 0.)

[!NOTE] A Domain is never instanced directly, it is always initialized as a property of a Geometry Class.

Operators

Python operators can be used to operate on

View on GitHub
GitHub Stars130
CategoryDevelopment
Updated8d ago
Forks12

Languages

Python

Security Score

80/100

Audited on Mar 26, 2026

No findings