Refactor depth surface and image cutout nodes for improved functionality and clarity
- Removed deprecated tests and code related to shell wall connections and coincident sheets. - Updated attribute handling in depth surface and image cutout groups, including new vector attribute functions. - Enhanced the inflation logic in the image depth cutout group to better manage shell and balloon behaviors. - Improved parameter naming and descriptions for clarity in the user interface. - Streamlined the geometry processing logic to ensure better performance and maintainability.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
"""Face separation and connected thickness for Depth Surface assets."""
|
||||
|
||||
from .nodes import (
|
||||
boolean_node, compare_node, evaluate_field, store_float_attribute,
|
||||
store_boolean_attribute, remove_attribute_pattern, sample_field,
|
||||
boolean_node, compare_node, evaluate_field, store_boolean_attribute,
|
||||
remove_attribute_pattern, sample_field,
|
||||
)
|
||||
from .smoothing import edge_boundary_field
|
||||
|
||||
@@ -318,8 +318,7 @@ def build_surface_camera(group, original, separated, cut_vertex, strength):
|
||||
return evaluate_field(group, choose.outputs["Output"], "FLOAT_VECTOR", "POINT")
|
||||
|
||||
|
||||
def thicken_depth_surface(group, geometry, thickness, normal_smooth=None, *,
|
||||
back_mask=None, weld_zero_thickness=False):
|
||||
def thicken_depth_surface(group, geometry, thickness, normal_smooth=None):
|
||||
"""Connect caps with single quads by source vertex and cap identity."""
|
||||
nodes, links = group.nodes, group.links
|
||||
position = nodes.new("GeometryNodeInputPosition")
|
||||
@@ -378,29 +377,12 @@ def thicken_depth_surface(group, geometry, thickness, normal_smooth=None, *,
|
||||
links.new(rear, back_parts.inputs["Geometry"])
|
||||
links.new(rim, back_parts.inputs["Geometry"])
|
||||
rear = back_parts.outputs["Geometry"]
|
||||
if back_mask is not None:
|
||||
rear = store_float_attribute(group, rear, back_mask, 1.0)
|
||||
for value in (
|
||||
saved,
|
||||
rear,
|
||||
):
|
||||
links.new(value, join.inputs["Geometry"])
|
||||
construction = join.outputs["Geometry"]
|
||||
if weld_zero_thickness:
|
||||
positive = compare_node(group, "GREATER_THAN", source_thickness, 1e-12)
|
||||
flattened = nodes.new("ShaderNodeCombineXYZ")
|
||||
for axis in ("X", "Z"):
|
||||
links.new(layer_axes.outputs[axis], flattened.inputs[axis])
|
||||
collapsed = nodes.new("GeometryNodeSwitch")
|
||||
collapsed.input_type = "FLOAT"
|
||||
collapsed.inputs["False"].default_value = 0.0
|
||||
links.new(positive, collapsed.inputs["Switch"])
|
||||
links.new(layer_axes.outputs["Y"], collapsed.inputs["True"])
|
||||
links.new(collapsed.outputs[0], flattened.inputs["Y"])
|
||||
collapse = nodes.new("GeometryNodeSetPosition")
|
||||
links.new(construction, collapse.inputs["Geometry"])
|
||||
links.new(flattened.outputs[0], collapse.inputs["Position"])
|
||||
construction = collapse.outputs["Geometry"]
|
||||
merge = nodes.new("GeometryNodeMergeByDistance")
|
||||
merge.mode = "ALL"
|
||||
merge.inputs["Distance"].default_value = 0.1
|
||||
|
||||
@@ -138,6 +138,13 @@ def read_float_attribute(group, name):
|
||||
return node.outputs["Attribute"]
|
||||
|
||||
|
||||
def read_vector_attribute(group, name):
|
||||
node = group.nodes.new("GeometryNodeInputNamedAttribute")
|
||||
node.data_type = "FLOAT_VECTOR"
|
||||
node.inputs["Name"].default_value = name
|
||||
return node.outputs["Attribute"]
|
||||
|
||||
|
||||
def store_float_attribute(group, geometry, name, value, domain="POINT"):
|
||||
node = group.nodes.new("GeometryNodeStoreNamedAttribute")
|
||||
node.domain, node.data_type = domain, "FLOAT"
|
||||
@@ -150,6 +157,15 @@ def store_float_attribute(group, geometry, name, value, domain="POINT"):
|
||||
return node.outputs["Geometry"]
|
||||
|
||||
|
||||
def store_vector_attribute(group, geometry, name, value, domain="POINT"):
|
||||
node = group.nodes.new("GeometryNodeStoreNamedAttribute")
|
||||
node.domain, node.data_type = domain, "FLOAT_VECTOR"
|
||||
node.inputs["Name"].default_value = name
|
||||
group.links.new(geometry, node.inputs["Geometry"])
|
||||
group.links.new(value, node.inputs["Value"])
|
||||
return node.outputs["Geometry"]
|
||||
|
||||
|
||||
def evaluate_field(group, value, data_type, domain):
|
||||
"""Evaluate a field on an explicit domain before downstream adaptation."""
|
||||
node = group.nodes.new("GeometryNodeFieldOnDomain")
|
||||
@@ -184,26 +200,12 @@ def store_boolean_attribute(group, geometry, name, value, domain="POINT"):
|
||||
return node.outputs["Geometry"], read.outputs["Attribute"]
|
||||
|
||||
|
||||
def remove_attributes(group, geometry, *names, enabled=None):
|
||||
"""Remove only the explicitly owned temporary attributes."""
|
||||
original = geometry
|
||||
for name in names:
|
||||
node = group.nodes.new("GeometryNodeRemoveAttribute")
|
||||
node.inputs["Name"].default_value = name
|
||||
group.links.new(geometry, node.inputs["Geometry"])
|
||||
geometry = node.outputs["Geometry"]
|
||||
if enabled is not None:
|
||||
choose = group.nodes.new("GeometryNodeSwitch")
|
||||
choose.input_type = "GEOMETRY"
|
||||
group.links.new(enabled, choose.inputs["Switch"])
|
||||
group.links.new(original, choose.inputs["False"])
|
||||
group.links.new(geometry, choose.inputs["True"])
|
||||
geometry = choose.outputs["Output"]
|
||||
return geometry
|
||||
|
||||
|
||||
def remove_attribute_pattern(group, geometry, pattern):
|
||||
"""Remove every attribute matching an internal wildcard pattern."""
|
||||
"""Remove every attribute matching an internal wildcard pattern.
|
||||
|
||||
Always clean internal attributes with a pattern: naming an attribute that a
|
||||
branch never stored makes the Remove Named Attribute node warn.
|
||||
"""
|
||||
node = group.nodes.new("GeometryNodeRemoveAttribute")
|
||||
node.inputs["Name"].default_value = pattern
|
||||
node.pattern_mode = "WILDCARD"
|
||||
|
||||
Reference in New Issue
Block a user