mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-25 18:00:57 +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
@@ -339,6 +339,10 @@ json describe_tools()
|
||||
json{{"name", "angle"}, {"type", "number"}, {"unit", "deg"}, {"default", 0}},
|
||||
json{{"name", "flip"}, {"type", "boolean"}, {"default", false}},
|
||||
})}},
|
||||
json{{"name", "check_interference"}, {"summary", "Solid bodies that overlap, as {body_a, body_b, volume}. Read-only; bodies that merely touch enclose no volume and are not reported."},
|
||||
{"params", json::array({
|
||||
json{{"name", "min_volume"}, {"type", "number"}, {"unit", "mm^3"}, {"default", 1e-6}, {"description", "overlap volume above which a pair counts as interfering"}},
|
||||
})}},
|
||||
json{{"name", "query_topology"}, {"summary", "Measured faces (centroid/normal/cylinder) and edges (length/circle) of a body."},
|
||||
{"params", json::array({
|
||||
json{{"name", "body"}, {"type", "integer"}, {"default", 0}},
|
||||
@@ -1344,6 +1348,19 @@ json action_mate(DesignPanel* panel, const json& params)
|
||||
return json{{"ok", ok}, {"mate_index", idx}, {"bodies", int(doc.bodies.size())}, {"error", doc.error}};
|
||||
}
|
||||
|
||||
json action_check_interference(DesignPanel* panel, const json& params)
|
||||
{
|
||||
const double min_volume = params.value("min_volume", 1e-6);
|
||||
CadDocument& doc = panel->mcp_doc();
|
||||
// Read-only: no checkpoint(), no recompute(), no mcp_after_change().
|
||||
const auto hits = doc.check_interference(min_volume);
|
||||
json arr = json::array();
|
||||
for (const auto& h : hits) {
|
||||
arr.push_back(json{{"body_a", h.body_a}, {"body_b", h.body_b}, {"volume", h.volume}});
|
||||
}
|
||||
return json{{"ok", true}, {"count", int(hits.size())}, {"interferences", arr}};
|
||||
}
|
||||
|
||||
json action_set_variable(DesignPanel* panel, const json& params)
|
||||
{
|
||||
if (!params.contains("name")) throw std::runtime_error("set_variable needs 'name'");
|
||||
@@ -1429,6 +1446,7 @@ std::string handle_on_main(const std::string& method, const json& params, const
|
||||
if (method == "surface_loft") return rpc_result(id, action_surface_loft(panel, params));
|
||||
if (method == "surface_fill") return rpc_result(id, action_surface_fill(panel, params));
|
||||
if (method == "mate") return rpc_result(id, action_mate(panel, params));
|
||||
if (method == "check_interference") return rpc_result(id, action_check_interference(panel, params));
|
||||
return rpc_error(id, -32601, "Unknown method: " + method);
|
||||
} catch (const Standard_Failure& ex) { // OCCT errors are NOT std::exception
|
||||
return rpc_error(id, -32000, std::string("OCCT: ") + (ex.GetMessageString() ? ex.GetMessageString() : "failure"));
|
||||
|
||||
Reference in New Issue
Block a user