Add cutout shell and volume node assets for depth volume processing
- Implemented `cutout_shell.py` to build front normals and shell positions for balloon geometry. - Created `cutout_volume.py` to establish smooth center fields and manage balloon surface attributes. - Introduced `pisa_sr_export.py` for exporting PiSA-SR components with dependencies and asset finalization.
This commit is contained in:
@@ -8,7 +8,6 @@ TEMPORARY_ATTRIBUTES = {
|
||||
"camera": ("FLOAT_VECTOR", "POINT"),
|
||||
"surface_position": ("FLOAT_VECTOR", "POINT"),
|
||||
"source_vertex": ("INT", "POINT"),
|
||||
"wall_layers": ("FLOAT", "POINT"),
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +49,7 @@ def _math(group, operation, a, b=None):
|
||||
return node.outputs[0]
|
||||
|
||||
|
||||
def split_depth_surface(group, geometry, image, strength, uniform, depth_scale):
|
||||
def split_depth_surface(group, geometry, image, strength, uniform):
|
||||
"""Keep each face's camera sample on its own corners before splitting."""
|
||||
nodes, links = group.nodes, group.links
|
||||
uv = nodes.new("GeometryNodeInputNamedAttribute")
|
||||
@@ -93,7 +92,6 @@ def split_depth_surface(group, geometry, image, strength, uniform, depth_scale):
|
||||
links.new(center, distance.inputs[index])
|
||||
delta = _math(group, "ABSOLUTE", _math(group, "SUBTRACT", *depths))
|
||||
scaled = _math(group, "MULTIPLY", delta, uniform)
|
||||
scaled = _math(group, "MULTIPLY", scaled, _math(group, "ABSOLUTE", depth_scale))
|
||||
# Cross multiplication avoids division and stays invariant under uniform scaling.
|
||||
selected = _math(
|
||||
group,
|
||||
@@ -171,7 +169,7 @@ def store_surface_camera(group, geometry, original, strength):
|
||||
|
||||
|
||||
def thicken_depth_surface(group, geometry, thickness):
|
||||
"""Connect caps and wall rings by source vertex and layer identity."""
|
||||
"""Connect caps with single quads by source vertex and cap identity."""
|
||||
nodes, links = group.nodes, group.links
|
||||
position = nodes.new("GeometryNodeInputPosition")
|
||||
geometry = _store(group, geometry, "surface_position", position.outputs[0])
|
||||
@@ -186,33 +184,7 @@ def thicken_depth_surface(group, geometry, thickness):
|
||||
geometry = _store(
|
||||
group, sheet.outputs["Geometry"], "source_vertex", index.outputs[0]
|
||||
)
|
||||
edge = nodes.new("GeometryNodeInputMeshEdgeVertices")
|
||||
length = nodes.new("ShaderNodeVectorMath")
|
||||
length.operation = "DISTANCE"
|
||||
links.new(edge.outputs["Position 1"], length.inputs[0])
|
||||
links.new(edge.outputs["Position 2"], length.inputs[1])
|
||||
neighbors = nodes.new("GeometryNodeInputMeshEdgeNeighbors")
|
||||
statistics = nodes.new("GeometryNodeAttributeStatistic")
|
||||
statistics.domain = "EDGE"
|
||||
statistics.data_type = "FLOAT"
|
||||
links.new(geometry, statistics.inputs["Geometry"])
|
||||
links.new(
|
||||
_math(group, "COMPARE", neighbors.outputs["Face Count"], 1.0),
|
||||
statistics.inputs["Selection"],
|
||||
)
|
||||
links.new(length.outputs["Value"], statistics.inputs["Attribute"])
|
||||
count = _math(
|
||||
group,
|
||||
"CEIL",
|
||||
_math(
|
||||
group,
|
||||
"DIVIDE",
|
||||
thickness,
|
||||
_math(group, "MAXIMUM", statistics.outputs["Median"], 1e-6),
|
||||
),
|
||||
)
|
||||
count = _math(group, "MINIMUM", _math(group, "MAXIMUM", count, 1.0), 128.0)
|
||||
saved = _store(group, geometry, "wall_layers", count)
|
||||
saved = geometry
|
||||
|
||||
# Weld in an integer identity grid, never in scene coordinates. Nearby cuts
|
||||
# retain distinct IDs; copies of one rim vertex share the same ID and layer.
|
||||
@@ -224,41 +196,26 @@ def thicken_depth_surface(group, geometry, thickness):
|
||||
links.new(_read(group, "source_vertex"), part.inputs[0])
|
||||
links.new(part.outputs[0], identity.inputs[axis])
|
||||
|
||||
repeat_output = nodes.new("GeometryNodeRepeatOutput")
|
||||
repeat_input = nodes.new("GeometryNodeRepeatInput")
|
||||
repeat_input.pair_with_output(repeat_output)
|
||||
repeat_output.repeat_items.clear()
|
||||
repeat_output.repeat_items.new("GEOMETRY", "Geometry")
|
||||
repeat_output.repeat_items.new("GEOMETRY", "Sides")
|
||||
links.new(count, repeat_input.inputs["Iterations"])
|
||||
links.new(saved, repeat_input.inputs["Geometry"])
|
||||
extrude = nodes.new("GeometryNodeExtrudeMesh")
|
||||
extrude.mode = "FACES"
|
||||
extrude.inputs["Individual"].default_value = False
|
||||
extrusion_offset = nodes.new("ShaderNodeCombineXYZ")
|
||||
extrusion_offset.inputs["Z"].default_value = -1.0
|
||||
links.new(extrusion_offset.outputs[0], extrude.inputs["Offset"])
|
||||
links.new(repeat_input.outputs["Geometry"], extrude.inputs["Mesh"])
|
||||
links.new(saved, extrude.inputs["Mesh"])
|
||||
sides = nodes.new("GeometryNodeSeparateGeometry")
|
||||
sides.domain = "FACE"
|
||||
links.new(extrude.outputs["Mesh"], sides.inputs["Geometry"])
|
||||
links.new(extrude.outputs["Side"], sides.inputs["Selection"])
|
||||
join_sides = nodes.new("GeometryNodeJoinGeometry")
|
||||
links.new(repeat_input.outputs["Sides"], join_sides.inputs["Geometry"])
|
||||
links.new(sides.outputs["Selection"], join_sides.inputs["Geometry"])
|
||||
links.new(sides.outputs["Inverted"], repeat_output.inputs["Geometry"])
|
||||
links.new(join_sides.outputs["Geometry"], repeat_output.inputs["Sides"])
|
||||
offset = nodes.new("ShaderNodeCombineXYZ")
|
||||
links.new(
|
||||
_math(group, "MULTIPLY", _read(group, "wall_layers"), -1.0), offset.inputs["Z"]
|
||||
)
|
||||
offset.inputs["Z"].default_value = -1.0
|
||||
back = nodes.new("GeometryNodeSetPosition")
|
||||
links.new(saved, back.inputs["Geometry"])
|
||||
links.new(offset.outputs[0], back.inputs["Offset"])
|
||||
flip_back = nodes.new("GeometryNodeFlipFaces")
|
||||
links.new(back.outputs["Geometry"], flip_back.inputs["Mesh"])
|
||||
flip_sides = nodes.new("GeometryNodeFlipFaces")
|
||||
links.new(repeat_output.outputs["Sides"], flip_sides.inputs["Mesh"])
|
||||
links.new(sides.outputs["Selection"], flip_sides.inputs["Mesh"])
|
||||
join = nodes.new("GeometryNodeJoinGeometry")
|
||||
for value in (
|
||||
saved,
|
||||
@@ -274,12 +231,11 @@ def thicken_depth_surface(group, geometry, thickness):
|
||||
merge.inputs["Distance"].default_value = 0.1
|
||||
links.new(encoded.outputs["Geometry"], merge.inputs["Geometry"])
|
||||
displacement = nodes.new("ShaderNodeCombineXYZ")
|
||||
step = _math(group, "DIVIDE", thickness, _read(group, "wall_layers"))
|
||||
layer_position = nodes.new("GeometryNodeInputPosition")
|
||||
layer_axes = nodes.new("ShaderNodeSeparateXYZ")
|
||||
links.new(layer_position.outputs[0], layer_axes.inputs[0])
|
||||
links.new(
|
||||
_math(group, "MULTIPLY", layer_axes.outputs["Z"], step),
|
||||
_math(group, "MULTIPLY", layer_axes.outputs["Z"], thickness),
|
||||
displacement.inputs["Z"],
|
||||
)
|
||||
restored = nodes.new("ShaderNodeVectorMath")
|
||||
|
||||
Reference in New Issue
Block a user