mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 19:01:02 +00:00
M8c: interference detection
check_interference(min_volume) reports every pair of solid bodies whose
intersection encloses more than min_volume, as {body_a, body_b, volume}. It
reports only — no geometry is mutated, so calling it cannot disturb mates or
placements. Read-only at the MCP surface too: no checkpoint, no recompute.
Sheet bodies are skipped up front: an intersection involving one encloses no
volume, so the boolean would be wasted work. Bodies that merely touch share a
face and enclose nothing, so face-to-face contact is not an interference.
A boolean that fails on one pair must not lose the report for every other pair,
so each pair is guarded — and OCCT raises Standard_Failure, which is not a
std::exception and would otherwise escape.
No new serialized fields, no recipe bump: this reads `bodies`, which is
recompute output and was never serialized.
No separate MCP listing for instances and mates: describe_scene already emits
the feature tree, and Mate has rendered there correctly since M8a fixed
feature_type_name.
Tests assert the exact overlap volume (20*20*4 = 1600 mm^3), both negative cases
(clearly apart, and exact face contact), that sheets are skipped, that the
min_volume gate silences a real overlap, and that a clash created by a Fastened
mate is detected — which ties the M8b placement work to this report.
Suite 139 cases / 1960 assertions green. McpControl.cpp is reviewed but not
compiled by kernel-test.sh, which builds only libslic3r_tests.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6a0031c9e5
commit
30d54f0074
@@ -3359,6 +3359,40 @@ int CadDocument::add_surface_fill(int sketch_ref, const std::string& name)
|
||||
return int(features.size()) - 1;
|
||||
}
|
||||
|
||||
std::vector<CadDocument::Interference> CadDocument::check_interference(double min_volume) const
|
||||
{
|
||||
std::vector<Interference> out;
|
||||
const int n = int(bodies.size());
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (bodies[i].shape.IsNull() || is_sheet_shape(bodies[i].shape)) continue;
|
||||
for (int j = i + 1; j < n; ++j) {
|
||||
if (bodies[j].shape.IsNull() || is_sheet_shape(bodies[j].shape)) continue;
|
||||
|
||||
double v = 0;
|
||||
// A boolean that blows up on one pair must not lose the report for the others,
|
||||
// and OCCT signals those as Standard_Failure, which is NOT a std::exception.
|
||||
try {
|
||||
BRepAlgoAPI_Common common(bodies[i].shape, bodies[j].shape);
|
||||
common.Build();
|
||||
if (!common.IsDone()) continue;
|
||||
const TopoDS_Shape s = common.Shape();
|
||||
if (s.IsNull()) continue;
|
||||
GProp_GProps props;
|
||||
BRepGProp::VolumeProperties(s, props);
|
||||
v = std::abs(props.Mass());
|
||||
} catch (const Standard_Failure&) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Bodies that merely touch share a face and enclose no volume, so the
|
||||
// threshold is what separates contact from interference.
|
||||
if (v > min_volume) out.push_back({i, j, v});
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// ponytail: derived from the OCCT shape type; no stored flag, bodies aren't serialized anyway.
|
||||
bool CadDocument::is_sheet_shape(const TopoDS_Shape& s)
|
||||
{
|
||||
|
||||
@@ -575,6 +575,13 @@ public:
|
||||
|
||||
GeometryEngine::MassProps body_mass_properties(int body_index) const;
|
||||
|
||||
// One overlapping pair of solid bodies. Indices are into `bodies`, a_ < b_.
|
||||
struct Interference { int body_a{-1}; int body_b{-1}; double volume{0}; };
|
||||
// Every pair of solid bodies whose intersection encloses more than min_volume (mm^3).
|
||||
// Reports only — mutates nothing, so mates and placements are unaffected by calling it.
|
||||
// Sheet bodies are skipped: an intersection involving one encloses no volume.
|
||||
std::vector<Interference> check_interference(double min_volume = 1e-6) const;
|
||||
|
||||
// ponytail: derived from the OCCT shape type; no stored flag, bodies aren't serialized anyway.
|
||||
static bool is_sheet_shape(const TopoDS_Shape& s); // true if TopExp finds no TopAbs_SOLID
|
||||
|
||||
|
||||
Reference in New Issue
Block a user