mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 19:01:02 +00:00
CAD: split a body by a picked face; add the missing both-halves cut test
Split-by-face reuses the existing Cut feature rather than adding a new type: two appended fields (cut_face_body, cut_face) let apply_cut derive the cut plane from a picked face via SketchPlane::from_face when cut_face >= 0, otherwise it keeps using the base `plane`. cut_offset / cut_flip still apply along the derived normal, so the same square-wire split machinery handles both cases. add_split_by_face() is the convenience entry point; MCP gains a `split` method (body / face_body / face / keep_upper / keep_lower). Serialization stays append-only — cut_face_body, cut_face appended to save/load, recipe version unchanged at 2. Tests: the previously-missing both-halves plane cut (keep_upper && keep_lower => two bodies whose volumes sum to the original), split-by-face via a top-face plane offset into the interior, keep-upper-only, and a round-trip. Golden fixture regenerated with a GoldenSplit cut-by-face feature and exact field-value assertions. Suite 63 -> 67 cases, 1119 -> 1178 assertions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVzKmX6Y1aEteit1HTXG4Q
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9da5851534
commit
07b39d45cb
@@ -724,6 +724,21 @@ int CadDocument::add_cut(const SketchPlane& plane, double offset, bool flip,
|
||||
return int(features.size()) - 1;
|
||||
}
|
||||
|
||||
int CadDocument::add_split_by_face(int target_body, int face_body, int face,
|
||||
bool keep_upper, bool keep_lower, const std::string& name)
|
||||
{
|
||||
CadFeature f;
|
||||
f.type = CadFeatureType::Cut;
|
||||
f.name = name;
|
||||
f.target_body = target_body;
|
||||
f.cut_face_body = face_body;
|
||||
f.cut_face = face;
|
||||
f.cut_keep_upper = keep_upper;
|
||||
f.cut_keep_lower = keep_lower;
|
||||
features.push_back(f);
|
||||
return int(features.size()) - 1;
|
||||
}
|
||||
|
||||
int CadDocument::add_mirror(const SketchPlane& plane, int target_body, BooleanMode mode,
|
||||
const std::string& name)
|
||||
{
|
||||
@@ -1905,7 +1920,16 @@ void CadDocument::apply_cut(std::vector<CadBody>& bodies, const CadFeature& f) c
|
||||
if (!f.cut_keep_upper && !f.cut_keep_lower)
|
||||
throw std::runtime_error("cut keeps nothing");
|
||||
|
||||
SketchPlane cp = f.plane;
|
||||
SketchPlane cp;
|
||||
if (f.cut_face >= 0) {
|
||||
const int fb = (f.cut_face_body >= 0 && f.cut_face_body < nb) ? f.cut_face_body : tgt;
|
||||
if (bodies[fb].shape.IsNull()) throw std::runtime_error("cut: face body is empty");
|
||||
TopoDS_Face fc = GeometryEngine::face_by_index(bodies[fb].shape, f.cut_face);
|
||||
if (fc.IsNull()) throw std::runtime_error("cut: face not found");
|
||||
cp = SketchPlane::from_face(fc);
|
||||
} else {
|
||||
cp = f.plane;
|
||||
}
|
||||
cp.origin += cp.normal * f.cut_offset;
|
||||
if (f.cut_flip) cp.normal = -cp.normal;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user