mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-27 19:01:02 +00:00
Port: mirror emits a half that continues the chain
Carries snaporca 0231bd5b68. Parity holds: 17 files identical, 8 diverging as expected. A reflection reverses orientation, so mirror_entities now hands the reflected half back reversed in ORDER and flipped per ENTITY — an arc swapping its angles as well as its ends, a spline reversing its control points. Appending it to the source then yields one walkable chain instead of two halves meeting head-to-head, and a mirrored CCW loop stays CCW. This is the producer half of the confusion that cost three defects; the consumers (offset, and the exact loop area) keep their defensive handling, because that is what makes them correct for hand-built and imported sketches rather than only for geometry this function produced. Contract change, carried with the reason: a mirrored line's p0 is the reflection of the SOURCE's p1, and a mirrored CCW arc keeps a POSITIVE sweep — the reflection negates it, walking it the other way negates it again. Both [SketchEdit] cases updated, and a new [SketchProfile] case "a mirrored half continues the original chain" pins the property directly. Kernel here: all tests passed, 2687 assertions in 232 test cases. GUI target builds and links. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
cbbd24dcb4
commit
942f6c28c7
@@ -897,6 +897,36 @@ std::vector<SketchEntity> SketchEngine::mirror_entities(
|
||||
out.push_back(m);
|
||||
}
|
||||
|
||||
// A REFLECTION REVERSES ORIENTATION, so the reflected half is handed back reversed — in
|
||||
// order, and each entity flipped — or it does not CONTINUE the chain it was made from.
|
||||
//
|
||||
// Draw half a stadium left-to-right along the bottom, round the cap, right-to-left along the
|
||||
// top, ending at (0, R). Reflecting each entity in place gives a half whose top run STARTS at
|
||||
// (-L, R) and ENDS at (0, R): it meets the original head-to-head, not head-to-tail. Every
|
||||
// consumer that walks the loop then has to cope, and two already had to be taught — the loop
|
||||
// area cancelled its own arc correction against the negated sweep, and offset put the
|
||||
// reflected half on the wrong side because it read each entity's STORED direction. Reversed
|
||||
// here, the two halves are one walkable chain and a mirrored CCW loop stays CCW.
|
||||
std::reverse(out.begin(), out.end());
|
||||
for (SketchEntity& m : out) {
|
||||
switch (m.type) {
|
||||
case SketchEntity::Type::Line:
|
||||
std::swap(m.p0, m.p1);
|
||||
break;
|
||||
case SketchEntity::Type::Arc:
|
||||
case SketchEntity::Type::EllipseArc:
|
||||
std::swap(m.p0, m.p1);
|
||||
std::swap(m.start_angle, m.end_angle); // what "walked the other way" means
|
||||
break;
|
||||
case SketchEntity::Type::BSpline:
|
||||
std::swap(m.p0, m.p1);
|
||||
std::reverse(m.ctrl.begin(), m.ctrl.end());
|
||||
break;
|
||||
default:
|
||||
break; // circle, ellipse, point: no direction to reverse
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user