MCP slice 5: body-targeted fillet/chamfer, ordered slice contours, surface-deviation validate, widen Build

- fillet/chamfer accept optional `body` (sets target_body; edge id resolved against THAT body)
- slice_body chains section segments into ordered contours, each flagged closed/open
- validate_against adds surface_deviation (one-sided Hausdorff via BRepExtrema_DistShapeShape)
- new actions pattern/shell/draft; extrude gains end=blind|symmetric|two_sided|through_all|up_to_face + taper/flip/distance2
- GeometryEngine::surface_deviation helper (byte-identical to snaporca; Catch2 [Deviation] test lives in snaporca, whose test_geometry.cpp carries the CAD suite)

Product code byte-identical to snaporca (md5 match). Both forks build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVzKmX6Y1aEteit1HTXG4Q
This commit is contained in:
Tommaso Bianchi
2026-06-30 17:52:08 +02:00
co-authored by Claude Opus 4.8
parent d2f97a752b
commit 94cde2af21
3 changed files with 209 additions and 19 deletions
+28
View File
@@ -28,6 +28,9 @@
#include <STEPControl_Reader.hxx>
#include <IFSelect_ReturnStatus.hxx>
#include <Standard_Failure.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <cmath>
namespace Slic3r {
@@ -275,6 +278,31 @@ TriangleMesh GeometryEngine::tessellate(const TopoDS_Shape& shape,
TriangleMesh result; result.from_stl(stl); return result;
}
GeometryEngine::Deviation
GeometryEngine::surface_deviation(const TopoDS_Shape& candidate,
const TopoDS_Shape& reference,
double linear_deflection)
{
Deviation d;
if (candidate.IsNull() || reference.IsNull()) return d;
TriangleMesh mesh = tessellate(candidate, linear_deflection, 0.5);
const auto& verts = mesh.its.vertices;
if (verts.empty()) return d;
double sum = 0.0, sumsq = 0.0;
int n = 0;
for (const auto& v : verts) {
gp_Pnt p(v.x(), v.y(), v.z());
BRepExtrema_DistShapeShape dss(BRepBuilderAPI_MakeVertex(p).Vertex(), reference);
if (!dss.IsDone() || dss.NbSolution() < 1) continue;
double dist = dss.Value();
d.max_mm = std::max(d.max_mm, dist);
sum += dist; sumsq += dist * dist; ++n;
}
d.sample_count = n;
if (n > 0) { d.mean_mm = sum / n; d.rms_mm = std::sqrt(sumsq / n); }
return d;
}
std::string GeometryEngine::primitive_name(PrimitiveType type)
{
switch (type) {