Add repeat zone support
This commit is contained in:
parent
e3befbefc9
commit
da99654edb
6 changed files with 117 additions and 4 deletions
51
api/static/repeat.py
Normal file
51
api/static/repeat.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import bpy
|
||||
import inspect
|
||||
import typing
|
||||
|
||||
def repeat_zone(block: typing.Callable):
|
||||
"""
|
||||
Create a repeat input/output block.
|
||||
|
||||
> Only available in Blender 4.0+.
|
||||
"""
|
||||
def wrapped(*args, **kwargs):
|
||||
from geometry_script.api.node_mapper import OutputsList, set_or_create_link
|
||||
from geometry_script.api.state import State
|
||||
from geometry_script.api.types import Type, socket_class_to_data_type
|
||||
|
||||
signature = inspect.signature(block)
|
||||
|
||||
# setup zone
|
||||
repeat_in = State.current_node_tree.nodes.new(bpy.types.GeometryNodeRepeatInput.__name__)
|
||||
repeat_out = State.current_node_tree.nodes.new(bpy.types.GeometryNodeRepeatOutput.__name__)
|
||||
repeat_in.pair_with_output(repeat_out)
|
||||
|
||||
# clear state items
|
||||
for item in repeat_out.repeat_items:
|
||||
repeat_out.repeat_items.remove(item)
|
||||
|
||||
# link the iteration count
|
||||
set_or_create_link(args[0], repeat_in.inputs[0])
|
||||
|
||||
# create state items from block signature
|
||||
repeat_items = {}
|
||||
for param in signature.parameters.values():
|
||||
repeat_items[param.name] = (param.annotation, param.default, None, None)
|
||||
for i, arg in enumerate(repeat_items.items()):
|
||||
repeat_out.repeat_items.new(socket_class_to_data_type(arg[1][0].socket_type), arg[0].replace('_', ' ').title())
|
||||
# skip the first index, which is reserved for the iteration count
|
||||
i = i + 1
|
||||
set_or_create_link(kwargs[arg[0]] if arg[0] in kwargs else args[i], repeat_in.inputs[i])
|
||||
|
||||
step = block(*[Type(o) for o in repeat_in.outputs[:-1]])
|
||||
|
||||
if isinstance(step, Type):
|
||||
step = (step,)
|
||||
for i, result in enumerate(step):
|
||||
set_or_create_link(result, repeat_out.inputs[i])
|
||||
|
||||
if len(repeat_out.outputs[:-1]) == 1:
|
||||
return Type(repeat_out.outputs[0])
|
||||
else:
|
||||
return OutputsList({o.name.lower().replace(' ', '_'): Type(o) for o in repeat_out.outputs[:-1]})
|
||||
return wrapped
|
||||
|
|
@ -6,6 +6,8 @@ def simulation_zone(block: typing.Callable):
|
|||
"""
|
||||
Create a simulation input/output block.
|
||||
|
||||
In Blender 4.0+, you must return a boolean value for the "Skip" argument as the first element in the return tuple.
|
||||
|
||||
> Only available in Blender 3.6+.
|
||||
"""
|
||||
def wrapped(*args, **kwargs):
|
||||
|
|
@ -37,7 +39,7 @@ def simulation_zone(block: typing.Callable):
|
|||
if isinstance(step, Type):
|
||||
step = (step,)
|
||||
for i, result in enumerate(step):
|
||||
State.current_node_tree.links.new(result._socket, simulation_out.inputs[i])
|
||||
set_or_create_link(result, simulation_out.inputs[i])
|
||||
|
||||
if len(simulation_out.outputs[:-1]) == 1:
|
||||
return Type(simulation_out.outputs[0])
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from .static.attribute import *
|
|||
from .static.curve import *
|
||||
from .static.expression import *
|
||||
from .static.input_group import *
|
||||
from .static.repeat import *
|
||||
from .static.sample_mode import *
|
||||
from .static.simulation import *
|
||||
from .arrange import _arrange
|
||||
|
|
|
|||
Reference in a new issue