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:
2026-09-08 17:18:03 +08:00
parent 7dec3b7ca4
commit 196b964efc
71 changed files with 3440 additions and 1988 deletions

View File

@@ -31,10 +31,9 @@ from .geometry import (
)
from .shape import (
BALLOON_ATTRIBUTE_NAME,
BALLOON_CUTOUT_SHAPES,
NORMAL_SCALE_ATTRIBUTE_NAME,
CUTOUT_X_TO_Z,
CUTOUT_NODE_GROUP_NAME,
CUTOUT_SHAPE_INDICES,
CUTOUT_NODE_GROUP_NAMES,
DEPTH_CUTOUT_SHAPES,
)
@@ -131,11 +130,11 @@ def create_cropped_color_image(source_object, crop_bounds, source_rgba):
return image
def load_cutout_node_group():
return load_node_group(CUTOUT_NODE_GROUP_NAME)
def load_cutout_node_group(shape):
return load_node_group(CUTOUT_NODE_GROUP_NAMES[shape], asset_revision=11)
def _connect_balloon_normal_scale(material):
def _connect_cutout_normal_scale(material):
nodes = material.node_tree.nodes
image_layer = next(
node
@@ -146,7 +145,7 @@ def _connect_balloon_normal_scale(material):
)
attribute = nodes.new("ShaderNodeAttribute")
attribute.attribute_type = "GEOMETRY"
attribute.attribute_name = BALLOON_ATTRIBUTE_NAME
attribute.attribute_name = NORMAL_SCALE_ATTRIBUTE_NAME
attribute.location = (-550.0, -250.0)
material.node_tree.links.new(
attribute.outputs["Fac"], image_layer.inputs["Normal Scale"]
@@ -206,8 +205,7 @@ def create_shape_object(
scene=context.scene,
)
depth_reference = None
if shape in BALLOON_CUTOUT_SHAPES:
_connect_balloon_normal_scale(material)
_connect_cutout_normal_scale(material)
uniform_scale = None
depth_direction = None
if shape in DEPTH_CUTOUT_SHAPES:
@@ -227,7 +225,7 @@ def create_shape_object(
depth_reference = DEFAULT_DEPTH_BASELINE
if shape == "DEPTH_BALLOON":
depth_direction = DEFAULT_DEPTH_DIRECTION
elif shape == "DEPTH_SURFACE":
elif shape == "DEPTH_SOLID":
depth_reference = metric_depth_reference(
camera_depth,
calibration_valid,
@@ -268,22 +266,19 @@ def create_shape_object(
inward_axis,
)
mesh_object["anyimage_mesh_shape"] = shape
node_group = load_cutout_node_group()
node_group = load_cutout_node_group(shape)
modifier = mesh_object.modifiers.new(name=node_group.name, type="NODES")
modifier.node_group = node_group
modifier.show_group_selector = False
for name, value in (
("Shape", CUTOUT_SHAPE_INDICES[shape]),
(
"Inward Axis",
0 if inward_axis == CutoutInwardAxis.NEGATIVE_Z else 1,
),
("Cleanup", cleanup_value),
("Smooth Iterations", 0),
("Smooth", 1.0),
("Cleanup Threshold", cleanup_value),
(
"Thickness",
1.0 if shape in {"BALLOON", "DEPTH_BALLOON"} else 0.0,
0.0 if shape == "FLAT" else 1.0,
),
):
set_modifier_input(