88left as empty instance geometry, and that a corner instance sits at its
99closed-form grid coordinate.
1010
11+ ``--one-cell`` builds a 1x1 grid and still asserts 3x3 realized topology,
12+ so the corner instance is missing. That is the falsifier
13+ (``--same-axis`` in export-preset-axis).
14+
1115By default it runs only the correctness check (no render) — the CI smoke
1216check. Pass --output to also render a still:
1317
1418 blender --background --python gn_instance_grid.py -- # check only
19+ blender --background --python gn_instance_grid.py -- --one-cell # must fail
1520 blender --background --python gn_instance_grid.py -- --output g.png # + render
1621"""
1722import bpy , bmesh , sys , os , math , argparse
3136CORNER_CENTER = (GRID_HALF , GRID_HALF , CUBE_SIZE / 2 )
3237
3338
34- def build_instance_grid_tree (material = None ):
39+ def build_instance_grid_tree (material = None , grid_x = GRID_X , grid_y = GRID_Y ):
3540 tree = bpy .data .node_groups .new ("InstanceGrid" , 'GeometryNodeTree' )
3641 # generative: no Group Input — the tree owns the geometry
3742 tree .interface .new_socket (
@@ -42,8 +47,8 @@ def build_instance_grid_tree(material=None):
4247 grid = tree .nodes .new ('GeometryNodeMeshGrid' )
4348 grid .inputs ["Size X" ].default_value = GRID_SIZE
4449 grid .inputs ["Size Y" ].default_value = GRID_SIZE
45- grid .inputs ["Vertices X" ].default_value = GRID_X
46- grid .inputs ["Vertices Y" ].default_value = GRID_Y
50+ grid .inputs ["Vertices X" ].default_value = grid_x
51+ grid .inputs ["Vertices Y" ].default_value = grid_y
4752
4853 cube = tree .nodes .new ('GeometryNodeMeshCube' )
4954 cube .inputs ["Size" ].default_value = (CUBE_SIZE , CUBE_SIZE , CUBE_SIZE )
@@ -75,7 +80,7 @@ def build_instance_grid_tree(material=None):
7580 return tree
7681
7782
78- def build ():
83+ def build (one_cell = False ):
7984 bpy .ops .wm .read_factory_settings (use_empty = True )
8085 # carrier mesh is unused by the generative tree; one vertex is enough
8186 me = bpy .data .meshes .new ("Carrier" )
@@ -89,7 +94,8 @@ def build():
8994 bsdf .inputs ["Base Color" ].default_value = (0.22 , 0.95 , 0.06 , 1.0 ) # lime
9095 bsdf .inputs ["Roughness" ].default_value = 0.22
9196
92- tree = build_instance_grid_tree (material = mat )
97+ gx = gy = 1 if one_cell else GRID_X
98+ tree = build_instance_grid_tree (material = mat , grid_x = gx , grid_y = gy )
9399 mod = obj .modifiers .new ("instance_grid" , 'NODES' )
94100 mod .node_group = tree
95101 return obj , mat
@@ -246,9 +252,11 @@ def main():
246252 p .add_argument ("--output" , default = None , help = "optional: render a still PNG here" )
247253 p .add_argument ("--engine" , default = "eevee" , choices = ("eevee" , "cycles" ),
248254 help = "render engine for --output (cycles for GPU-less hosts)" )
255+ p .add_argument ("--one-cell" , action = "store_true" ,
256+ help = "instance a 1x1 grid (must fail)" )
249257 args = p .parse_args (argv )
250258
251- obj , _mat = build ()
259+ obj , _mat = build (one_cell = args . one_cell )
252260 code = check (obj )
253261 if code :
254262 return code
0 commit comments