geometry-script icon indicating copy to clipboard operation
geometry-script copied to clipboard

Geometry Nodes -> Geometry Script conversion

Open carson-katri opened this issue 2 years ago • 1 comments
trafficstars

Adds an operator to convert the opposite direction, Geometry Nodes -> Geometry Script.

In the node editor, press the "Convert to Geometry Script" button in the top right. This will automatically create a text datablock with the same name as the node tree.

Note This has not been tested with more complex node trees, so YMMV.

Examples

Here is a simple example of a generated script.

Screenshot 2023-03-01 at 7 43 01 PM
from geometry_script import *

@tree("Random Cubes")
def random_cubes(geometry: Geometry):
    r1 = random_value(min=0.0, max=10.0, seed=0, data_type="FLOAT")
    m1 = cube(size=(1.0, 1.0, 1.0), vertices_x=2, vertices_y=2, vertices_z=2)
    r2 = random_value(min=(0.0, 0.0, 0.0), max=(0.5, 0.5, 0.5), seed=3, data_type="FLOAT_VECTOR")
    c1 = combine_xyz(x=4.199999809265137, y=0.0, z=0.0)
    d1 = distribute_points_on_faces(seed=0, distribute_method="RANDOM", mesh=geometry, density=r1)
    i1 = instance_on_points(pick_instance=False, rotation=(0.0, 0.0, 0.0), points=d1.points, instance=m1, scale=r2)
    t1 = translate_instances(local_space=True, instances=i1, translation=c1)
    return { "geometry": t1 }

TODOs

Some of these may be added in future PRs.

Better Variables Names

Here's one possible naming scheme, in order of precedence:

  1. If the node has a custom "Label", use that as the variable name.
  2. If only one socket is used, use the name of the socket and an index.
  3. Otherwise, use the name of the node and an index.

Indexes would only be used if there are duplicate names or a collision with a function name. Otherwise they can be elided.

Inlining

If a node only has a single link that connects to its outputs, inline its call into the use-site. For example, this section:

def random_cubes(geometry: Geometry):
    ...
    r1 = random_value(min=0.0, max=10.0, seed=0, data_type="FLOAT")
    d1 = distribute_points_on_faces(seed=0, distribute_method="RANDOM", mesh=geometry, density=r1)

with inlining would transform to this:

def random_cubes(geometry: Geometry):
    ...
    d1 = distribute_points_on_faces(seed=0, distribute_method="RANDOM", mesh=geometry, density=random_value(min=0.0, max=10.0, seed=0, data_type="FLOAT"))

carson-katri avatar Mar 02 '23 01:03 carson-katri

PR Preview Action v1.3.0 :---: :rocket: Deployed preview to https://carson-katri.github.io/geometry-script/pr-preview/pr-13/ on branch gh-pages at 2023-03-02 01:30 UTC

github-actions[bot] avatar Mar 02 '23 01:03 github-actions[bot]