Skip to content

AICodeDev/geonodes

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

geonodes

Scripting Geometry Nodes for Blender

Short

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.

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

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 distance of the vertex to the center.

import geonodes as gn

with gn.Tree("Geometry Nodes") as tree:

    # Let's document our parameters
    count  = 100  # Grid resolution
    size   = 20   # Size
    omega  = 2.   # Period
    height = 2.   # Height of the surface
    
    # The base (x, y) grid
    grid = gn.Mesh.Grid(vertices_x=count, vertices_y=count, size_x=size, size_y=size).mesh
    
    # We compute z
    with tree.layout("Computing the wave", color="dark_rose"):
        distance = gn.sqrt(grid.verts.position.x**2 + grid.verts.position.y**2)
        z = height * gn.sin(distance*omega)/distance
        
    # Let's change the z coordinate of our vertices
    grid.verts.position += (0, 0, z)
    
    # We are done: plugging the deformed grid as the modified geometry
    tree.output_geometry = grid.set_shade_smooth()
               

See Demo details

The generated nodes and the result of the Geometry nodes modifier is given below:

Installation

geonode 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/
               nodes/
               sockets/
               ...

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

import geonodes as gn

gn is the recommended alias for geonodes.

Documentation

Uses index to gain access to the list of availables classes.

Scripting geometry

Geometry nodes are global functions operating on geometry passed through sockets.

geonodes presents the nodes sockets as classes and the nodes as methods.

Rather than thinking : "What are the inputs of the 'Set Curve Tilt' node to change the tilt of spline #2?", you take benefit of an object oriented language and simply write:

curve.splines[2].tilt = 1

Geometry classes

The geometry classes are:

Domains

In geometry nodes, attributes refer to domains such as Point, Corner, Face, Spline...

geonodes implement domains as properties of geometry classes.

Attributes are properties or domain properties, for instances:

mesh.verts.position += (0, 0, 1)        # All the mesh points are moved 1 upwards (node 'Set Position')
cloud = mesh.faces.distribute_points()  # Node 'Distribute Points on Faces'
mesh.edges.extrude()                    # Node 'Extrude Mesh' with option 'Edges'
curve.splines.type = 'BEZIER'           # Curve splines type to BEZIER
curve.points.handle_type = 'FREE'       # Curve handle type to FREE
instances.insts[0].position = (1, 2, 3) # The instance # 0 is set at position (1, 2, 3)

Note 1: Mesh and Curve have several domains, respectively (verts, faces, edges, *corners) and (splines, points), when Points and Instances have only one domain each, respectively points and insts.

Values

To manipulate geometry, the available classes are:

These values are used as arguments of geometry and domain classes. With the notable exception of Booleans, the values can be manipulated with python operators:

import geonodes as gn

with gn.Tree("Geometry Nodes") as tree:

    count = gn.Integer.Input(2, "Subdivisions")     # Creation of a modifier input parameter
    
    sphere = gn.Mesh.IcoSphere(subdivisions=count)  # Creation primitives are implemented as class static methods
    n = sphere.verts.count                          # count is generated with node 'Attribute statistic'
    v = gn.sqrt(n + 10)                             # Standard math functions are available as global functions
                                                    # standard operators can be used between values or between values and python data
    
    label = (gn.String("The square root of the number of vertices + 10 is: ") + gn.String.Value(v, 3)).to_curves().curve_instances
    
    location = gn.Vector()                          # Creation of null vector
    location += (1, v, 3)                           # Triplets can be used. Triplets can include geonodes types
    
    label.transform(translation=location, rotation=(gn.pi/2, 0, 0))
    
    tree.output_geometry = label + sphere           # Addition between geometries is implemented with the node 'Join Geometry'
                                                    # Setting the output_geometry property defines the ouput geometry

Booleans

geonodes Booleans can't be manipulated with standard python operators:

a = gn.Boolean(True)
b = gn.Boolean(False)
c = a or b            # No logical operation is performed, c has the value of a
d = gn.b_or(a, b)     # The right instruction to compute a logical operation in geometry nodes
d = a.b_or(b)         # Alternative syntax: boolean operators are also implemented as methods

Similary, logical operations between values can't be used:

i = gn.Integer(10)
a = i == 10           # a is a python bool, not a geonodes Boolean
b = i.equal(10)       # Correct way to compare two values in geonodes

To ease the way to implement logical operations in geonodes, +, - and * can be used as alernative to or, not and and:

a = gn.Boolean(True)
b = gn.Boolean(False)
c = a + b      # a or b
d = a * b      # a and b
e = -a         # not a

Other sockets

Other data are available through the following classes:

Naming

geonodes classes and properties are named after the Blender names.

  • Nodes classes are CamelCase versions of Blender geometry nodes name:
    • Node 'Set Shade Smooth' --> SetShadeSmooth
  • Methods calling a node are snake_case of the Blender name:
    • mesh.set_shade_smooth()
  • Node sockets are snake_case of their Blender name:
    • Socket 'Mesh' --> mesh

For more details, refer to Naming conventions

About

Create Blender geometry nodes with python script

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 100.0%