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

@@ -228,6 +228,27 @@ def test_cdt_preserves_constraint_split_by_an_interior_vertex():
assert not g.boundary_vertices_from_faces(len(points), faces)[constraints].any()
@pytest.mark.parametrize("offset", [0, 4096, 16384])
def test_cdt_collinear_outline_samples_do_not_become_sliver_faces(offset):
contour = np.asarray(((0., 0.), (240., 0.), (240., 160.), (0., 160.)))
contour = contour @ np.asarray(((.763, -.646), (.646, .763)))
contour += np.asarray((420.123456, 540.234567)) + offset
contours, spine, edges = fine.subdivide_constraints(
[contour], np.empty((0, 2)), [], 16
)
free = g.uniform_interior_points_for_contours(contours, 16)
points, faces, _ = fine.triangulate(contours, spine, edges, free, 16)
triangles = points[faces]
area = abs(np.cross(triangles[:, 1] - triangles[:, 0], triangles[:, 2] - triangles[:, 0]))
longest_squared = np.max(np.sum((triangles - np.roll(triangles, 1, axis=1))**2, axis=2), axis=1)
assert np.min(area / longest_squared) > 1e-4
assert area.sum() / 2 == pytest.approx(abs(g.contour_area(contour)), rel=1e-9)
boundary = g.boundary_vertices_from_faces(len(points), faces)
np.testing.assert_allclose(fine.ContourDomain([contour]).clearance(points[boundary]), 0, atol=1e-9)
# Every subdivided outline point survives; removing slivers must not skip it.
assert cKDTree(points[boundary]).query(contours[0])[0].max() < 1e-9
def test_contour_validation_accepts_pixel_contacts_and_rejects_crossings():
crossing = np.asarray(((0, 0), (4, 4), (0, 4), (4, 0)))
assert not fine.valid_contours([crossing])