From 62d39fba276788d25e404d10a08d6cd0c7f5e52d Mon Sep 17 00:00:00 2001 From: Tommaso Bianchi Date: Sat, 25 Jul 2026 00:27:01 +0200 Subject: [PATCH] test(cad): lock construction-geometry flag with real regression tests The construction flag was already honored (excluded from the extrude wire in SketchEngine.cpp, participates in the solver, and serialized) but the existing "construction line excluded" test was a false tripwire: its construction line ran corner-to-corner inside the square, so the bbox was unchanged whether or not the line was excluded. - Strengthen that test: the construction line now runs (-30,0)->(30,0) outside the profile, so an exclusion regression breaks the closed wire / bbox. - Add a serialize/deserialize round-trip test asserting construction survives. - Lock the flag on-disk: add Sketch_Ctor to the golden fixture with a real edge + a construction edge, and assert both flags survive the binary recipe. Test-only; no kernel change. Recipe version stays 2 (construction was already a serialized field). Suite: 72 cases / 1246 assertions green. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01BVzKmX6Y1aEteit1HTXG4Q --- tests/data/cad_recipe_v2.bin | Bin 26835 -> 27913 bytes tests/libslic3r/test_caddocument.cpp | 65 ++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/tests/data/cad_recipe_v2.bin b/tests/data/cad_recipe_v2.bin index 3d131e40d72b3f751fb363dc22ee66c7c7cb16e4..93ab5e116e8b22a0725f3c9f91012231e9d22315 100644 GIT binary patch delta 124 zcmcb7k+Jg@BP$aF1B3iV)^iyX9ax09fgBJB&Q2{!&WLv|$uFAxF`#YoBwZmXjRRmQ t1~}~i<4>Mw=q>32l~#fZyFh8B$$@;DlckvWCf6IQPIM62e86TV696q78 wire -> extrude", "[CadDocument]") SketchEntity cline; cline.type = SketchEntity::Type::Line; - cline.p0 = Vec2d(-10, -10); - cline.p1 = Vec2d(10, 10); + cline.p0 = Vec2d(-30, 0); + cline.p1 = Vec2d(30, 0); cline.construction = true; sk.entities = { @@ -232,6 +232,47 @@ TEST_CASE("sketch entities -> wire -> extrude", "[CadDocument]") } } +TEST_CASE("construction flag survives recipe round-trip", "[CadDocument]") +{ + CadDocument doc; + + // Square edge + 1 construction line + std::vector ents = { + {SketchEntity::Type::Line, Vec2d(-10, -10), Vec2d(10, -10)}, + {SketchEntity::Type::Line, Vec2d(10, -10), Vec2d(10, 10)}, + {SketchEntity::Type::Line, Vec2d(10, 10), Vec2d(-10, 10)}, + {SketchEntity::Type::Line, Vec2d(-10, 10), Vec2d(-10, -10)}, + }; + SketchEntity cx; + cx.type = SketchEntity::Type::Line; + cx.p0 = Vec2d(-33.0, 7.0); + cx.p1 = Vec2d(33.0, 7.0); + cx.construction = true; + ents.push_back(cx); // ents[4] + + int sk = doc.add_sketch_entities(ents, SketchPlane::XY(), "SkCtor"); + REQUIRE(sk == 0); + doc.add_extrude(sk, 5.0, false, BooleanMode::New, "Ex"); + + std::string blob = doc.serialize_recipe(); + REQUIRE_FALSE(blob.empty()); + + CadDocument fresh; + REQUIRE(fresh.deserialize_recipe(blob)); + + // Locate SkCtor in fresh.features + const CadFeature* sf = nullptr; + for (const auto& f : fresh.features) { + if (f.name == "SkCtor") { sf = &f; break; } + } + REQUIRE(sf != nullptr); + REQUIRE(sf->entities.size() == 5); + REQUIRE(sf->entities[0].construction == false); + REQUIRE(sf->entities[4].construction == true); + REQUIRE_THAT(sf->entities[4].p0.x(), Catch::Matchers::WithinAbs(-33.0, 1e-9)); + REQUIRE_THAT(sf->entities[4].p1.x(), Catch::Matchers::WithinAbs( 33.0, 1e-9)); +} + // Mirrors the GUI interactive-sketch commit path (DesignPanel -> // add_sketch_entities) for the Fase 4.1 entity drawing tools: a corner-rect and // a center-rect produce 4 closed Line entities; a center-circle produces 1 @@ -3420,6 +3461,20 @@ static CadDocument make_golden_doc_v1() doc.add_project_edges(0, {}, 0, SketchPlane::XY(), "GoldenProject"); + // Construction-flag on-disk lock: a real edge + a construction edge with distinctive + // literals. Regen-golden does not recompute, so this only exercises serialization. + { + std::vector ge; + SketchEntity real0; real0.type = SketchEntity::Type::Line; + real0.p0 = Vec2d(-12.0, -12.0); real0.p1 = Vec2d(12.0, -12.0); + SketchEntity ctor; ctor.type = SketchEntity::Type::Line; + ctor.p0 = Vec2d(-40.0, 9.0); ctor.p1 = Vec2d(40.0, 9.0); + ctor.construction = true; + ge.push_back(real0); + ge.push_back(ctor); + doc.add_sketch_entities(ge, SketchPlane::XY(), "Sketch_Ctor"); + } + return doc; } @@ -3518,6 +3573,12 @@ TEST_CASE("golden recipe v1 still deserialises", "[CadDocument]") if (e.name == "Sketch_LoftTop") { REQUIRE_THAT(f.plane.origin.z(), WithinAbs(25.0, 1e-9)); } + if (e.name == "Sketch_Ctor") { + REQUIRE(f.entities.size() == 2); + REQUIRE(f.entities[0].construction == false); + REQUIRE(f.entities[1].construction == true); + REQUIRE_THAT(f.entities[1].p0.x(), WithinAbs(-40.0, 1e-9)); + } } // Extrude params