Refactor and enhance geometry node groups for depth plane and material layers
- Updated the depth plane node group to load from an asset and simplified the interface. - Created a new build script for depth plane geometry nodes. - Introduced material layer groups for image and depth materials with appropriate sockets. - Added functionality to connect balloon normal scale to the image material. - Enhanced tests to validate the new node groups and their connections. - Ensured that production code does not create node groups directly.
This commit is contained in:
@@ -17,6 +17,8 @@ from build_cutout import (
|
||||
build_cutout_modifier_group,
|
||||
build_node_group,
|
||||
)
|
||||
from build_depth_plane import build_depth_plane_group
|
||||
from build_material_layers import build_material_layer_group
|
||||
from build_mesh_plane import build_mesh_plane_group
|
||||
from build_shadeless import build_shadeless_group
|
||||
OUTPUT_PATH = (
|
||||
@@ -31,7 +33,10 @@ OUTPUT_PATH = (
|
||||
def main():
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
bpy.context.preferences.filepaths.save_version = 0
|
||||
build_mesh_plane_group()
|
||||
mesh_plane = build_mesh_plane_group()
|
||||
build_depth_plane_group(mesh_plane)
|
||||
build_material_layer_group()
|
||||
build_material_layer_group(depth_plane=True)
|
||||
build_shadeless_group()
|
||||
shape_groups = {
|
||||
shape: build_node_group(shape)
|
||||
|
||||
190
tools/node_assets/build_depth_plane.py
Normal file
190
tools/node_assets/build_depth_plane.py
Normal file
@@ -0,0 +1,190 @@
|
||||
"""Build the Depth Plane Geometry Nodes group."""
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
DEPTH_PLANE_NODE_GROUP_NAME = "O Image Depth Plane"
|
||||
|
||||
|
||||
def _interface_socket(group, name, in_out, socket_type):
|
||||
socket = group.interface.new_socket(
|
||||
name=name,
|
||||
in_out=in_out,
|
||||
socket_type=socket_type,
|
||||
)
|
||||
if in_out == "INPUT" and hasattr(socket, "structure_type"):
|
||||
socket.structure_type = "SINGLE"
|
||||
return socket
|
||||
|
||||
|
||||
def _group_input(nodes, location, visible_names):
|
||||
node = nodes.new("NodeGroupInput")
|
||||
node.location = location
|
||||
visible = set(visible_names)
|
||||
for output in node.outputs:
|
||||
output.hide = output.name not in visible
|
||||
return node
|
||||
|
||||
|
||||
def build_depth_plane_group(mesh_plane_group):
|
||||
group = bpy.data.node_groups.get(DEPTH_PLANE_NODE_GROUP_NAME)
|
||||
if group is not None:
|
||||
return group
|
||||
group = bpy.data.node_groups.new(
|
||||
DEPTH_PLANE_NODE_GROUP_NAME,
|
||||
"GeometryNodeTree",
|
||||
)
|
||||
group.is_modifier = True
|
||||
_interface_socket(group, "Geometry", "INPUT", "NodeSocketGeometry")
|
||||
subdivide = _interface_socket(group, "Subdivide", "INPUT", "NodeSocketInt")
|
||||
subdivide.default_value = 7
|
||||
subdivide.min_value = 0
|
||||
subdivide.max_value = 10
|
||||
thickness = _interface_socket(group, "Thickness", "INPUT", "NodeSocketFloat")
|
||||
thickness.default_value = 0.1
|
||||
thickness.min_value = 0.0
|
||||
thickness.subtype = "DISTANCE"
|
||||
depth_amount = _interface_socket(group, "Depth Amount", "INPUT", "NodeSocketFloat")
|
||||
depth_amount.default_value = 1.0
|
||||
depth_amount.min_value = 0.0
|
||||
reference_depth = _interface_socket(
|
||||
group, "Reference Depth", "INPUT", "NodeSocketFloat"
|
||||
)
|
||||
reference_depth.hide_in_modifier = True
|
||||
uniform_scale = _interface_socket(
|
||||
group, "Uniform Scale", "INPUT", "NodeSocketFloat"
|
||||
)
|
||||
uniform_scale.hide_in_modifier = True
|
||||
depth_image = _interface_socket(group, "Depth Image", "INPUT", "NodeSocketImage")
|
||||
depth_image.hide_in_modifier = True
|
||||
material = _interface_socket(group, "Material", "INPUT", "NodeSocketMaterial")
|
||||
material.hide_in_modifier = True
|
||||
_interface_socket(group, "Geometry", "OUTPUT", "NodeSocketGeometry")
|
||||
|
||||
nodes = group.nodes
|
||||
links = group.links
|
||||
geometry_input = _group_input(
|
||||
nodes,
|
||||
(-1850.0, 450.0),
|
||||
{"Geometry", "Subdivide", "Material"},
|
||||
)
|
||||
shape_input = _group_input(
|
||||
nodes,
|
||||
(-1250.0, 850.0),
|
||||
{"Thickness", "Depth Amount"},
|
||||
)
|
||||
image_input = _group_input(
|
||||
nodes,
|
||||
(-1050.0, 50.0),
|
||||
{"Depth Image", "Reference Depth", "Uniform Scale"},
|
||||
)
|
||||
cleanup_input = _group_input(nodes, (650.0, -200.0), {"Thickness"})
|
||||
group_output = nodes.new("NodeGroupOutput")
|
||||
group_output.location = (1850.0, 450.0)
|
||||
mesh_plane = nodes.new("GeometryNodeGroup")
|
||||
mesh_plane.node_tree = mesh_plane_group
|
||||
mesh_plane.inputs["Thickness"].default_value = 0.0
|
||||
mesh_plane.location = (-1550.0, 450.0)
|
||||
links.new(geometry_input.outputs["Geometry"], mesh_plane.inputs["Geometry"])
|
||||
links.new(geometry_input.outputs["Subdivide"], mesh_plane.inputs["Subdivide"])
|
||||
links.new(geometry_input.outputs["Material"], mesh_plane.inputs["Material"])
|
||||
|
||||
extrude = nodes.new("GeometryNodeExtrudeMesh")
|
||||
extrude.mode = "FACES"
|
||||
extrude.inputs["Offset"].default_value = (0.0, 0.0, -1.0)
|
||||
extrude.inputs["Individual"].default_value = False
|
||||
extrude.location = (-1200.0, 450.0)
|
||||
links.new(mesh_plane.outputs["Geometry"], extrude.inputs["Mesh"])
|
||||
links.new(shape_input.outputs["Thickness"], extrude.inputs["Offset Scale"])
|
||||
geometry = extrude.outputs["Mesh"]
|
||||
|
||||
uv = nodes.new("GeometryNodeInputNamedAttribute")
|
||||
uv.data_type = "FLOAT_VECTOR"
|
||||
uv.inputs["Name"].default_value = "UVMap"
|
||||
uv.location = (-1000.0, 50.0)
|
||||
texture = nodes.new("GeometryNodeImageTexture")
|
||||
texture.location = (-800.0, 50.0)
|
||||
links.new(image_input.outputs["Depth Image"], texture.inputs["Image"])
|
||||
links.new(uv.outputs["Attribute"], texture.inputs["Vector"])
|
||||
separate = nodes.new("ShaderNodeSeparateXYZ")
|
||||
separate.location = (-600.0, 50.0)
|
||||
links.new(texture.outputs["Color"], separate.inputs["Vector"])
|
||||
relative_depth = nodes.new("ShaderNodeMath")
|
||||
relative_depth.operation = "SUBTRACT"
|
||||
relative_depth.location = (-600.0, -150.0)
|
||||
links.new(image_input.outputs["Reference Depth"], relative_depth.inputs[0])
|
||||
links.new(separate.outputs["X"], relative_depth.inputs[1])
|
||||
local_depth = nodes.new("ShaderNodeMath")
|
||||
local_depth.operation = "MULTIPLY"
|
||||
local_depth.location = (-350.0, -150.0)
|
||||
links.new(relative_depth.outputs[0], local_depth.inputs[0])
|
||||
links.new(image_input.outputs["Uniform Scale"], local_depth.inputs[1])
|
||||
raw_depth = nodes.new("ShaderNodeMath")
|
||||
raw_depth.operation = "MULTIPLY"
|
||||
raw_depth.location = (-100.0, 150.0)
|
||||
links.new(local_depth.outputs[0], raw_depth.inputs[0])
|
||||
links.new(shape_input.outputs["Depth Amount"], raw_depth.inputs[1])
|
||||
inward_limit = nodes.new("ShaderNodeMath")
|
||||
inward_limit.operation = "MULTIPLY"
|
||||
inward_limit.inputs[1].default_value = -0.98
|
||||
inward_limit.location = (-100.0, -50.0)
|
||||
links.new(shape_input.outputs["Thickness"], inward_limit.inputs[0])
|
||||
clamp = nodes.new("ShaderNodeMath")
|
||||
clamp.operation = "MAXIMUM"
|
||||
clamp.location = (150.0, 50.0)
|
||||
links.new(raw_depth.outputs[0], clamp.inputs[0])
|
||||
links.new(inward_limit.outputs[0], clamp.inputs[1])
|
||||
has_thickness = nodes.new("ShaderNodeMath")
|
||||
has_thickness.operation = "GREATER_THAN"
|
||||
has_thickness.inputs[1].default_value = 1e-6
|
||||
has_thickness.location = (-100.0, -350.0)
|
||||
links.new(shape_input.outputs["Thickness"], has_thickness.inputs[0])
|
||||
choose_depth = nodes.new("GeometryNodeSwitch")
|
||||
choose_depth.input_type = "FLOAT"
|
||||
choose_depth.location = (400.0, 50.0)
|
||||
links.new(has_thickness.outputs[0], choose_depth.inputs["Switch"])
|
||||
links.new(raw_depth.outputs[0], choose_depth.inputs["False"])
|
||||
links.new(clamp.outputs[0], choose_depth.inputs["True"])
|
||||
combine = nodes.new("ShaderNodeCombineXYZ")
|
||||
combine.location = (600.0, 50.0)
|
||||
links.new(choose_depth.outputs["Output"], combine.inputs["Z"])
|
||||
front = nodes.new("FunctionNodeBooleanMath")
|
||||
front.operation = "NOT"
|
||||
front.location = (400.0, 300.0)
|
||||
links.new(extrude.outputs["Top"], front.inputs[0])
|
||||
set_position = nodes.new("GeometryNodeSetPosition")
|
||||
set_position.location = (800.0, 450.0)
|
||||
links.new(geometry, set_position.inputs["Geometry"])
|
||||
links.new(front.outputs[0], set_position.inputs["Selection"])
|
||||
links.new(combine.outputs["Vector"], set_position.inputs["Offset"])
|
||||
geometry = set_position.outputs["Geometry"]
|
||||
|
||||
zero_thickness = nodes.new("ShaderNodeMath")
|
||||
zero_thickness.operation = "LESS_THAN"
|
||||
zero_thickness.inputs[1].default_value = 1e-6
|
||||
zero_thickness.location = (1000.0, -150.0)
|
||||
links.new(cleanup_input.outputs["Thickness"], zero_thickness.inputs[0])
|
||||
back_or_side = nodes.new("FunctionNodeBooleanMath")
|
||||
back_or_side.operation = "OR"
|
||||
back_or_side.location = (1000.0, 150.0)
|
||||
links.new(extrude.outputs["Top"], back_or_side.inputs[0])
|
||||
links.new(extrude.outputs["Side"], back_or_side.inputs[1])
|
||||
delete_selection = nodes.new("FunctionNodeBooleanMath")
|
||||
delete_selection.operation = "AND"
|
||||
delete_selection.location = (1200.0, 50.0)
|
||||
links.new(zero_thickness.outputs[0], delete_selection.inputs[0])
|
||||
links.new(back_or_side.outputs[0], delete_selection.inputs[1])
|
||||
delete_geometry = nodes.new("GeometryNodeDeleteGeometry")
|
||||
delete_geometry.domain = "FACE"
|
||||
delete_geometry.location = (1350.0, 450.0)
|
||||
links.new(geometry, delete_geometry.inputs["Geometry"])
|
||||
links.new(delete_selection.outputs[0], delete_geometry.inputs["Selection"])
|
||||
shade_smooth = nodes.new("GeometryNodeSetShadeSmooth")
|
||||
shade_smooth.domain = "FACE"
|
||||
shade_smooth.inputs["Shade Smooth"].default_value = True
|
||||
shade_smooth.location = (1600.0, 450.0)
|
||||
links.new(delete_geometry.outputs["Geometry"], shade_smooth.inputs["Geometry"])
|
||||
links.new(shade_smooth.outputs["Geometry"], group_output.inputs["Geometry"])
|
||||
group.use_fake_user = True
|
||||
return group
|
||||
|
||||
195
tools/node_assets/build_material_layers.py
Normal file
195
tools/node_assets/build_material_layers.py
Normal file
@@ -0,0 +1,195 @@
|
||||
"""Build the image material Shader node groups."""
|
||||
|
||||
import bpy
|
||||
|
||||
from anyimage.operators.common.mesh_result import (
|
||||
DEPTH_MATERIAL_NODE_GROUP_NAME,
|
||||
IMAGE_MATERIAL_NODE_GROUP_NAME,
|
||||
)
|
||||
|
||||
|
||||
BUMP_BASE_DISTANCE = 0.001
|
||||
MATERIAL_DISPLACEMENT_ATTRIBUTE = "o_material_displacement"
|
||||
BACKGROUND_DEPTH_ATTRIBUTE = "o_background_depth"
|
||||
DEPTH_SCALE_ATTRIBUTE = "o_depth_scale"
|
||||
|
||||
|
||||
def build_material_layer_group(depth_plane=False):
|
||||
group_name = (
|
||||
DEPTH_MATERIAL_NODE_GROUP_NAME
|
||||
if depth_plane
|
||||
else IMAGE_MATERIAL_NODE_GROUP_NAME
|
||||
)
|
||||
existing = bpy.data.node_groups.get(group_name)
|
||||
if existing is not None:
|
||||
return existing
|
||||
group = bpy.data.node_groups.new(group_name, "ShaderNodeTree")
|
||||
interface = group.interface
|
||||
input_sockets = [
|
||||
("Color", "NodeSocketColor"),
|
||||
("Alpha", "NodeSocketFloat"),
|
||||
("Bump Scale", "NodeSocketFloat"),
|
||||
]
|
||||
normal_group = not depth_plane
|
||||
if normal_group:
|
||||
input_sockets.insert(2, ("Normal", "NodeSocketColor"))
|
||||
input_sockets.insert(3, ("Normal Scale", "NodeSocketFloat"))
|
||||
input_sockets.insert(4, ("Object Space", "NodeSocketBool"))
|
||||
if depth_plane:
|
||||
input_sockets.insert(2, ("Depth", "NodeSocketFloat"))
|
||||
for name, socket_type in input_sockets:
|
||||
socket = interface.new_socket(
|
||||
name=name,
|
||||
in_out="INPUT",
|
||||
socket_type=socket_type,
|
||||
)
|
||||
if name == "Alpha":
|
||||
socket.default_value = 1.0
|
||||
socket.min_value = 0.0
|
||||
socket.max_value = 1.0
|
||||
socket.subtype = "FACTOR"
|
||||
elif name == "Bump Scale":
|
||||
socket.default_value = 0.0
|
||||
socket.min_value = -10000.0
|
||||
socket.max_value = 10000.0
|
||||
elif name == "Normal":
|
||||
socket.default_value = (0.5, 0.5, 1.0, 1.0)
|
||||
elif name == "Normal Scale":
|
||||
socket.default_value = 1.0
|
||||
socket.min_value = 0.0
|
||||
socket.max_value = 10.0
|
||||
elif name == "Object Space":
|
||||
socket.default_value = False
|
||||
output_sockets = [
|
||||
("Color", "NodeSocketColor"),
|
||||
("Roughness", "NodeSocketFloat"),
|
||||
("Alpha", "NodeSocketFloat"),
|
||||
("Normal", "NodeSocketVector"),
|
||||
]
|
||||
if depth_plane:
|
||||
output_sockets.append(("Displacement", "NodeSocketVector"))
|
||||
for name, socket_type in output_sockets:
|
||||
interface.new_socket(
|
||||
name=name,
|
||||
in_out="OUTPUT",
|
||||
socket_type=socket_type,
|
||||
)
|
||||
|
||||
nodes = group.nodes
|
||||
links = group.links
|
||||
group_input = nodes.new("NodeGroupInput")
|
||||
group_input.location = (-500.0, 100.0)
|
||||
group_output = nodes.new("NodeGroupOutput")
|
||||
group_output.location = (300.0, 100.0)
|
||||
roughness_curve = nodes.new("ShaderNodeFloatCurve")
|
||||
roughness_curve.mapping.initialize()
|
||||
curve_points = roughness_curve.mapping.curves[0].points
|
||||
curve_points[0].location = (0.0, 0.5)
|
||||
curve_points[-1].location = (1.0, 0.1)
|
||||
roughness_curve.mapping.update()
|
||||
roughness_curve.location = (-250.0, 350.0)
|
||||
bump = nodes.new("ShaderNodeBump")
|
||||
bump.location = (100.0, 0.0)
|
||||
if normal_group:
|
||||
tangent_normal = nodes.new("ShaderNodeNormalMap")
|
||||
tangent_normal.space = "TANGENT"
|
||||
tangent_normal.location = (-500.0, -100.0)
|
||||
object_normal = nodes.new("ShaderNodeNormalMap")
|
||||
object_normal.space = "OBJECT"
|
||||
object_normal.location = (-500.0, -350.0)
|
||||
choose_normal = nodes.new("ShaderNodeMix")
|
||||
choose_normal.data_type = "VECTOR"
|
||||
choose_normal.location = (-150.0, -150.0)
|
||||
for normal_map in (tangent_normal, object_normal):
|
||||
links.new(group_input.outputs["Normal"], normal_map.inputs["Color"])
|
||||
links.new(
|
||||
group_input.outputs["Normal Scale"],
|
||||
normal_map.inputs["Strength"],
|
||||
)
|
||||
links.new(group_input.outputs["Object Space"], choose_normal.inputs[0])
|
||||
links.new(tangent_normal.outputs["Normal"], choose_normal.inputs[4])
|
||||
links.new(object_normal.outputs["Normal"], choose_normal.inputs[5])
|
||||
links.new(choose_normal.outputs["Result"], bump.inputs["Normal"])
|
||||
displacement = None
|
||||
|
||||
processed_alpha = group_input.outputs["Alpha"]
|
||||
bump_depth = group_input.outputs["Color"]
|
||||
if depth_plane:
|
||||
displacement = nodes.new("ShaderNodeDisplacement")
|
||||
displacement.inputs["Midlevel"].default_value = 0.0
|
||||
displacement.inputs["Scale"].default_value = 1.0
|
||||
group_input.location = (-1200.0, 100.0)
|
||||
group_output.location = (1050.0, 100.0)
|
||||
roughness_curve.location = (-300.0, 450.0)
|
||||
bump.location = (750.0, 50.0)
|
||||
displacement.location = (750.0, -300.0)
|
||||
background_attribute = nodes.new("ShaderNodeAttribute")
|
||||
background_attribute.attribute_type = "GEOMETRY"
|
||||
background_attribute.attribute_name = BACKGROUND_DEPTH_ATTRIBUTE
|
||||
background_attribute.location = (-950.0, -500.0)
|
||||
material_attribute = nodes.new("ShaderNodeAttribute")
|
||||
material_attribute.attribute_type = "GEOMETRY"
|
||||
material_attribute.attribute_name = MATERIAL_DISPLACEMENT_ATTRIBUTE
|
||||
material_attribute.location = (-50.0, -650.0)
|
||||
strength_attribute = nodes.new("ShaderNodeAttribute")
|
||||
strength_attribute.attribute_type = "GEOMETRY"
|
||||
strength_attribute.attribute_name = DEPTH_SCALE_ATTRIBUTE
|
||||
strength_attribute.location = (200.0, -650.0)
|
||||
foreground_mask = nodes.new("ShaderNodeMath")
|
||||
foreground_mask.operation = "GREATER_THAN"
|
||||
foreground_mask.inputs[1].default_value = 0.5
|
||||
foreground_mask.location = (-950.0, -250.0)
|
||||
clamp_foreground = nodes.new("ShaderNodeMath")
|
||||
clamp_foreground.operation = "MAXIMUM"
|
||||
clamp_foreground.location = (-650.0, -400.0)
|
||||
masked_depth = nodes.new("ShaderNodeMix")
|
||||
masked_depth.data_type = "FLOAT"
|
||||
masked_depth.location = (-350.0, -350.0)
|
||||
enabled_depth = nodes.new("ShaderNodeMath")
|
||||
enabled_depth.operation = "MULTIPLY"
|
||||
enabled_depth.location = (250.0, -350.0)
|
||||
scaled_depth = nodes.new("ShaderNodeMath")
|
||||
scaled_depth.operation = "MULTIPLY"
|
||||
scaled_depth.location = (450.0, -350.0)
|
||||
links.new(group_input.outputs["Alpha"], foreground_mask.inputs[0])
|
||||
links.new(group_input.outputs["Depth"], clamp_foreground.inputs[0])
|
||||
links.new(background_attribute.outputs["Fac"], clamp_foreground.inputs[1])
|
||||
links.new(foreground_mask.outputs[0], masked_depth.inputs[0])
|
||||
links.new(background_attribute.outputs["Fac"], masked_depth.inputs[2])
|
||||
links.new(clamp_foreground.outputs[0], masked_depth.inputs[3])
|
||||
links.new(masked_depth.outputs["Result"], enabled_depth.inputs[0])
|
||||
links.new(material_attribute.outputs["Fac"], enabled_depth.inputs[1])
|
||||
links.new(enabled_depth.outputs[0], scaled_depth.inputs[0])
|
||||
links.new(strength_attribute.outputs["Fac"], scaled_depth.inputs[1])
|
||||
processed_alpha = foreground_mask.outputs[0]
|
||||
processed_depth = scaled_depth.outputs[0]
|
||||
|
||||
links.new(group_input.outputs["Color"], group_output.inputs["Color"])
|
||||
links.new(group_input.outputs["Color"], roughness_curve.inputs["Value"])
|
||||
links.new(
|
||||
roughness_curve.outputs["Value"],
|
||||
group_output.inputs["Roughness"],
|
||||
)
|
||||
links.new(processed_alpha, group_output.inputs["Alpha"])
|
||||
links.new(bump_depth, bump.inputs["Height"])
|
||||
bump_distance = nodes.new("ShaderNodeMath")
|
||||
bump_distance.operation = "MULTIPLY"
|
||||
bump_distance.inputs[1].default_value = BUMP_BASE_DISTANCE
|
||||
bump_distance.location = (500.0, 100.0) if depth_plane else (-250.0, 150.0)
|
||||
links.new(group_input.outputs["Bump Scale"], bump_distance.inputs[0])
|
||||
links.new(bump_distance.outputs[0], bump.inputs["Distance"])
|
||||
links.new(bump.outputs["Normal"], group_output.inputs["Normal"])
|
||||
if displacement is not None:
|
||||
links.new(processed_depth, displacement.inputs["Height"])
|
||||
links.new(
|
||||
displacement.outputs["Displacement"],
|
||||
group_output.inputs["Displacement"],
|
||||
)
|
||||
group.color_tag = "SHADER"
|
||||
group.description = (
|
||||
"Prepare image depth material outputs."
|
||||
if depth_plane
|
||||
else f"Prepare {group_name} material outputs."
|
||||
)
|
||||
group.use_fake_user = True
|
||||
return group
|
||||
@@ -11,8 +11,12 @@ sys.path.insert(
|
||||
)
|
||||
|
||||
from anyimage.operators.common.mesh_result import (
|
||||
DEPTH_MATERIAL_NODE_GROUP_NAME,
|
||||
IMAGE_MATERIAL_NODE_GROUP_NAME,
|
||||
load_asset_node_group,
|
||||
node_asset_path,
|
||||
)
|
||||
from anyimage.operators.convert_to_plane.nodes import DEPTH_PLANE_NODE_GROUP_NAME
|
||||
from anyimage.operators.cutout_tool.shape import (
|
||||
CUTOUT_NODE_GROUP_NAME,
|
||||
CUTOUT_NODE_GROUP_NAMES,
|
||||
@@ -30,11 +34,25 @@ def input_names(group):
|
||||
def main():
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
mesh_plane = load_asset_node_group("O Mesh Plane")
|
||||
depth_plane = load_asset_node_group(DEPTH_PLANE_NODE_GROUP_NAME)
|
||||
image_layer = load_asset_node_group(IMAGE_MATERIAL_NODE_GROUP_NAME)
|
||||
depth_layer = load_asset_node_group(DEPTH_MATERIAL_NODE_GROUP_NAME)
|
||||
shadeless = load_asset_node_group("O Shadeless")
|
||||
cutout = load_asset_node_group(CUTOUT_NODE_GROUP_NAME)
|
||||
cutout_groups = {
|
||||
name: bpy.data.node_groups[name] for name in CUTOUT_NODE_GROUP_NAMES.values()
|
||||
}
|
||||
expected_names = {
|
||||
"O Mesh Plane",
|
||||
DEPTH_PLANE_NODE_GROUP_NAME,
|
||||
IMAGE_MATERIAL_NODE_GROUP_NAME,
|
||||
DEPTH_MATERIAL_NODE_GROUP_NAME,
|
||||
"O Shadeless",
|
||||
CUTOUT_NODE_GROUP_NAME,
|
||||
*CUTOUT_NODE_GROUP_NAMES.values(),
|
||||
}
|
||||
with bpy.data.libraries.load(str(node_asset_path()), link=False) as (source, _):
|
||||
assert set(source.node_groups) == expected_names
|
||||
|
||||
assert mesh_plane.name == "O Mesh Plane"
|
||||
assert mesh_plane.bl_idname == "GeometryNodeTree"
|
||||
@@ -45,6 +63,34 @@ def main():
|
||||
"Thickness",
|
||||
"Material",
|
||||
]
|
||||
assert depth_plane.bl_idname == "GeometryNodeTree"
|
||||
assert depth_plane.is_modifier
|
||||
assert input_names(depth_plane) == [
|
||||
"Geometry",
|
||||
"Subdivide",
|
||||
"Thickness",
|
||||
"Depth Amount",
|
||||
"Reference Depth",
|
||||
"Uniform Scale",
|
||||
"Depth Image",
|
||||
"Material",
|
||||
]
|
||||
assert image_layer.bl_idname == "ShaderNodeTree"
|
||||
assert input_names(image_layer) == [
|
||||
"Color",
|
||||
"Alpha",
|
||||
"Normal",
|
||||
"Normal Scale",
|
||||
"Object Space",
|
||||
"Bump Scale",
|
||||
]
|
||||
assert depth_layer.bl_idname == "ShaderNodeTree"
|
||||
assert input_names(depth_layer) == [
|
||||
"Color",
|
||||
"Alpha",
|
||||
"Depth",
|
||||
"Bump Scale",
|
||||
]
|
||||
assert shadeless.name == "O Shadeless"
|
||||
assert shadeless.bl_idname == "ShaderNodeTree"
|
||||
assert input_names(shadeless) == ["Color"]
|
||||
@@ -59,7 +105,14 @@ def main():
|
||||
assert not group.is_modifier
|
||||
assert input_names(group)[0] == "Geometry"
|
||||
|
||||
public_groups = {mesh_plane, shadeless, cutout}
|
||||
public_groups = {
|
||||
mesh_plane,
|
||||
depth_plane,
|
||||
image_layer,
|
||||
depth_layer,
|
||||
shadeless,
|
||||
cutout,
|
||||
}
|
||||
loaded = {*public_groups, *cutout_groups.values()}
|
||||
assert all(group.use_fake_user for group in public_groups)
|
||||
assert all(group.users > 0 for group in cutout_groups.values())
|
||||
|
||||
Reference in New Issue
Block a user