From 018ac7b9dd55d4780f2a3ca503abf257e5bf4ee7 Mon Sep 17 00:00:00 2001 From: Ajinkya Dahale Date: Sat, 19 Jul 2025 03:07:31 +0530 Subject: [PATCH 1/2] Sketcher: Skip checks in `deriveConstraintsForPieces` when risky Possibly fixes #22352. It is possible to call the method when new geos are not yet created or added to the sketch. In such cases, the values obtained can be "dirty", and is likely a seg-fault. --- src/Mod/Sketcher/App/SketchObject.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index bc9148dd39..c88fde3c20 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -3578,6 +3578,8 @@ bool SketchObject::deriveConstraintsForPieces(const int oldId, conPos = con->SecondPos; } + bool newGeosLikelyNotCreated = std::ranges::find(newGeos, nullptr) != newGeos.end(); + bool transferToAll = false; switch (con->Type) { case Horizontal: @@ -3598,6 +3600,11 @@ bool SketchObject::deriveConstraintsForPieces(const int oldId, return false; } + // no use going forward if newGeos aren't ready + if (newGeosLikelyNotCreated) { + break; + } + // For now: just transfer to the first intersection // TODO: Actually check that there was perpendicularity earlier // TODO: Choose piece based on parameters ("values" of the constraint) @@ -3632,10 +3639,11 @@ bool SketchObject::deriveConstraintsForPieces(const int oldId, return true; } - if (conId == GeoEnum::GeoUndef) { + if (conId == GeoEnum::GeoUndef || newGeosLikelyNotCreated) { // nothing further to do return false; } + Base::Vector3d conPoint(getPoint(conId, conPos)); double conParam; auto* geoAsCurve = static_cast(geo); From 114d3dcd8716b1f5659c5b5c95231a18f13caae0 Mon Sep 17 00:00:00 2001 From: Ajinkya Dahale Date: Sat, 19 Jul 2025 03:13:54 +0530 Subject: [PATCH 2/2] Sketcher: Improve constraint transfer in `SketchObject::trim()` Provide new geos to `deriveConstraintsForPieces` manually, since they are not (and likely cannot be at time of calling) added to the sketch. This will make sure that the method has sufficient information to properly transfer/create new constraints. --- src/Mod/Sketcher/App/SketchObject.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index c88fde3c20..92c7a9b703 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -3276,6 +3276,7 @@ void createNewConstraintsForTrim(const SketchObject* obj, const std::array& cuttingGeoIds, const std::array& cutPoints, const std::vector& newIds, + const std::vector newGeos, std::vector& idsOfOldConstraints, std::vector& newConstraints, std::set>& geoIdsToBeDeleted) @@ -3320,7 +3321,7 @@ void createNewConstraintsForTrim(const SketchObject* obj, continue; } // constraint has not yet been changed - obj->deriveConstraintsForPieces(GeoId, newIds, con, newConstraints); + obj->deriveConstraintsForPieces(GeoId, newIds, newGeos, con, newConstraints); } // Add point-on-object/coincidence constraints with the newly exposed points. @@ -3403,6 +3404,7 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) //****************************************// std::vector newIds; std::vector newGeos; + std::vector newGeosAsConsts; switch (paramsOfNewGeos.size()) { case 0: { @@ -3424,6 +3426,9 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) } createArcsFromGeoWithLimits(geoAsCurve, paramsOfNewGeos, newGeos); + for (const auto* geo : newGeos) { + newGeosAsConsts.push_back(geo); + } //******************* Step C => Creation of new constraints //****************************************// @@ -3461,6 +3466,7 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) cuttingGeoIds, cutPoints, newIds, + newGeosAsConsts, idsOfOldConstraints, newConstraints, geoIdsToBeDeleted);