From 22a41d4478dbc8f03294371d76bc9cb7907762c4 Mon Sep 17 00:00:00 2001 From: moon Date: Wed, 12 Jun 2024 23:25:14 -0700 Subject: [PATCH] New changes and new tests --- .../assets/materials/aluminumdisp2tut.py | 15 +-- infinigen/assets/materials/basic_bsdf.py | 2 +- infinigen/assets/materials/bird.py | 6 +- .../assets/materials/face_size_visualizer.py | 9 +- .../assets/materials/grass_blade_texture.py | 2 +- infinigen/assets/materials/ice.py | 3 +- infinigen/assets/materials/mountain.py | 6 +- infinigen/assets/materials/new_whitewater.py | 5 +- infinigen/assets/materials/nose.py | 2 +- infinigen/assets/materials/sand.py | 4 +- infinigen/assets/materials/slimy.py | 3 +- infinigen/assets/materials/snake_plant.py | 2 +- infinigen/assets/materials/snake_shaders.py | 6 +- infinigen/assets/materials/spider_plant.py | 2 +- infinigen/assets/materials/tongue.py | 2 +- .../assets/materials/waterfall_material.py | 46 +++---- infinigen/core/execute_tasks.py | 8 +- infinigen/core/nodes/node_info.py | 1 + infinigen/core/nodes/node_utils.py | 5 +- infinigen/core/nodes/node_wrangler.py | 117 +++++++++--------- 20 files changed, 120 insertions(+), 126 deletions(-) diff --git a/infinigen/assets/materials/aluminumdisp2tut.py b/infinigen/assets/materials/aluminumdisp2tut.py index e8ac1ffe6..e21290afe 100644 --- a/infinigen/assets/materials/aluminumdisp2tut.py +++ b/infinigen/assets/materials/aluminumdisp2tut.py @@ -19,19 +19,19 @@ def shader_aluminumdisp2tut(nw: NodeWrangler, rand=False, **input_kwargs): input_kwargs={'Vector': texture_coordinate.outputs["Generated"]}) multiply = nw.new_node(Nodes.Math, - input_kwargs={'Value': separate_xyz.outputs["X"], 'Value_1': 0.1}, + input_kwargs={'Value': separate_xyz.outputs["X"], 'Value_001': 0.1}, attrs={'operation': 'MULTIPLY'}) if rand: - multiply.inputs['Value_1'].default_value = sample_range(-1, 1) + multiply.inputs['Value_001'].default_value = sample_range(-1, 1) multiply_1 = nw.new_node(Nodes.Math, - input_kwargs={'Value': separate_xyz.outputs["Y"], 'Value_1': 0.1}, + input_kwargs={'Value': separate_xyz.outputs["Y"], 'Value_001': 0.1}, attrs={'operation': 'MULTIPLY'}) if rand: - multiply_1.inputs['Value_1'].default_value = sample_range(-1, 1) + multiply_1.inputs['Value_001'].default_value = sample_range(-1, 1) add = nw.new_node(Nodes.Math, - input_kwargs={'Value': multiply.outputs["Value"], 'Value_1': multiply_1.outputs["Value"]}, + input_kwargs={'Value': multiply.outputs["Value"], 'Value_001': multiply_1.outputs["Value"]}, attrs={'operation': 'ADD'}) combine_xyz = nw.new_node(Nodes.CombineXYZ, @@ -45,9 +45,10 @@ def shader_aluminumdisp2tut(nw: NodeWrangler, rand=False, **input_kwargs): attrs={'operation': 'MULTIPLY'}) musgrave_texture = nw.new_node(Nodes.MusgraveTexture, - input_kwargs={'Vector': mapping.outputs["Vector"], 'W': 0.7, 'Scale': 2.0, 'Detail': 10.0, 'Dimensions': '4D'}) + input_kwargs={'Vector': mapping.outputs["Vector"], 'Roughness': 0.7, 'Scale': 2.0, 'Detail': 10.0}, + attrs={'musgrave_dimensions': '4D'}) if rand: - musgrave_texture.inputs['W'].default_value = sample_range(0, 5) + musgrave_texture.inputs['Roughness'].default_value = sample_range(0, 5) musgrave_texture.inputs['Scale'].default_value = sample_ratio(2, 0.5, 2) colorramp_4 = nw.new_node(Nodes.ColorRamp, diff --git a/infinigen/assets/materials/basic_bsdf.py b/infinigen/assets/materials/basic_bsdf.py index 295d29b85..f02cddf9d 100644 --- a/infinigen/assets/materials/basic_bsdf.py +++ b/infinigen/assets/materials/basic_bsdf.py @@ -24,7 +24,7 @@ def shader_basic_bsdf(nw): 'Base Color': color, 'Roughness': np.clip(normal(0.6, 0.3), 0.05, 0.95), 'Metallic': uniform(0, 1) if uniform() < 0.3 else 0, - 'Subsurface': 0 if uniform() < 0.8 else uniform(0, 0.2) + 'Subsurface Weight': 0 if uniform() < 0.8 else uniform(0, 0.2) }, attrs={'subsurface_method': 'BURLEY'}) diff --git a/infinigen/assets/materials/bird.py b/infinigen/assets/materials/bird.py index 151dd5532..2bbb9340f 100644 --- a/infinigen/assets/materials/bird.py +++ b/infinigen/assets/materials/bird.py @@ -298,7 +298,7 @@ def shader_bird_body(nw: NodeWrangler, rand=True, kind='duck', **input_kwargs): group.inputs['W'].default_value = sample_range(-2, 2) principled_bsdf = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': group, 'Subsurface IOR': 0.0, 'Specular': 0.0, 'Roughness': 1.0}) + input_kwargs={'Base Color': group, 'Subsurface Weight': 0.0, 'Roughness': 1.0}) material_output = nw.new_node(Nodes.MaterialOutput, input_kwargs={'Surface': principled_bsdf}) @@ -356,7 +356,7 @@ def shader_bird_feather(nw: NodeWrangler, rand=True, kind='duck', tail=False, ** input_kwargs={'Fac': 0.5 if tail else 1.0, 'Color1': colorramp2.outputs["Color"], 'Color2': colorramp.outputs["Color"]}) principled_bsdf = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': (mix, "Result"), 'Specular': 0.0, 'Roughness': 1.0}, + input_kwargs={'Base Color': (mix, "Result"), 'Roughness': 1.0}, attrs={'subsurface_method': 'BURLEY'}) material_output = nw.new_node(Nodes.MaterialOutput, @@ -445,7 +445,7 @@ def shader_bird_claw(nw: NodeWrangler, rand=True, **input_kwargs): # Code generated using version 2.4.3 of the node_transpiler principled_bsdf = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': (0.0091, 0.0091, 0.0091, 1.0), 'Specular': 0.0, 'Roughness': 0.4409}) + input_kwargs={'Base Color': (0.0091, 0.0091, 0.0091, 1.0), 'Roughness': 0.4409}) material_output = nw.new_node(Nodes.MaterialOutput, input_kwargs={'Surface': principled_bsdf}) diff --git a/infinigen/assets/materials/face_size_visualizer.py b/infinigen/assets/materials/face_size_visualizer.py index d8106f8ba..4c3e4c260 100644 --- a/infinigen/assets/materials/face_size_visualizer.py +++ b/infinigen/assets/materials/face_size_visualizer.py @@ -25,19 +25,18 @@ def shader_material(nw: NodeWrangler): input_kwargs={'Surface': principled_bsdf}) def geo_face_colors(nw: NodeWrangler): - # Code generated using version 2.4.3 of the node_transpiler + # Code generated using version 2.6.5 of the node_transpiler - group_input = nw.new_node(Nodes.GroupInput, - expose_input=[('NodeSocketGeometry', 'Geometry', None)]) + group_input = nw.expose_input('Geometry', dtype='NodeSocketGeometry') random_value = nw.new_node(Nodes.RandomValue, attrs={'data_type': 'FLOAT_VECTOR'}) store_named_attribute = nw.new_node(Nodes.StoreNamedAttribute, - input_kwargs={'Geometry': group_input.outputs["Geometry"], 'Name': 'col', "Value": random_value.outputs["Value"]}, + input_kwargs={'Geometry': group_input, 'Name': 'col', "Value": random_value.outputs["Value"]}, attrs={'data_type': 'FLOAT_VECTOR', 'domain': 'FACE'}) - group_output = nw.new_node(Nodes.GroupOutput, + nw.new_node(Nodes.GroupOutput, input_kwargs={'Geometry': store_named_attribute}) diff --git a/infinigen/assets/materials/grass_blade_texture.py b/infinigen/assets/materials/grass_blade_texture.py index a2d925ed2..8223e6689 100644 --- a/infinigen/assets/materials/grass_blade_texture.py +++ b/infinigen/assets/materials/grass_blade_texture.py @@ -187,7 +187,7 @@ def shader_grass_texture_original(nw: NodeWrangler): input_kwargs={'Vector': separate_xyz.outputs["Y"], 'Scale': 25.0, 'Distortion': 8.0, 'Detail Scale': 6.0}) musgrave_texture = nw.new_node(Nodes.MusgraveTexture, - input_kwargs={'Vector': combine_xyz, 'Scale': 8.0, 'Detail': 5.0, 'Dimension': 0.1, 'Lacunarity': 3.0}) + input_kwargs={'Vector': combine_xyz, 'Scale': 8.0, 'Detail': 5.0, 'Roughness': 0.1, 'Lacunarity': 3.0}) mix_1 = nw.new_node(Nodes.MixRGB, input_kwargs={'Fac': 0.2, 'Color1': wave_texture.outputs["Color"], 'Color2': musgrave_texture}) diff --git a/infinigen/assets/materials/ice.py b/infinigen/assets/materials/ice.py index c26f2b3f3..3983a7d3f 100644 --- a/infinigen/assets/materials/ice.py +++ b/infinigen/assets/materials/ice.py @@ -44,9 +44,8 @@ def shader_ice(nw: NodeWrangler): principled_bsdf = nw.new_node( Nodes.PrincipledBSDF, input_kwargs={ - 'Subsurface': 1.0000, + 'Subsurface Weight': 1.0000, 'Subsurface Radius': (0.0010, 0.0010, 0.0020), - 'Subsurface Color': tuple(col_ice), 'Roughness': color_ramp.outputs["Color"], 'IOR': 1.3100 }, diff --git a/infinigen/assets/materials/mountain.py b/infinigen/assets/materials/mountain.py index c7ad82cf0..4a1b51e52 100644 --- a/infinigen/assets/materials/mountain.py +++ b/infinigen/assets/materials/mountain.py @@ -29,8 +29,8 @@ def geo_MOUNTAIN_general( crack_modulation_params, selection=None ): - position = nw.new_node("GeometryNodeInputPosition", []) - normal = nw.new_node("GeometryNodeInputNormal", []) + position = nw.new_node(Nodes.InputPosition, []) + normal = nw.new_node(Nodes.InputNormal, []) noises = [] @@ -231,7 +231,7 @@ def shader_MOUNTAIN( z_noise.inputs[1].default_value = np.random.uniform(0.1, 0.3) z = nw.add2(z, z_noise) - ramp = nw.new_node('ShaderNodeValToRGB', [z]) + ramp = nw.new_node(Nodes.ColorRamp, [z]) elements = ramp.color_ramp.elements elements.remove(elements[0]) # todo: better way to sample the initial color diff --git a/infinigen/assets/materials/new_whitewater.py b/infinigen/assets/materials/new_whitewater.py index 8582862e7..7406d3bfe 100644 --- a/infinigen/assets/materials/new_whitewater.py +++ b/infinigen/assets/materials/new_whitewater.py @@ -16,8 +16,7 @@ def new_whitewater(nw: NodeWrangler): input_kwargs={ "Base Color": (1.0000, 1.0000, 1.0000, 1.0000), "Subsurface Weight": 1.0, - "Subsurface Color": random_color_neighbour((0.7147, 0.6062, 0.8000, 1.0000), 0.05, 0.05, 0.05), - "Specular IOR Level": 0.0886 + 0.01 * normal(), + "Subsurface Radius": (0.05, 0.05, 0.05), "Roughness": 0.1500, "IOR": 1.1000, "Transmission Weight": 0.5000, @@ -33,9 +32,7 @@ def new_whitewater(nw: NodeWrangler): material_output = nw.new_node( Nodes.MaterialOutput, input_kwargs={"Surface": principled_bsdf, "Volume": volume_scatter}, - attrs={"is_active_output": True}, ) - def apply(obj, selection=None, **kwargs): surface.add_material(obj, new_whitewater, selection=selection) diff --git a/infinigen/assets/materials/nose.py b/infinigen/assets/materials/nose.py index 797746dee..eb1858d8f 100644 --- a/infinigen/assets/materials/nose.py +++ b/infinigen/assets/materials/nose.py @@ -16,7 +16,7 @@ def shader_nose(nw: NodeWrangler): # Code generated using version 2.4.3 of the node_transpiler musgrave_texture = nw.new_node(Nodes.MusgraveTexture, - input_kwargs={'Scale': U(2, 6), 'Detail': 14.699999999999999, 'Dimension': 1.5}) + input_kwargs={'Scale': U(2, 6), 'Detail': 14.699999999999999, 'Roughness': 1.5}) colorramp = nw.new_node(Nodes.ColorRamp, input_kwargs={'Fac': musgrave_texture}) diff --git a/infinigen/assets/materials/sand.py b/infinigen/assets/materials/sand.py index 6fa798412..d3169c560 100644 --- a/infinigen/assets/materials/sand.py +++ b/infinigen/assets/materials/sand.py @@ -67,8 +67,8 @@ def geo_SAND(nw, selection=None, ): nw.force_input_consistency() - normal = nw.new_node("GeometryNodeInputNormal", []) - position = nw.new_node("GeometryNodeInputPosition", []) + normal = nw.new_node(Nodes.InputNormal, []) + position = nw.new_node(Nodes.InputPosition, []) offsets = [] for i in range(n_waves): diff --git a/infinigen/assets/materials/slimy.py b/infinigen/assets/materials/slimy.py index a5c8926e5..6115c939f 100644 --- a/infinigen/assets/materials/slimy.py +++ b/infinigen/assets/materials/slimy.py @@ -54,10 +54,9 @@ def shader_slimy(nw, rand=False, **input_kwargs): input_kwargs={'Color1': colorramp_1.outputs["Color"], 'Color2': colorramp_4.outputs["Color"]}) principled_bsdf = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': (0.6605, 0.0279, 0.0359, 1.0), 'Subsurface': 0.2, 'Subsurface Color': (0.4621, 0.0213, 0.0265, 1.0), 'Specular': 0.8591, 'Roughness': mix_1}) + input_kwargs={'Base Color': (0.6605, 0.0279, 0.0359, 1.0), 'Subsurface Weight': 0.2, 'Roughness': mix_1}) if rand: sample_color(principled_bsdf.inputs['Base Color'].default_value) - sample_color(principled_bsdf.inputs['Subsurface Color'].default_value) material_output = nw.new_node(Nodes.MaterialOutput, input_kwargs={'Surface': principled_bsdf}) diff --git a/infinigen/assets/materials/snake_plant.py b/infinigen/assets/materials/snake_plant.py index f4dc29af0..270ddd1a6 100644 --- a/infinigen/assets/materials/snake_plant.py +++ b/infinigen/assets/materials/snake_plant.py @@ -105,7 +105,7 @@ def shader_snake_plant(nw: NodeWrangler): 'Color2': colorramp_3.outputs["Color"]}) principled_bsdf = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': mix, 'Roughness': U(8.0, 15.0), 'Clearcoat Roughness': 0.0}) + input_kwargs={'Base Color': mix, 'Roughness': U(8.0, 15.0), 'Coat Roughness': 0.0}) material_output = nw.new_node(Nodes.MaterialOutput, input_kwargs={'Surface': principled_bsdf}) diff --git a/infinigen/assets/materials/snake_shaders.py b/infinigen/assets/materials/snake_shaders.py index 5fe6ac9ca..01cc43053 100644 --- a/infinigen/assets/materials/snake_shaders.py +++ b/infinigen/assets/materials/snake_shaders.py @@ -54,7 +54,7 @@ def shader_black_white_snake(nw: NodeWrangler, rand=True): sample_color(e.color, offset=0.05, keep_sum=True) principled_bsdf = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': colorramp.outputs["Color"], 'Metallic': 0.6, 'Specular': 0.2, 'Roughness': 0.4}, + input_kwargs={'Base Color': colorramp.outputs["Color"], 'Metallic': 0.6, 'Roughness': 0.4}, attrs={'subsurface_method': 'BURLEY'}) material_output = nw.new_node(Nodes.MaterialOutput, @@ -83,7 +83,7 @@ def shader_brown(nw: NodeWrangler, rand=False): sample_color(e.color, offset=0.05) principled_bsdf_1 = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': colorramp_2.outputs["Color"], 'Metallic': 0.4, 'Specular': 0.3, 'Roughness': 1}, + input_kwargs={'Base Color': colorramp_2.outputs["Color"], 'Metallic': 0.4, 'Roughness': 1}, attrs={'subsurface_method': 'BURLEY'}) noise_texture_1 = nw.new_node(Nodes.NoiseTexture, @@ -183,7 +183,7 @@ def shader_golden(nw: NodeWrangler, rand=False): sample_color(e.color, offset=0.05, keep_sum=True) principled_bsdf = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': colorramp.outputs["Color"], 'Metallic': 0.4, 'Specular': 0.2, 'Roughness': 0.4}, + input_kwargs={'Base Color': colorramp.outputs["Color"], 'Metallic': 0.4, 'Roughness': 0.4}, attrs={'subsurface_method': 'BURLEY'}) material_output = nw.new_node(Nodes.MaterialOutput, diff --git a/infinigen/assets/materials/spider_plant.py b/infinigen/assets/materials/spider_plant.py index 1d920761b..74e046538 100644 --- a/infinigen/assets/materials/spider_plant.py +++ b/infinigen/assets/materials/spider_plant.py @@ -17,7 +17,7 @@ def shader_spider_plant(nw: NodeWrangler): main_color = hsv2rgba(main_hsv_color) principled_bsdf = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': main_color, 'Subsurface IOR': 1.01, + input_kwargs={'Base Color': main_color, 'Subsurface Weight': 1.01, 'Roughness': 2.0}) translucent_bsdf = nw.new_node(Nodes.TranslucentBSDF, diff --git a/infinigen/assets/materials/tongue.py b/infinigen/assets/materials/tongue.py index 8ecd0c4a8..2dddc6e95 100644 --- a/infinigen/assets/materials/tongue.py +++ b/infinigen/assets/materials/tongue.py @@ -26,7 +26,7 @@ def shader_tongue(nw: NodeWrangler): colorramp.color_ramp.elements[1].color = (0.0979, 0.0979, 0.0979, 1.0) principled_bsdf = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': (0.8, 0.0605, 0.0437, 1.0), 'Subsurface': 0.0312, 'Subsurface Color': (0.8, 0.0, 0.2679, 1.0), 'Roughness': colorramp.outputs["Color"]}) + input_kwargs={'Base Color': (0.8, 0.0605, 0.0437, 1.0), 'Subsurface Weight': 0.0312, 'Roughness': colorramp.outputs["Color"]}) material_output = nw.new_node(Nodes.MaterialOutput, input_kwargs={'Surface': principled_bsdf}) diff --git a/infinigen/assets/materials/waterfall_material.py b/infinigen/assets/materials/waterfall_material.py index 2805a708c..74b4106b7 100644 --- a/infinigen/assets/materials/waterfall_material.py +++ b/infinigen/assets/materials/waterfall_material.py @@ -3,12 +3,7 @@ # Authors: Karhan Kayan -import bpy -import mathutils -from numpy.random import uniform, normal, randint from infinigen.core.nodes.node_wrangler import Nodes, NodeWrangler -from infinigen.core.nodes import node_utils -from infinigen.core.util.color import color_category from infinigen.core import surface def waterfall_shader(nw: NodeWrangler): @@ -23,10 +18,10 @@ def waterfall_shader(nw: NodeWrangler): input_kwargs={'Color': rgb}) principled_bsdf = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Base Color': rgb, 'Roughness': 0.0, 'IOR': 1.33, 'Transmission': 1.0}) + input_kwargs={'Base Color': rgb, 'Roughness': 0.0, 'IOR': 1.33, 'Transmission Weight': 1.0}) mix_shader = nw.new_node(Nodes.MixShader, - input_kwargs={'Fac': light_path.outputs["Is Camera Ray"], 1: transparent_bsdf, 2: principled_bsdf}) + input_kwargs={'Fac': light_path.outputs["Is Camera Ray"], 'Shader': transparent_bsdf, 'Shader_001': principled_bsdf}) texture_coordinate = nw.new_node(Nodes.TextureCoord) @@ -34,58 +29,57 @@ def waterfall_shader(nw: NodeWrangler): input_kwargs={'Vector': texture_coordinate.outputs["Object"]}) musgrave_texture_1 = nw.new_node(Nodes.MusgraveTexture, - input_kwargs={'Vector': mapping, 'Scale': 3.3, 'Detail': 13.0, 'Dimension': 0.3}) + input_kwargs={'Vector': mapping, 'Scale': 3.3, 'Detail': 13.0, 'Roughness': 0.3}) colorramp = nw.new_node(Nodes.ColorRamp, input_kwargs={'Fac': musgrave_texture_1}) - colorramp.color_ramp.interpolation = "B_SPLINE" - colorramp.color_ramp.elements[0].position = 0.325 + colorramp.color_ramp.interpolation = "EASE" + colorramp.color_ramp.elements[0].position = 0.325 colorramp.color_ramp.elements[0].color = (0.0, 0.0, 0.0, 1.0) colorramp.color_ramp.elements[1].position = 0.6727 colorramp.color_ramp.elements[1].color = (1.0, 1.0, 1.0, 1.0) - principled_bsdf_1 = nw.new_node(Nodes.PrincipledBSDF, - input_kwargs={'Metallic': 0.2636, 'Specular': 1.0, 'Roughness': 0.0, 'IOR': 1.333, 'Transmission': 0.8205, 'Alpha': colorramp.outputs["Color"]}) + principled_bsdf_1 = nw.new_node(Nodes.PrincipledBSDF, + input_kwargs={'Metallic': 0.2636, 'Roughness': 0.0, 'IOR': 1.333, 'Transmission Weight': 0.8205, 'Alpha': colorramp.outputs["Color"]}) mix_shader_1 = nw.new_node(Nodes.MixShader, - input_kwargs={1: mix_shader, 2: principled_bsdf_1}) + input_kwargs={'Shader': mix_shader, 'Shader_001': principled_bsdf_1}) - volume_scatter = nw.new_node('ShaderNodeVolumeScatter', + volume_scatter = nw.new_node(Nodes.VolumeScatter, input_kwargs={'Color': (0.5841, 0.7339, 0.8, 1.0)}) - material_output = nw.new_node(Nodes.MaterialOutput, + material_output = nw.new_node(Nodes.MaterialOutput, input_kwargs={'Surface': mix_shader_1, 'Volume': volume_scatter}) def geometry_geo_water(nw: NodeWrangler): # Code generated using version 2.4.3 of the node_transpiler - - group_input = nw.new_node(Nodes.GroupInput, - expose_input=[('NodeSocketGeometry', 'Geometry', None)]) + + group_input = nw.expose_input('Geometry', dtype='NodeSocketGeometry') position = nw.new_node(Nodes.InputPosition) add = nw.new_node(Nodes.VectorMath, - input_kwargs={0: position, 1: (630.0, 564.0, 374.0)}) + input_kwargs={'Vector': position, 'Vector_001': (630.0, 564.0, 374.0)}) musgrave_texture = nw.new_node(Nodes.MusgraveTexture, - input_kwargs={'Vector': add.outputs["Vector"], 'Scale': 4.1307, 'Detail': 9.7953, 'Dimension': 1.34, 'Lacunarity': 1.8087}) + input_kwargs={'Vector': add.outputs["Vector"], 'Scale': 4.1307, 'Detail': 9.7953, 'Roughness': 1.34, 'Lacunarity': 1.8087}) multiply = nw.new_node(Nodes.VectorMath, - input_kwargs={0: musgrave_texture, 1: (0.0, 0.0, 0.0128)}, + input_kwargs={'Vector': musgrave_texture, 'Vector_001': (0.0, 0.0, 0.0128)}, attrs={'operation': 'MULTIPLY'}) - value = nw.new_node(Nodes.Value) + value = nw.new_node(Nodes.Value) value.outputs[0].default_value = 1.0 multiply_1 = nw.new_node(Nodes.VectorMath, - input_kwargs={0: multiply.outputs["Vector"], 1: value}, + input_kwargs={'Vector': multiply.outputs["Vector"], 'Vector_001': value}, attrs={'operation': 'MULTIPLY'}) set_position = nw.new_node(Nodes.SetPosition, - input_kwargs={'Geometry': group_input.outputs["Geometry"], 'Offset': multiply_1.outputs["Vector"]}) - + input_kwargs={'Geometry': group_input, 'Offset': multiply_1.outputs["Vector"]}) + group_output = nw.new_node(Nodes.GroupOutput, - input_kwargs={'Geometry': set_position}) + input_kwargs={'Geometry': set_position.outputs['Geometry']}) diff --git a/infinigen/core/execute_tasks.py b/infinigen/core/execute_tasks.py index 482286acb..9c25f8a07 100644 --- a/infinigen/core/execute_tasks.py +++ b/infinigen/core/execute_tasks.py @@ -47,10 +47,10 @@ pine_needle, seaweed, coral_reef, jellyfish, urchin ) -from infinigen.assets.materials import ( - mountain, sand, water, atmosphere_light_haze, sandstone, cracked_ground, \ - soil, dirt, cobble_stone, chunkyrock, stone, lava, ice, mud, snow -) +# from infinigen.assets.materials import ( +# mountain, sand, water, atmosphere_light_haze, sandstone, cracked_ground, \ +# soil, dirt, cobble_stone, chunkyrock, stone, lava, ice, mud, snow +# ) from infinigen.assets import ( fluid, diff --git a/infinigen/core/nodes/node_info.py b/infinigen/core/nodes/node_info.py index 201cbfb18..860627728 100644 --- a/infinigen/core/nodes/node_info.py +++ b/infinigen/core/nodes/node_info.py @@ -21,6 +21,7 @@ class Nodes: Mix = "ShaderNodeMix" VolumeScatter = "ShaderNodeVolumeScatter" Displacement = "ShaderNodeDisplacement" + Tree = "ShaderNodeTree" # Attribute Attribute = "ShaderNodeAttribute" diff --git a/infinigen/core/nodes/node_utils.py b/infinigen/core/nodes/node_utils.py index 90d511c90..544346681 100644 --- a/infinigen/core/nodes/node_utils.py +++ b/infinigen/core/nodes/node_utils.py @@ -13,7 +13,7 @@ import bpy from infinigen.core import surface -from infinigen.core.nodes.node_wrangler import Nodes, NodeWrangler +from infinigen.core.nodes.node_wrangler import Nodes, NodeWrangler, geometry_node_group_empty_new from infinigen.core.util.blender import group_in_collection from infinigen.core.util.color import random_color_mapping @@ -47,7 +47,8 @@ def init_fn(*args, **kwargs): if singleton and name in bpy.data.node_groups: return bpy.data.node_groups[name] else: - ng = bpy.data.node_groups.new(name, type) + ng = geometry_node_group_empty_new() + ng.name = name nw = NodeWrangler(ng) fn(nw, *args, **kwargs) return ng diff --git a/infinigen/core/nodes/node_wrangler.py b/infinigen/core/nodes/node_wrangler.py index f17ac4730..309a4f0b0 100644 --- a/infinigen/core/nodes/node_wrangler.py +++ b/infinigen/core/nodes/node_wrangler.py @@ -33,22 +33,28 @@ class NodeMisuseWarning(UserWarning): # This is for Blender 4.1 because of the nodetree change def geometry_node_group_empty_new(): + # Create a new node group for geometry nodes group = bpy.data.node_groups.new("Geometry Nodes", 'GeometryNodeTree') interface = group.interface - interface.new_socket(name="Geometry", in_out='INPUT', socket_type='NodeSocketGeometry', description="") - interface.new_socket(name="Geometry", in_out='OUTPUT', socket_type='NodeSocketGeometry', description="") + # Add inputs and outputs using the new method + interface.new_socket(name="Geometry", in_out='INPUT', socket_type='NodeSocketGeometry') + interface.new_socket(name="Geometry", in_out='OUTPUT', socket_type='NodeSocketGeometry') + # Create the group input and output nodes input_node = group.nodes.new('NodeGroupInput') output_node = group.nodes.new('NodeGroupOutput') output_node.is_active_output = True + # Set node selection input_node.select = False output_node.select = False + # Set node positions input_node.location.x = -200 - input_node.width output_node.location.x = 200 + # Link nodes group.links.new(output_node.inputs[0], input_node.outputs[0]) return group @@ -133,14 +139,14 @@ def infer_input_socket(node, input_socket_name): class NodeWrangler(): def __init__(self, node_group): - if issubclass(type(node_group), bpy.types.NodeTree): + if isinstance(node_group, bpy.types.NodeTree): self.modifier = None self.node_group = node_group - elif issubclass(type(node_group), bpy.types.NodesModifier): + elif isinstance(node_group, bpy.types.NodesModifier): self.modifier = node_group self.node_group = self.modifier.node_group else: - raise ValueError(f'Couldnt initialize NodeWrangler with {node_group=}, {type(node_group)=}') + raise ValueError(f'Couldn\'t initialize NodeWrangler with {node_group=}, {type(node_group)=}') self.interface = self.node_group.interface @@ -188,20 +194,15 @@ def new_node( if attrs is not None: for key, val in attrs.items(): - # if key not in NODE_ATTRS_AVAILABLE.get(node.bl_idname, []): - # warnings.warn(f'Node Wrangler is setting attr {repr(key)} on {node.bl_idname=}, - # but it is not in node_info.NODE_ATTRS_AVAILABLE. Please add it so that the transpiler is - # aware') try: setattr(node, key, val) except AttributeError as e: logger.error(f"Failed to set attribute {key} on node {node.name}: {e}") - # TODO: This section causes errors if node_type in [Nodes.VoronoiTexture, Nodes.NoiseTexture, Nodes.WaveTexture, Nodes.WhiteNoiseTexture, Nodes.MusgraveTexture]: if not (input_args != [] or "Vector" in input_kwargs): - w = f"{self.node_group=}, no vector input for noise texture in specified" + w = f"{self.node_group=}, no vector input for noise texture specified" if self.input_consistency_forced: logger.debug(f"{w}, it is fixed automatically by using position for consistency") if self.node_group.type == "SHADER": @@ -209,36 +210,38 @@ def new_node( else: input_kwargs["Vector"] = self.new_node(Nodes.InputPosition) else: - pass #print(f"{w}, please fix it if you found it causes inconsistency") - - # input_keyval_list = list(enumerate(input_args)) + list(input_kwargs.items()) - # for input_socket_name, input_item in input_keyval_list: - # if input_item is None: - # continue - # if node_type == Nodes.GroupOutput: - # assert not isinstance(input_socket_name, int), ( - # 'Attribute inputs to group output nodes must be given a string ' - # 'name, integer name {input_socket_name} will not suffice' - # ) - # assert not isinstance(input_item, list), 'Multi-input sockets to GroupOutput nodes are impossible' - # if input_socket_name not in node.inputs: - # nodeclass = infer_output_socket(input_item).bl_idname - # self.node_group.interface.new_socket( - # name=input_socket_name, in_out='OUTPUT', socket_type=nodeclass, description='' - # ) - # assert input_socket_name in node.inputs and node.inputs[input_socket_name].enabled - - # input_socket = infer_input_socket(node, input_socket_name) - # self.connect_input(input_socket, input_item) - - # if expose_input is not None: - # names = [v[1] for v in expose_input] - # uniq, counts = np.unique(names, return_counts=True) - # if (counts > 1).any(): - # raise ValueError(f'expose_input with {names} features duplicate entries. in bl3.5 this is invalid.') - # for inp in expose_input: - # nodeclass, name, val = inp - # self.expose_input(name, val=val, dtype=nodeclass) + logger.warning(f"{w}, please fix it if you found it causes inconsistency") + + input_keyval_list = list(enumerate(input_args)) + list(input_kwargs.items()) + for input_socket_name, input_item in input_keyval_list: + if input_item is None: + continue + if node_type == Nodes.GroupOutput: + assert not isinstance(input_socket_name, int), ( + 'Attribute inputs to group output nodes must be given a string ' + 'name, integer name {input_socket_name} will not suffice' + ) + assert not isinstance(input_item, list), 'Multi-input sockets to GroupOutput nodes are impossible' + if input_socket_name not in node.inputs: + nodeclass = infer_output_socket(input_item).bl_idname + if self.node_group.type == 'GEOMETRY': + self.interface.new_socket(name=input_socket_name, in_out='OUTPUT', socket_type=nodeclass) + else: + self.node_group.outputs.new(nodeclass, input_socket_name) + assert input_socket_name in node.inputs and node.inputs[input_socket_name].enabled + + input_socket = infer_input_socket(node, input_socket_name) + self.connect_input(input_socket, input_item) + + + if expose_input is not None: + names = [v[1] for v in expose_input] + unique_names, counts = np.unique(names, return_counts=True) + if (counts > 1).any(): + raise ValueError(f'expose_input with {names} features duplicate entries. In Blender 4.1, this is invalid.') + for inp in expose_input: + nodeclass, name, val = inp + self.expose_input(name, val=val, dtype=nodeclass) return node @@ -263,10 +266,10 @@ def expose_input(self, name, val=None, attribute=None, dtype=None, use_namednode group_input = self.new_node(Nodes.GroupInput) # will reuse singleton nodeclass = self._infer_nodeclass_from_args(dtype, val) - inp = self.node_group.interface.new_socket(name=name, in_out='INPUT', socket_type=nodeclass) + inp = self.interface.new_socket(name=name, in_out='INPUT', socket_type=nodeclass) def prepare_cast(to_type, val): - # cast val only when necessary, and only when type(val) wont crash + # cast val only when necessary, and only when type(val) won't crash if to_type not in [bpy.types.bpy_prop_array, bpy.types.bpy_prop]: val = to_type(val) return val @@ -274,7 +277,7 @@ def prepare_cast(to_type, val): if val is not None: if not hasattr(inp, 'default_value') or inp.default_value is None: raise ValueError( - f'expose_input() recieved {val=} but inp {inp} does not expect a default_value') + f'expose_input() received {val=} but inp {inp} does not expect a default_value') inp.default_value = prepare_cast(type(inp.default_value), val) if self.modifier is not None: @@ -323,7 +326,7 @@ def _update_socket(self, input_socket, input_item): output_socket = infer_output_socket(input_item) if output_socket is None and hasattr(input_socket, 'default_value'): - # we couldnt parse the inp to be any kind of node, it must be a default_value for us to assign + # we couldn't parse the inp to be any kind of node, it must be a default_value for us to assign try: input_socket.default_value = input_item return @@ -371,7 +374,7 @@ def _make_node(self, node_type): return node def get_position_translation_seed(self, i): - if not i in self.position_translation_seed: + if i not in self.position_translation_seed: self.position_translation_seed[i] = random_vector3() return self.position_translation_seed[i] @@ -480,21 +483,21 @@ def boolean_math(self, node_type, *nodes): def compare(self, node_type, *nodes): return self.new_node(Nodes.Compare, attrs={'operation': node_type}, input_args=nodes) - + def compare_direction(self, node_type, x, y, angle): - return self.new_node(Nodes.Compare, input_kwargs={'A': x, 'B': y, 'Angle': angle}, - attrs={'data_type': 'VECTOR', 'mode': 'DIRECTION', 'operation': node_type}) + return self.new_node(Nodes.Compare, input_kwargs={'A': x, 'B': y, 'Angle': angle}, + attrs={'data_type': 'VECTOR', 'mode': 'DIRECTION', 'operation': node_type}) def bernoulli(self, prob, seed=None): if seed is None: seed = np.random.randint(1e5) return self.new_node(Nodes.RandomValue, input_kwargs={'Probability': prob, 'Seed': seed}, - attrs={'data_type': 'BOOLEAN'}) + attrs={'data_type': 'BOOLEAN'}) def uniform(self, low=0., high=1., seed=None, data_type='FLOAT'): if seed is None: seed = np.random.randint(1e5) if isinstance(low, Iterable): data_type = 'FLOAT_VECTOR' return self.new_node(Nodes.RandomValue, input_kwargs={'Min': low, 'Max': high, 'Seed': seed}, - attrs={'data_type': data_type}) + attrs={'data_type': data_type}) def combine(self, x, y, z): return self.new_node(Nodes.CombineXYZ, [x, y, z]) @@ -504,11 +507,11 @@ def separate(self, x): def switch(self, pred, true, false, input_type='FLOAT'): return self.new_node(Nodes.Switch, input_kwargs={'Switch': pred, 'True': true, 'False': false}, - attrs={'input_type': input_type}) + attrs={'input_type': input_type}) def vector_switch(self, pred, true, false): return self.new_node(Nodes.Switch, input_kwargs={'Switch': pred, 'True': true, 'False': false}, - attrs={'input_type': 'VECTOR'}) + attrs={'input_type': 'VECTOR'}) def geometry2point(self, geometry): return self.new_node(Nodes.MergeByDistance, input_kwargs={'Geometry': geometry, 'Distance': 100.}) @@ -524,12 +527,12 @@ def capture(self, geometry, attribute, attrs=None): def musgrave(self, scale=10, vector=None): return self.new_node(Nodes.MapRange, - [self.new_node(Nodes.MusgraveTexture, [vector], input_kwargs={'Scale': scale}), -1, - 1, 0, 1]) + [self.new_node(Nodes.MusgraveTexture, [vector], input_kwargs={'Scale': scale}), -1, + 1, 0, 1]) def curve2mesh(self, curve, profile_curve=None): return self.new_node(Nodes.SetShadeSmooth, - [self.new_node(Nodes.CurveToMesh, [curve, profile_curve, True]), None, False]) + [self.new_node(Nodes.CurveToMesh, [curve, profile_curve, True]), None, False]) def build_float_curve(self, x, anchors, handle='VECTOR'): float_curve = self.new_node(Nodes.FloatCurve, input_kwargs={'Value': x}) @@ -550,4 +553,4 @@ def build_case(self, value, inputs, outputs, input_type='FLOAT'): return node def build_index_case(self, inputs): - return self.build_case(self.new_node(Nodes.Index), inputs + [-1], [True] * len(inputs) + [False]) + return self.build_case(self.new_node(Nodes.Index), inputs + [-1], [True] * len(inputs) + [False]) \ No newline at end of file