From 223877873b30c8387dfd50e111bbe009940d07e1 Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Mon, 25 Nov 2024 17:57:16 +0100 Subject: [PATCH] Sketcher: Offset & tranforms: enable external geos input. (#17615) * Sketcher: Offset & tranforms: enable external geos input. * Sketcher: enable delGeometries to handle external geos. --- src/Mod/Sketcher/App/SketchObject.cpp | 29 ++++++++++-- src/Mod/Sketcher/Gui/CommandSketcherTools.cpp | 46 +++++++++++-------- 2 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index eb346a7187..7bbc06c2c0 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -1681,10 +1681,33 @@ int SketchObject::delGeometry(int GeoId, bool deleteinternalgeo) return 0; } - int SketchObject::delGeometries(const std::vector& GeoIds) { - std::vector sGeoIds(GeoIds); + std::vector sGeoIds; + std::vector negativeGeoIds; + + // Separate GeoIds into negative (external) and non-negative GeoIds + for (int geoId : GeoIds) { + if (geoId < 0 && geoId <= GeoEnum::RefExt) { + negativeGeoIds.push_back(geoId); + } + else if (geoId >= 0){ + sGeoIds.push_back(geoId); + } + } + + // Handle negative GeoIds by calling delExternal + if (!negativeGeoIds.empty()) { + int result = delExternal(negativeGeoIds); + if (result != 0) { + return result; // Return if deletion of external geometries failed + } + } + + // Proceed with non-negative GeoIds + if (sGeoIds.empty()) { + return 0; // No positive GeoIds to delete + } // if a GeoId has internal geometry, it must delete internal geometries too for (auto c : Constraints.getValues()) { @@ -7732,7 +7755,7 @@ int SketchObject::delExternal(const std::vector& ExtGeoIds) { std::set geoIds; for (int ExtGeoId : ExtGeoIds) { - int GeoId = GeoEnum::RefExt - ExtGeoId; + int GeoId = ExtGeoId > 0 ? GeoEnum::RefExt - ExtGeoId : ExtGeoId; if (GeoId > GeoEnum::RefExt || -GeoId - 1 >= ExternalGeo.getSize()) return -1; diff --git a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp index a2ddc72884..7bfa00b82e 100644 --- a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp +++ b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp @@ -88,12 +88,13 @@ std::vector getListOfSelectedGeoIds(bool forceInternalSelection) if (!subNames.empty()) { for (auto& name : subNames) { - // only handle non-external edges if (name.size() > 4 && name.substr(0, 4) == "Edge") { int geoId = std::atoi(name.substr(4, 4000).c_str()) - 1; - if (geoId >= 0) { - listOfGeoIds.push_back(geoId); - } + listOfGeoIds.push_back(geoId); + } + else if (name.size() > 12 && name.substr(0, 12) == "ExternalEdge") { + int geoId = -std::atoi(name.substr(12, 4000).c_str()) - 2; + listOfGeoIds.push_back(geoId); } else if (name.size() > 6 && name.substr(0, 6) == "Vertex") { // only if it is a GeomPoint @@ -2341,23 +2342,28 @@ void CmdSketcherOffset::activated(int iMsg) const std::vector& subNames = selection[0].getSubNames(); if (!subNames.empty()) { for (auto& name : subNames) { - // only handle non-external edges + int geoId; if (name.size() > 4 && name.substr(0, 4) == "Edge") { - int geoId = std::atoi(name.substr(4, 4000).c_str()) - 1; - if (geoId >= 0) { - const Part::Geometry* geo = Obj->getGeometry(geoId); - if (!isPoint(*geo) - && !isBSplineCurve(*geo) - && !isEllipse(*geo) - && !isArcOfEllipse(*geo) - && !isArcOfHyperbola(*geo) - && !isArcOfParabola(*geo) - && !GeometryFacade::isInternalAligned(geo)) { - // Currently ellipse/parabola/hyperbola/bspline are not handled correctly. - // Occ engine gives offset of those as set of lines and arcs and does not seem to work consistently. - listOfGeoIds.push_back(geoId); - } - } + geoId = std::atoi(name.substr(4, 4000).c_str()) - 1; + } + else if (name.size() > 12 && name.substr(0, 12) == "ExternalEdge") { + geoId = -std::atoi(name.substr(12, 4000).c_str()) - 2; + } + else { + continue; + } + + const Part::Geometry* geo = Obj->getGeometry(geoId); + if (!isPoint(*geo) + && !isBSplineCurve(*geo) + && !isEllipse(*geo) + && !isArcOfEllipse(*geo) + && !isArcOfHyperbola(*geo) + && !isArcOfParabola(*geo) + && !GeometryFacade::isInternalAligned(geo)) { + // Currently ellipse/parabola/hyperbola/bspline are not handled correctly. + // Occ engine gives offset of those as set of lines and arcs and does not seem to work consistently. + listOfGeoIds.push_back(geoId); } } }