2023-10-09 19:05:08 -04:00
import bpy
2022-12-01 09:07:07 -05:00
import inspect
import typing
2023-10-09 19:05:08 -04:00
def simulation_zone ( block : typing . Callable ) :
2022-12-01 09:07:07 -05:00
"""
Create a simulation input / output block .
2023-11-11 14:43:12 -05:00
In Blender 4.0 + , you must return a boolean value for the " Skip " argument as the first element in the return tuple .
2023-10-09 19:05:08 -04:00
> Only available in Blender 3.6 + .
2022-12-01 09:07:07 -05:00
"""
2023-10-09 19:05:08 -04:00
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
2022-12-01 09:07:07 -05:00
signature = inspect . signature ( block )
2023-10-09 19:05:08 -04:00
# setup zone
simulation_in = State . current_node_tree . nodes . new ( bpy . types . GeometryNodeSimulationInput . __name__ )
simulation_out = State . current_node_tree . nodes . new ( bpy . types . GeometryNodeSimulationOutput . __name__ )
simulation_in . pair_with_output ( simulation_out )
# clear state items
for item in simulation_out . state_items :
simulation_out . state_items . remove ( item )
# create state items from block signature
state_items = { }
for param in [ * signature . parameters . values ( ) ] [ 1 : ] :
state_items [ param . name ] = ( param . annotation , param . default , None , None )
for i , arg in enumerate ( state_items . items ( ) ) :
simulation_out . state_items . new ( socket_class_to_data_type ( arg [ 1 ] [ 0 ] . socket_type ) , arg [ 0 ] . replace ( ' _ ' , ' ' ) . title ( ) )
set_or_create_link ( kwargs [ arg [ 0 ] ] if arg [ 0 ] in kwargs else args [ i ] , simulation_in . inputs [ i ] )
step = block ( * [ Type ( o ) for o in simulation_in . outputs [ : - 1 ] ] )
if isinstance ( step , Type ) :
step = ( step , )
for i , result in enumerate ( step ) :
2023-11-11 14:43:12 -05:00
set_or_create_link ( result , simulation_out . inputs [ i ] )
2023-10-09 19:05:08 -04:00
if len ( simulation_out . outputs [ : - 1 ] ) == 1 :
return Type ( simulation_out . outputs [ 0 ] )
else :
return OutputsList ( { o . name . lower ( ) . replace ( ' ' , ' _ ' ) : Type ( o ) for o in simulation_out . outputs [ : - 1 ] } )
2022-12-01 09:07:07 -05:00
return wrapped