Refactor geometry generation to standardize Blender object coordinates

- Unified the canonical local frame for generated geometries (Plane, Depth Plane, Relief Plane, Cutout, Depth Cutout) to align with Blender's object coordinate system, setting X as horizontal, Z as up, and +Y as depth.
- Removed the `Depth Axis` parameter from `O Image Cutout` and `O Image Depth Cutout`, simplifying the geometry generation process.
- Updated the depth direction defaults to use +Y instead of -Z for `O Image Relief Plane` and Depth Symmetry.
- Adjusted the geometry nodes to ensure thickness, projection, and shell displacements operate along the Y-axis.
- Implemented new capabilities for handling object space normals to align with the new canonical frame.
- Enhanced the Depth Symmetry functionality to mirror across the canonical Y-axis and perform a final rotation to maintain the correct orientation.
- Added tests to validate the new coordinate system and ensure compatibility with existing assets.
This commit is contained in:
2026-09-15 13:33:37 +08:00
parent 591e62085a
commit 4035f5c9e4
47 changed files with 892 additions and 570 deletions

View File

@@ -7,6 +7,7 @@ import bpy
from ...common.depth import camera_depth_values, depth_uniform_scale
from ...common.material import create_image_material
from ...common.object import (
blender_frame_rotation,
finalize_object_result,
modifier_input_identifier,
set_modifier_input,
@@ -43,7 +44,11 @@ def _cutout_world_matrix(source_matrix, crop_center):
from mathutils import Matrix
center_x, center_y = (float(value) for value in crop_center)
return source_matrix @ Matrix.Translation((center_x, center_y, 0.0))
return (
source_matrix
@ Matrix.Translation((center_x, center_y, 0.0))
@ blender_frame_rotation().inverted()
)
def _assign_uv(mesh, uv):
@@ -89,6 +94,7 @@ def create_shape_object(
gesture="LASSO",
):
import numpy as np
from mathutils import Matrix
normal_mode = NormalMode.OBJECT if shape in DEPTH_CUTOUT_SHAPES else NormalMode(normal_mode)
bounds = crop_plane_bounds(
@@ -179,6 +185,11 @@ def create_shape_object(
source_object.matrix_world,
crop_center,
)
if shape == "DEPTH_SYMMETRY":
mesh_object.matrix_world = (
mesh_object.matrix_world
@ Matrix.Rotation(-1.5707963267948966, 4, "Z")
)
mesh_object["anyimage_mesh_shape"] = shape
node_group = load_cutout_node_group("DEPTH_SOLID" if shape == "DEPTH_SYMMETRY" else shape)
modifier = mesh_object.modifiers.new(name=node_group.name, type="NODES")