Constrained Delaunay tetrahedralization (boundary recovery) and mesh.tet.generate (M2) (#29)

* predicates: LNC points, generic insphere and its perturbed form (Diazzi et al. 2023 §4.3)

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

* mesh: constrained Delaunay tetrahedralization (segment recovery with LNC Steiner points, gift-wrapping facet recovery, labelling)

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

* cdt: rounding repair, mesh.tet.generate, corpus CDT column; review cleanups (shared perturbation rule, one facet scan, cached coordinates, worklist segment recovery)

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

* mesh.tet.generate is ready in the catalogue; corpus table with the CDT column

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 18:37:09 -04:00
1 parent e688f6f934
commit aa68bbbcdf
24 files changed
+2876 -56

No files matched your search

+4 -4
View File
@@ -404,11 +404,11 @@ mod tests {
assert_eq!(r["result"]["tab"], "mesh", "{r}");
let entries = r["result"]["entries"].as_array().unwrap();
assert_eq!(entries.len(), modelcraft_engine::catalogue::CATALOGUE.len());
let tet = entries.iter().find(|e| e["id"] == "mesh.tet.generate").unwrap();
assert_eq!((tet["coming_soon"].as_str(), tet["command"].is_null()), (Some("M2"), true));
let soon = entries.iter().find(|e| e["id"] == "mesh.order.quadratic").unwrap();
assert_eq!((soon["coming_soon"].as_str(), soon["command"].is_null()), (Some("M2"), true));
assert_eq!(call(&mut app, "ui.set", json!({"tab": "nope"}))["ok"], false);
let r = call(&mut app, "ui.start", json!({"command": "mesh.tet.generate"}));
assert_eq!((r["ok"].as_bool(), r["error"].as_str()), (Some(false), Some("Tet Mesh is coming soon (M2)")));
let r = call(&mut app, "ui.start", json!({"command": "mesh.order.quadratic"}));
assert_eq!((r["ok"].as_bool(), r["error"].as_str()), (Some(false), Some("Quadratic is coming soon (M2)")));
}
#[test]
+2 -2
View File
@@ -520,8 +520,8 @@ mod tests {
assert_eq!(app.dialog.as_ref().map(|d| d.command), Some("model.material.create"));
app.dialog = None;
let journal = app.session.journal.len();
let err = app.start("mesh.tet.generate").unwrap_err();
assert_eq!(err, "Tet Mesh is coming soon (M2)");
let err = app.start("mesh.order.quadratic").unwrap_err();
assert_eq!(err, "Quadratic is coming soon (M2)");
assert!(app.dialog.is_none());
assert_eq!(app.session.journal.len(), journal);
assert_eq!(app.status.as_ref().map(|s| s.error), Some(false));