Support generators and add City Builder example

This commit is contained in:
Carson Katri 2022-11-14 22:32:32 -05:00
commit 3850ec011c
6 changed files with 91 additions and 13 deletions

View file

@ -34,6 +34,8 @@ def build_node(node_type):
State.current_node_tree.links.new(constant._socket, node_input)
outputs = {}
for node_output in node.outputs:
if not node_output.enabled:
continue
outputs[node_output.name.lower().replace(' ', '_')] = Type(node_output)
if len(outputs) == 1:
return list(outputs.values())[0]

View file

@ -66,7 +66,14 @@ def tree(name):
# Run the builder function
State.current_node_tree = node_group
outputs = builder(*builder_inputs)
if inspect.isgeneratorfunction(builder):
generated_outputs = [*builder(*builder_inputs)]
if all(map(lambda x: issubclass(type(x), Type) and x._socket.type == 'GEOMETRY', generated_outputs)):
outputs = join_geometry(geometry=generated_outputs)
else:
outputs = generated_outputs
else:
outputs = builder(*builder_inputs)
# Create the output sockets
for i, result in enumerate(_as_iterable(outputs)):

View file

@ -81,23 +81,28 @@ class Type:
def __ge__(self, other):
return self._compare(other, 'GREATER_EQUAL')
def _get_xyz_component(self, component):
if self._socket.type != 'VECTOR':
raise Exception("`x`, `y`, `z` properties are not available on non-Vector types.")
separate_node = State.current_node_tree.nodes.new('ShaderNodeSeparateXYZ')
State.current_node_tree.links.new(self._socket, separate_node.inputs[0])
return Type(separate_node.outputs[component])
@property
def x(self):
return self._get_xyz_component(0)
@property
def y(self):
return self._get_xyz_component(1)
@property
def z(self):
return self._get_xyz_component(2)
for standard_socket in list(filter(lambda x: 'NodeSocket' in x, dir(bpy.types))):
name = standard_socket.replace('NodeSocket', '')
if len(name) < 1:
continue
globals()[name] = type(name, (Type,), { 'socket_type': standard_socket, '__module__': Type.__module__ })
if name == 'Vector':
def get_component(component):
@property
def get(self):
separate_node = State.current_node_tree.nodes.new('ShaderNodeSeparateXYZ')
State.current_node_tree.links.new(self._socket, separate_node.inputs[0])
return Type(separate_node.outputs[component])
return get
globals()[name].x = get_component(0)
globals()[name].y = get_component(1)
globals()[name].z = get_component(2)
if name == 'Int':
class IntIterator:
def __init__(self, integer):