Boundary surface preparation (weld, manifold/orientation, exact self-intersection, feature edges) and mesh.surface.check (#15)

* mesh: boundary surface preparation (weld, manifold and orientation checks, exact self-intersection, feature edges)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* engine: mesh.surface.check on an open design's body or an imported surface

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* engine: struct-init the test session

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* surface: weld at an absolute distance too; the engine welds CAD tessellations at twice SolidCraft's linear tolerance

Faces of a SolidCraft tessellation carry their own copies of shared boundary points, which agree
only to within the kernel's tolerance (up to ~2e-6 mm on the test corpus).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* docs: surface preparation in the literature survey, architecture and roadmap

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* surface: simplify after review

- The weld distance travels with the mesh (SurfaceMesh::weld_distance, set by Shape::tessellate),
  so every consumer welds a tessellation correctly without opting in.
- Exact tests are infallible on predicates::orient2d_projected (shared with generic_orient2d), and
  compute each vertex's plane side once per pair with an early reject.
- One Box3 for the weld, the BVH and shells; a Half struct for edges; the weld's two lookups share
  one loop, with chained grid cells; cached normals for feature edges; shared parameter helpers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

* corpus: boundary surface preparation as a corpus stage

20 of 21 parts are valid boundaries with their expected genus; cross-cylinders' tessellation has
cracks and flipped triangles where its two intersection curves meet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm

---------

Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-10-13 16:01:42 -04:00
1 parent 94dc50bb0c
commit 02cc9dab57
24 files changed
+1987 -60

No files matched your search

+13
View File
@@ -184,6 +184,10 @@ mod tests {
json!({"points": [[1e308, -1e308, 0], [0, 0, 0]]}),
json!({"points": [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]}),
json!({"points": vec![[1, 1, 1]; 30_000]}),
json!({"surface": 0}),
json!({"surface": -1}),
json!({"surface": 1e300}),
json!({"surface": "0", "weld": -1, "feature_angle": 1e300}),
];
for spec in commands() {
for p in &hostile {
@@ -204,6 +208,15 @@ mod tests {
json!({"body": "Body1", "tolerance": 1e-300}),
json!({"body": "Body1", "tolerance": 1e300}),
json!({"body": "Body2", "tolerance": 0.1}),
json!({"body": "Body1", "tolerance": 0.5, "surface": 0}),
json!({"body": "Body1", "tolerance": 0.5, "weld": 0}),
json!({"body": "Body1", "tolerance": 0.5, "weld": 1e-3}),
json!({"body": "Body1", "tolerance": 0.5, "weld": f64::MIN_POSITIVE}),
json!({"body": "Body1", "tolerance": 0.5, "weld": 0, "weld_distance": 0}),
json!({"body": "Body1", "tolerance": 0.5, "weld_distance": 1e300}),
json!({"body": "Body1", "tolerance": 0.5, "weld_distance": 0.05}),
json!({"body": "Body1", "tolerance": 0.5, "feature_angle": 1e-300}),
json!({"body": "Body1", "tolerance": 0.5, "feature_angle": null}),
];
for p in tess.iter().chain(&hostile) {
for spec in commands() {