Spaces:
Running
on
Zero
Running
on
Zero
# Copyright (C) 2023, Princeton University. | |
# This source code is licensed under the BSD 3-Clause license found in the LICENSE file in the root directory of this source tree. | |
# Authors: Alexander Raistrick, Alejandro Newell | |
# Code generated using version v2.0.1 of the node_transpiler | |
import bpy | |
import numpy as np | |
from numpy.random import normal, uniform | |
import infinigen | |
from infinigen.core import surface | |
from infinigen.core.nodes import node_utils | |
from infinigen.core.nodes.node_wrangler import Nodes | |
from infinigen.core.placement.factory import AssetFactory | |
from infinigen.core.tagging import tag_nodegroup, tag_object | |
from infinigen.core.util import blender as butil | |
from infinigen.core.util import color | |
from infinigen.core.util.math import FixedSeed, dict_lerp | |
def nodegroup_polar_to_cart_old(nw): | |
group_input = nw.new_node( | |
Nodes.GroupInput, | |
expose_input=[ | |
("NodeSocketVector", "Addend", (0.0, 0.0, 0.0)), | |
("NodeSocketFloat", "Value", 0.5), | |
("NodeSocketVector", "Vector", (0.0, 0.0, 0.0)), | |
], | |
) | |
cosine = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: group_input.outputs["Value"]}, | |
attrs={"operation": "COSINE"}, | |
) | |
sine = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: group_input.outputs["Value"]}, | |
attrs={"operation": "SINE"}, | |
) | |
combine_xyz_4 = nw.new_node(Nodes.CombineXYZ, input_kwargs={"Y": cosine, "Z": sine}) | |
multiply_add = nw.new_node( | |
Nodes.VectorMath, | |
input_kwargs={ | |
0: group_input.outputs["Vector"], | |
1: combine_xyz_4, | |
2: group_input.outputs["Addend"], | |
}, | |
attrs={"operation": "MULTIPLY_ADD"}, | |
) | |
group_output = nw.new_node( | |
Nodes.GroupOutput, input_kwargs={"Vector": multiply_add.outputs["Vector"]} | |
) | |
def nodegroup_follow_curve(nw): | |
group_input = nw.new_node( | |
Nodes.GroupInput, | |
expose_input=[ | |
("NodeSocketGeometry", "Geometry", None), | |
("NodeSocketGeometry", "Curve", None), | |
("NodeSocketFloat", "Curve Min", 0.5), | |
("NodeSocketFloat", "Curve Max", 1.0), | |
], | |
) | |
position = nw.new_node(Nodes.InputPosition) | |
capture_attribute = nw.new_node( | |
Nodes.CaptureAttribute, | |
input_kwargs={"Geometry": group_input.outputs["Geometry"], 1: position}, | |
attrs={"data_type": "FLOAT_VECTOR"}, | |
) | |
separate_xyz = nw.new_node( | |
Nodes.SeparateXYZ, | |
input_kwargs={"Vector": capture_attribute.outputs["Attribute"]}, | |
) | |
attribute_statistic = nw.new_node( | |
Nodes.AttributeStatistic, | |
input_kwargs={ | |
"Geometry": capture_attribute.outputs["Geometry"], | |
2: separate_xyz.outputs["Z"], | |
}, | |
) | |
map_range = nw.new_node( | |
Nodes.MapRange, | |
input_kwargs={ | |
"Value": separate_xyz.outputs["Z"], | |
1: attribute_statistic.outputs["Min"], | |
2: attribute_statistic.outputs["Max"], | |
3: group_input.outputs["Curve Min"], | |
4: group_input.outputs["Curve Max"], | |
}, | |
) | |
curve_length = nw.new_node( | |
Nodes.CurveLength, input_kwargs={"Curve": group_input.outputs["Curve"]} | |
) | |
multiply = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: map_range.outputs["Result"], 1: curve_length}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
sample_curve = nw.new_node( | |
Nodes.SampleCurve, | |
input_kwargs={"Curves": group_input.outputs["Curve"], "Length": multiply}, | |
attrs={"mode": "LENGTH"}, | |
) | |
cross_product = nw.new_node( | |
Nodes.VectorMath, | |
input_kwargs={ | |
0: sample_curve.outputs["Tangent"], | |
1: sample_curve.outputs["Normal"], | |
}, | |
attrs={"operation": "CROSS_PRODUCT"}, | |
) | |
scale = nw.new_node( | |
Nodes.VectorMath, | |
input_kwargs={ | |
0: cross_product.outputs["Vector"], | |
"Scale": separate_xyz.outputs["X"], | |
}, | |
attrs={"operation": "SCALE"}, | |
) | |
scale_1 = nw.new_node( | |
Nodes.VectorMath, | |
input_kwargs={ | |
0: sample_curve.outputs["Normal"], | |
"Scale": separate_xyz.outputs["Y"], | |
}, | |
attrs={"operation": "SCALE"}, | |
) | |
add = nw.new_node( | |
Nodes.VectorMath, | |
input_kwargs={0: scale.outputs["Vector"], 1: scale_1.outputs["Vector"]}, | |
) | |
set_position = nw.new_node( | |
Nodes.SetPosition, | |
input_kwargs={ | |
"Geometry": capture_attribute.outputs["Geometry"], | |
"Position": sample_curve.outputs["Position"], | |
"Offset": add.outputs["Vector"], | |
}, | |
) | |
group_output = nw.new_node( | |
Nodes.GroupOutput, input_kwargs={"Geometry": set_position} | |
) | |
def nodegroup_norm_index(nw): | |
index = nw.new_node(Nodes.Index) | |
group_input = nw.new_node( | |
Nodes.GroupInput, expose_input=[("NodeSocketInt", "Count", 0)] | |
) | |
divide = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: index, 1: group_input.outputs["Count"]}, | |
attrs={"operation": "DIVIDE"}, | |
) | |
group_output = nw.new_node(Nodes.GroupOutput, input_kwargs={"T": divide}) | |
def nodegroup_flower_petal(nw): | |
group_input = nw.new_node( | |
Nodes.GroupInput, | |
expose_input=[ | |
("NodeSocketGeometry", "Geometry", None), | |
("NodeSocketFloat", "Length", 0.2), | |
("NodeSocketFloat", "Point", 1.0), | |
("NodeSocketFloat", "Point height", 0.5), | |
("NodeSocketFloat", "Bevel", 6.8), | |
("NodeSocketFloat", "Base width", 0.2), | |
("NodeSocketFloat", "Upper width", 0.3), | |
("NodeSocketInt", "Resolution H", 8), | |
("NodeSocketInt", "Resolution V", 4), | |
("NodeSocketFloat", "Wrinkle", 0.1), | |
("NodeSocketFloat", "Curl", 0.0), | |
], | |
) | |
multiply_add = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: group_input.outputs["Resolution H"], 1: 2.0, 2: 1.0}, | |
attrs={"operation": "MULTIPLY_ADD"}, | |
) | |
grid = nw.new_node( | |
Nodes.MeshGrid, | |
input_kwargs={ | |
"Vertices X": group_input.outputs["Resolution V"], | |
"Vertices Y": multiply_add, | |
}, | |
) | |
position = nw.new_node(Nodes.InputPosition) | |
capture_attribute = nw.new_node( | |
Nodes.CaptureAttribute, | |
input_kwargs={"Geometry": grid, 1: position}, | |
attrs={"data_type": "FLOAT_VECTOR"}, | |
) | |
separate_xyz = nw.new_node( | |
Nodes.SeparateXYZ, | |
input_kwargs={"Vector": capture_attribute.outputs["Attribute"]}, | |
) | |
multiply = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: separate_xyz.outputs["X"], 1: 0.05}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
combine_xyz = nw.new_node( | |
Nodes.CombineXYZ, input_kwargs={"X": multiply, "Y": separate_xyz.outputs["Y"]} | |
) | |
noise_texture = nw.new_node( | |
Nodes.NoiseTexture, | |
input_kwargs={ | |
"Vector": combine_xyz, | |
"Scale": 7.9, | |
"Detail": 0.0, | |
"Distortion": 0.2, | |
}, | |
attrs={"noise_dimensions": "2D"}, | |
) | |
add = nw.new_node( | |
Nodes.Math, input_kwargs={0: noise_texture.outputs["Fac"], 1: -0.5} | |
) | |
multiply_1 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: add, 1: group_input.outputs["Wrinkle"]}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
separate_xyz_1 = nw.new_node( | |
Nodes.SeparateXYZ, | |
input_kwargs={"Vector": capture_attribute.outputs["Attribute"]}, | |
) | |
add_1 = nw.new_node(Nodes.Math, input_kwargs={0: separate_xyz_1.outputs["X"]}) | |
absolute = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: separate_xyz_1.outputs["Y"]}, | |
attrs={"operation": "ABSOLUTE"}, | |
) | |
multiply_2 = nw.new_node( | |
Nodes.Math, input_kwargs={0: absolute, 1: 2.0}, attrs={"operation": "MULTIPLY"} | |
) | |
power = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: multiply_2, 1: group_input.outputs["Bevel"]}, | |
attrs={"operation": "POWER"}, | |
) | |
multiply_add_1 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: power, 1: -1.0, 2: 1.0}, | |
attrs={"operation": "MULTIPLY_ADD"}, | |
) | |
multiply_3 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: add_1, 1: multiply_add_1}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
multiply_add_2 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={ | |
0: multiply_3, | |
1: group_input.outputs["Upper width"], | |
2: group_input.outputs["Base width"], | |
}, | |
attrs={"operation": "MULTIPLY_ADD"}, | |
) | |
multiply_4 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: separate_xyz_1.outputs["Y"], 1: multiply_add_2}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
power_1 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: absolute, 1: group_input.outputs["Point"]}, | |
attrs={"operation": "POWER"}, | |
) | |
multiply_add_3 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: power_1, 1: -1.0, 2: 1.0}, | |
attrs={"operation": "MULTIPLY_ADD"}, | |
) | |
multiply_5 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: multiply_add_3, 1: group_input.outputs["Point height"]}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
multiply_add_4 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: group_input.outputs["Point height"], 1: -1.0, 2: 1.0}, | |
attrs={"operation": "MULTIPLY_ADD"}, | |
) | |
add_2 = nw.new_node(Nodes.Math, input_kwargs={0: multiply_5, 1: multiply_add_4}) | |
multiply_6 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: add_2, 1: multiply_add_1}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
multiply_7 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: add_1, 1: multiply_6}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
combine_xyz_1 = nw.new_node( | |
Nodes.CombineXYZ, | |
input_kwargs={"X": multiply_1, "Y": multiply_4, "Z": multiply_7}, | |
) | |
set_position = nw.new_node( | |
Nodes.SetPosition, | |
input_kwargs={ | |
"Geometry": capture_attribute.outputs["Geometry"], | |
"Position": combine_xyz_1, | |
}, | |
) | |
multiply_8 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: group_input.outputs["Length"]}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
combine_xyz_3 = nw.new_node(Nodes.CombineXYZ, input_kwargs={"Y": multiply_8}) | |
reroute = nw.new_node( | |
Nodes.Reroute, input_kwargs={"Input": group_input.outputs["Curl"]} | |
) | |
group_1 = nw.new_node( | |
nodegroup_polar_to_cart_old().name, | |
input_kwargs={"Addend": combine_xyz_3, "Value": reroute, "Vector": multiply_8}, | |
) | |
quadratic_bezier = nw.new_node( | |
Nodes.QuadraticBezier, | |
input_kwargs={ | |
"Resolution": 8, | |
"Start": (0.0, 0.0, 0.0), | |
"Middle": combine_xyz_3, | |
"End": group_1, | |
}, | |
) | |
group = nw.new_node( | |
nodegroup_follow_curve().name, | |
input_kwargs={ | |
"Geometry": set_position, | |
"Curve": quadratic_bezier, | |
"Curve Min": 0.0, | |
}, | |
) | |
group_output = nw.new_node( | |
Nodes.GroupOutput, input_kwargs={"Geometry": tag_nodegroup(nw, group, "petal")} | |
) | |
def nodegroup_phyllo_points(nw): | |
group_input = nw.new_node( | |
Nodes.GroupInput, | |
expose_input=[ | |
("NodeSocketInt", "Count", 50), | |
("NodeSocketFloat", "Min Radius", 0.0), | |
("NodeSocketFloat", "Max Radius", 2.0), | |
("NodeSocketFloat", "Radius exp", 0.5), | |
("NodeSocketFloat", "Min angle", -0.5236), | |
("NodeSocketFloat", "Max angle", 0.7854), | |
("NodeSocketFloat", "Min z", 0.0), | |
("NodeSocketFloat", "Max z", 1.0), | |
("NodeSocketFloat", "Clamp z", 1.0), | |
("NodeSocketFloat", "Yaw offset", -1.5708), | |
], | |
) | |
mesh_line = nw.new_node( | |
Nodes.MeshLine, input_kwargs={"Count": group_input.outputs["Count"]} | |
) | |
mesh_to_points = nw.new_node(Nodes.MeshToPoints, input_kwargs={"Mesh": mesh_line}) | |
position = nw.new_node(Nodes.InputPosition) | |
capture_attribute = nw.new_node( | |
Nodes.CaptureAttribute, | |
input_kwargs={"Geometry": mesh_to_points, 1: position}, | |
attrs={"data_type": "FLOAT_VECTOR"}, | |
) | |
index = nw.new_node(Nodes.Index) | |
cosine = nw.new_node( | |
Nodes.Math, input_kwargs={0: index}, attrs={"operation": "COSINE"} | |
) | |
sine = nw.new_node(Nodes.Math, input_kwargs={0: index}, attrs={"operation": "SINE"}) | |
combine_xyz = nw.new_node(Nodes.CombineXYZ, input_kwargs={"X": cosine, "Y": sine}) | |
divide = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: index, 1: group_input.outputs["Count"]}, | |
attrs={"operation": "DIVIDE"}, | |
) | |
power = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: divide, 1: group_input.outputs["Radius exp"]}, | |
attrs={"operation": "POWER"}, | |
) | |
map_range = nw.new_node( | |
Nodes.MapRange, | |
input_kwargs={ | |
"Value": power, | |
3: group_input.outputs["Min Radius"], | |
4: group_input.outputs["Max Radius"], | |
}, | |
) | |
multiply = nw.new_node( | |
Nodes.VectorMath, | |
input_kwargs={0: combine_xyz, 1: map_range.outputs["Result"]}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
separate_xyz = nw.new_node( | |
Nodes.SeparateXYZ, input_kwargs={"Vector": multiply.outputs["Vector"]} | |
) | |
map_range_2 = nw.new_node( | |
Nodes.MapRange, | |
input_kwargs={ | |
"Value": divide, | |
2: group_input.outputs["Clamp z"], | |
3: group_input.outputs["Min z"], | |
4: group_input.outputs["Max z"], | |
}, | |
) | |
combine_xyz_1 = nw.new_node( | |
Nodes.CombineXYZ, | |
input_kwargs={ | |
"X": separate_xyz.outputs["X"], | |
"Y": separate_xyz.outputs["Y"], | |
"Z": map_range_2.outputs["Result"], | |
}, | |
) | |
set_position = nw.new_node( | |
Nodes.SetPosition, | |
input_kwargs={ | |
"Geometry": capture_attribute.outputs["Geometry"], | |
"Position": combine_xyz_1, | |
}, | |
) | |
map_range_3 = nw.new_node( | |
Nodes.MapRange, | |
input_kwargs={ | |
"Value": divide, | |
3: group_input.outputs["Min angle"], | |
4: group_input.outputs["Max angle"], | |
}, | |
) | |
random_value = nw.new_node(Nodes.RandomValue, input_kwargs={2: -0.1, 3: 0.1}) | |
add = nw.new_node( | |
Nodes.Math, input_kwargs={0: index, 1: group_input.outputs["Yaw offset"]} | |
) | |
combine_xyz_2 = nw.new_node( | |
Nodes.CombineXYZ, | |
input_kwargs={ | |
"X": map_range_3.outputs["Result"], | |
"Y": random_value.outputs[1], | |
"Z": add, | |
}, | |
) | |
group_output = nw.new_node( | |
Nodes.GroupOutput, | |
input_kwargs={"Points": set_position, "Rotation": combine_xyz_2}, | |
) | |
def nodegroup_plant_seed(nw): | |
group_input = nw.new_node( | |
Nodes.GroupInput, | |
expose_input=[ | |
("NodeSocketVector", "Dimensions", (0.0, 0.0, 0.0)), | |
("NodeSocketIntUnsigned", "U", 4), | |
("NodeSocketInt", "V", 8), | |
], | |
) | |
separate_xyz = nw.new_node( | |
Nodes.SeparateXYZ, input_kwargs={"Vector": group_input.outputs["Dimensions"]} | |
) | |
combine_xyz = nw.new_node( | |
Nodes.CombineXYZ, input_kwargs={"X": separate_xyz.outputs["X"]} | |
) | |
multiply_add = nw.new_node( | |
Nodes.VectorMath, | |
input_kwargs={0: combine_xyz, 1: (0.5, 0.5, 0.5)}, | |
attrs={"operation": "MULTIPLY_ADD"}, | |
) | |
quadratic_bezier_1 = nw.new_node( | |
Nodes.QuadraticBezier, | |
input_kwargs={ | |
"Resolution": group_input.outputs["U"], | |
"Start": (0.0, 0.0, 0.0), | |
"Middle": multiply_add.outputs["Vector"], | |
"End": combine_xyz, | |
}, | |
) | |
group = nw.new_node( | |
nodegroup_norm_index().name, input_kwargs={"Count": group_input.outputs["U"]} | |
) | |
float_curve = nw.new_node(Nodes.FloatCurve, input_kwargs={"Value": group}) | |
node_utils.assign_curve( | |
float_curve.mapping.curves[0], [(0.0, 0.0), (0.3159, 0.4469), (1.0, 0.0156)] | |
) | |
map_range = nw.new_node(Nodes.MapRange, input_kwargs={"Value": float_curve, 4: 3.0}) | |
set_curve_radius = nw.new_node( | |
Nodes.SetCurveRadius, | |
input_kwargs={ | |
"Curve": quadratic_bezier_1, | |
"Radius": map_range.outputs["Result"], | |
}, | |
) | |
curve_circle = nw.new_node( | |
Nodes.CurveCircle, | |
input_kwargs={ | |
"Resolution": group_input.outputs["V"], | |
"Radius": separate_xyz.outputs["Y"], | |
}, | |
) | |
curve_to_mesh = nw.new_node( | |
Nodes.CurveToMesh, | |
input_kwargs={ | |
"Curve": set_curve_radius, | |
"Profile Curve": curve_circle.outputs["Curve"], | |
"Fill Caps": True, | |
}, | |
) | |
group_output = nw.new_node( | |
Nodes.GroupOutput, | |
input_kwargs={"Mesh": tag_nodegroup(nw, curve_to_mesh, "seed")}, | |
) | |
def shader_flower_center(nw): | |
ambient_occlusion = nw.new_node(Nodes.AmbientOcclusion) | |
colorramp = nw.new_node( | |
Nodes.ColorRamp, input_kwargs={"Fac": ambient_occlusion.outputs["Color"]} | |
) | |
colorramp.color_ramp.elements.new(1) | |
colorramp.color_ramp.elements[0].position = 0.4841 | |
colorramp.color_ramp.elements[0].color = (0.0127, 0.0075, 0.0026, 1.0) | |
colorramp.color_ramp.elements[1].position = 0.8591 | |
colorramp.color_ramp.elements[1].color = (0.0848, 0.0066, 0.0007, 1.0) | |
colorramp.color_ramp.elements[2].position = 1.0 | |
colorramp.color_ramp.elements[2].color = (1.0, 0.6228, 0.1069, 1.0) | |
principled_bsdf = nw.new_node( | |
Nodes.PrincipledBSDF, input_kwargs={"Base Color": colorramp.outputs["Color"]} | |
) | |
material_output = nw.new_node( | |
Nodes.MaterialOutput, input_kwargs={"Surface": principled_bsdf} | |
) | |
def shader_petal(nw): | |
translucent_color_change = uniform(0.1, 0.6) | |
specular = normal(0.6, 0.1) | |
roughness = normal(0.4, 0.05) | |
translucent_amt = normal(0.3, 0.05) | |
petal_color = nw.new_node(Nodes.RGB) | |
petal_color.outputs[0].default_value = color.color_category("petal") | |
translucent_color = nw.new_node( | |
Nodes.MixRGB, | |
[translucent_color_change, petal_color, color.color_category("petal")], | |
) | |
translucent_bsdf = nw.new_node( | |
Nodes.TranslucentBSDF, input_kwargs={"Color": translucent_color} | |
) | |
principled_bsdf = nw.new_node( | |
Nodes.PrincipledBSDF, | |
input_kwargs={ | |
"Base Color": petal_color, | |
"Specular": specular, | |
"Roughness": roughness, | |
}, | |
) | |
mix_shader = nw.new_node( | |
Nodes.MixShader, | |
input_kwargs={"Fac": translucent_amt, 1: principled_bsdf, 2: translucent_bsdf}, | |
) | |
material_output = nw.new_node( | |
Nodes.MaterialOutput, input_kwargs={"Surface": mix_shader} | |
) | |
def geo_flower(nw, petal_material, center_material): | |
group_input = nw.new_node( | |
Nodes.GroupInput, | |
expose_input=[ | |
("NodeSocketGeometry", "Geometry", None), | |
("NodeSocketFloat", "Center Rad", 0.0), | |
("NodeSocketVector", "Petal Dims", (0.0, 0.0, 0.0)), | |
("NodeSocketFloat", "Seed Size", 0.0), | |
("NodeSocketFloat", "Min Petal Angle", 0.1), | |
("NodeSocketFloat", "Max Petal Angle", 1.36), | |
("NodeSocketFloat", "Wrinkle", 0.01), | |
("NodeSocketFloat", "Curl", 13.89), | |
], | |
) | |
uv_sphere = nw.new_node( | |
Nodes.MeshUVSphere, | |
input_kwargs={ | |
"Segments": 8, | |
"Rings": 8, | |
"Radius": group_input.outputs["Center Rad"], | |
}, | |
) | |
transform = nw.new_node( | |
Nodes.Transform, input_kwargs={"Geometry": uv_sphere, "Scale": (1.0, 1.0, 0.05)} | |
) | |
multiply = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: group_input.outputs["Seed Size"], 1: 1.5}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
distribute_points_on_faces = nw.new_node( | |
Nodes.DistributePointsOnFaces, | |
input_kwargs={ | |
"Mesh": transform, | |
"Distance Min": multiply, | |
"Density Max": 50000.0, | |
}, | |
attrs={"distribute_method": "POISSON"}, | |
) | |
multiply_1 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: group_input.outputs["Seed Size"], 1: 10.0}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
combine_xyz = nw.new_node( | |
Nodes.CombineXYZ, | |
input_kwargs={"X": multiply_1, "Y": group_input.outputs["Seed Size"]}, | |
) | |
group_3 = nw.new_node( | |
nodegroup_plant_seed().name, | |
input_kwargs={"Dimensions": combine_xyz, "U": 6, "V": 6}, | |
) | |
musgrave_texture = nw.new_node( | |
Nodes.MusgraveTexture, | |
input_kwargs={"W": 13.8, "Scale": 2.41}, | |
attrs={"musgrave_dimensions": "4D"}, | |
) | |
map_range = nw.new_node( | |
Nodes.MapRange, input_kwargs={"Value": musgrave_texture, 3: 0.34, 4: 1.21} | |
) | |
combine_xyz_1 = nw.new_node( | |
Nodes.CombineXYZ, | |
input_kwargs={"X": map_range.outputs["Result"], "Y": 1.0, "Z": 1.0}, | |
) | |
instance_on_points_1 = nw.new_node( | |
Nodes.InstanceOnPoints, | |
input_kwargs={ | |
"Points": distribute_points_on_faces.outputs["Points"], | |
"Instance": group_3, | |
"Rotation": (0.0, -1.5708, 0.0541), | |
"Scale": combine_xyz_1, | |
}, | |
) | |
realize_instances = nw.new_node( | |
Nodes.RealizeInstances, input_kwargs={"Geometry": instance_on_points_1} | |
) | |
join_geometry_1 = nw.new_node( | |
Nodes.JoinGeometry, input_kwargs={"Geometry": [realize_instances, transform]} | |
) | |
set_material_1 = nw.new_node( | |
Nodes.SetMaterial, | |
input_kwargs={"Geometry": join_geometry_1, "Material": center_material}, | |
) | |
multiply_2 = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: group_input.outputs["Center Rad"], 1: 6.2832}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
separate_xyz = nw.new_node( | |
Nodes.SeparateXYZ, input_kwargs={"Vector": group_input.outputs["Petal Dims"]} | |
) | |
divide = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: multiply_2, 1: separate_xyz.outputs["Y"]}, | |
attrs={"operation": "DIVIDE"}, | |
) | |
multiply_3 = nw.new_node( | |
Nodes.Math, input_kwargs={0: divide, 1: 1.2}, attrs={"operation": "MULTIPLY"} | |
) | |
reroute_3 = nw.new_node( | |
Nodes.Reroute, input_kwargs={"Input": group_input.outputs["Center Rad"]} | |
) | |
reroute_1 = nw.new_node( | |
Nodes.Reroute, input_kwargs={"Input": group_input.outputs["Min Petal Angle"]} | |
) | |
reroute = nw.new_node( | |
Nodes.Reroute, input_kwargs={"Input": group_input.outputs["Max Petal Angle"]} | |
) | |
group_1 = nw.new_node( | |
nodegroup_phyllo_points().name, | |
input_kwargs={ | |
"Count": multiply_3, | |
"Min Radius": reroute_3, | |
"Max Radius": reroute_3, | |
"Radius exp": 0.0, | |
"Min angle": reroute_1, | |
"Max angle": reroute, | |
"Max z": 0.0, | |
}, | |
) | |
subtract = nw.new_node( | |
Nodes.Math, | |
input_kwargs={0: separate_xyz.outputs["Z"], 1: separate_xyz.outputs["Y"]}, | |
attrs={"operation": "SUBTRACT", "use_clamp": True}, | |
) | |
reroute_2 = nw.new_node( | |
Nodes.Reroute, input_kwargs={"Input": group_input.outputs["Wrinkle"]} | |
) | |
reroute_4 = nw.new_node( | |
Nodes.Reroute, input_kwargs={"Input": group_input.outputs["Curl"]} | |
) | |
group = nw.new_node( | |
nodegroup_flower_petal().name, | |
input_kwargs={ | |
"Length": separate_xyz.outputs["X"], | |
"Point": 0.56, | |
"Point height": -0.1, | |
"Bevel": 1.83, | |
"Base width": separate_xyz.outputs["Y"], | |
"Upper width": subtract, | |
"Resolution H": 8, | |
"Resolution V": 16, | |
"Wrinkle": reroute_2, | |
"Curl": reroute_4, | |
}, | |
) | |
instance_on_points = nw.new_node( | |
Nodes.InstanceOnPoints, | |
input_kwargs={ | |
"Points": group_1.outputs["Points"], | |
"Instance": group, | |
"Rotation": group_1.outputs["Rotation"], | |
}, | |
) | |
realize_instances_1 = nw.new_node( | |
Nodes.RealizeInstances, input_kwargs={"Geometry": instance_on_points} | |
) | |
noise_texture = nw.new_node( | |
Nodes.NoiseTexture, | |
input_kwargs={"Scale": 3.73, "Detail": 5.41, "Distortion": -1.0}, | |
) | |
subtract_1 = nw.new_node( | |
Nodes.VectorMath, | |
input_kwargs={0: noise_texture.outputs["Color"], 1: (0.5, 0.5, 0.5)}, | |
attrs={"operation": "SUBTRACT"}, | |
) | |
value = nw.new_node(Nodes.Value) | |
value.outputs[0].default_value = 0.025 | |
multiply_4 = nw.new_node( | |
Nodes.VectorMath, | |
input_kwargs={0: subtract_1.outputs["Vector"], 1: value}, | |
attrs={"operation": "MULTIPLY"}, | |
) | |
set_position = nw.new_node( | |
Nodes.SetPosition, | |
input_kwargs={ | |
"Geometry": realize_instances_1, | |
"Offset": multiply_4.outputs["Vector"], | |
}, | |
) | |
set_material = nw.new_node( | |
Nodes.SetMaterial, | |
input_kwargs={"Geometry": set_position, "Material": petal_material}, | |
) | |
join_geometry = nw.new_node( | |
Nodes.JoinGeometry, input_kwargs={"Geometry": [set_material_1, set_material]} | |
) | |
set_shade_smooth = nw.new_node( | |
Nodes.SetShadeSmooth, | |
input_kwargs={"Geometry": join_geometry, "Shade Smooth": False}, | |
) | |
group_output = nw.new_node( | |
Nodes.GroupOutput, input_kwargs={"Geometry": set_shade_smooth} | |
) | |
class FlowerFactory(AssetFactory): | |
def __init__(self, factory_seed, rad=0.15, diversity_fac=0.25): | |
super(FlowerFactory, self).__init__(factory_seed=factory_seed) | |
self.get_params_dict() | |
self.rad = rad | |
self.diversity_fac = diversity_fac | |
with FixedSeed(factory_seed): | |
self.petal_material = surface.shaderfunc_to_material(shader_petal) | |
self.center_material = surface.shaderfunc_to_material(shader_flower_center) | |
#self.species_params = self.get_flower_params(self.rad) | |
self.params = self.get_flower_params(self.rad * normal(1.0, 0.05)) | |
def get_params_dict(self): | |
self.params_dict = { | |
"overall_rad": ['continuous', (0.7, 1.3)], | |
"pct_inner": ['continuous', (0.05, 0.5)], | |
"base_width": ['continuous', (4, 16)], | |
"top_width": ['continuous', (0.0, 1.6)], | |
"min_angle": ['continuous', (-20, 100)], | |
"max_angle": ['continuous', (-20, 100)], | |
"seed_size": ['continuous', (0.005, 0.03)], | |
"wrinkle": ['continuous', (0.003, 0.02)], | |
"curl": ['continuous', (-120, 120)], | |
} | |
def get_flower_params(overall_rad=0.05): | |
pct_inner = uniform(0.05, 0.4) | |
base_width = 2 * np.pi * overall_rad * pct_inner / normal(20, 5) | |
top_width = overall_rad * np.clip(normal(0.7, 0.3), base_width * 1.2, 100) | |
min_angle, max_angle = np.deg2rad(np.sort(uniform(-20, 100, 2))) | |
return { | |
"Center Rad": overall_rad * pct_inner, | |
"Petal Dims": np.array( | |
[overall_rad * (1 - pct_inner), base_width, top_width], dtype=np.float32 | |
), | |
"Seed Size": uniform(0.005, 0.01), | |
"Min Petal Angle": min_angle, | |
"Max Petal Angle": max_angle, | |
"Wrinkle": uniform(0.003, 0.02), | |
"Curl": np.deg2rad(normal(30, 50)), | |
} | |
def update_params(self, params): | |
overall_rad = params['overall_rad'] | |
pct_inner = params['pct_inner'] | |
base_width = 2 * np.pi * overall_rad * pct_inner / params['base_width'] | |
top_width = overall_rad * np.clip(params['top_width'], base_width * 1.2, 100) | |
min_angle = np.deg2rad(params['min_angle']) | |
max_angle = np.deg2rad(params['max_angle']) | |
if min_angle > max_angle: | |
min_angle, max_angle = max_angle, min_angle | |
parameters = { | |
"Center Rad": overall_rad * pct_inner, | |
"Petal Dims": np.array( | |
[overall_rad * (1 - pct_inner), base_width, top_width], dtype=np.float32 | |
), | |
"Seed Size": params['seed_size'], | |
"Min Petal Angle": min_angle, | |
"Max Petal Angle": max_angle, | |
"Wrinkle": params['wrinkle'], | |
"Curl": np.deg2rad(params['curl']), | |
} | |
self.params.update(parameters) | |
self.petal_material = surface.shaderfunc_to_material(shader_petal) | |
self.center_material = surface.shaderfunc_to_material(shader_flower_center) | |
def fix_unused_params(self, params): | |
return params | |
def create_asset(self, **kwargs) -> bpy.types.Object: | |
vert = butil.spawn_vert("flower") | |
mod = surface.add_geomod( | |
vert, | |
geo_flower, | |
input_kwargs={ | |
"petal_material": self.petal_material, | |
"center_material": self.center_material, | |
}, | |
) | |
#inst_params = self.get_flower_params(self.rad * normal(1, 0.05)) | |
#params = dict_lerp(self.species_params, inst_params, 0.25) | |
butil.set_geomod_inputs(mod, self.params) | |
butil.apply_modifiers(vert, mod=mod) | |
vert.rotation_euler.z = uniform(0, 360) | |
tag_object(vert, "flower") | |
return vert | |