diff --git a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp index 582bb8c529..bce3f729c1 100644 --- a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp +++ b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp @@ -983,50 +983,67 @@ void CmdSketcherRestoreInternalAlignmentGeometry::activated(int iMsg) getSelection().clearSelection(); + // Return GeoId of the SubName only if it is an edge + auto getEdgeGeoId = [&Obj](const std::string& SubName) { + int GeoId; + Sketcher::PointPos PosId; + getIdsFromName(SubName, Obj, GeoId, PosId); + if (PosId == Sketcher::PointPos::none) + return GeoId; + else + return (int)GeoEnum::GeoUndef; + }; + + // Tells if the geometry with given GeoId has internal geometry + auto noInternalGeo = [&Obj](const auto& GeoId) { + const Part::Geometry *geo = Obj->getGeometry(GeoId); + bool hasInternalGeo = geo && + (geo->getTypeId() == Part::GeomEllipse::getClassTypeId() || + geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || + geo->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId() || + geo->getTypeId() == Part::GeomArcOfParabola::getClassTypeId() || + geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()); + return !hasInternalGeo; // so it's removed + }; + + std::vector SubGeoIds(SubNames.size()); + std::transform(SubNames.begin(), SubNames.end(), SubGeoIds.begin(), getEdgeGeoId); + + // Handle highest GeoIds first to minimize GeoIds changing + // TODO: this might not completely resolve GeoIds changing + std::sort(SubGeoIds.begin(), SubGeoIds.end(), std::greater()); + // Keep unique + SubGeoIds.erase(std::unique(SubGeoIds.begin(), SubGeoIds.end()), SubGeoIds.end()); + + // Only for supported types and keep unique + SubGeoIds.erase(std::remove_if(SubGeoIds.begin(), SubGeoIds.end(), noInternalGeo), + SubGeoIds.end()); + // go through the selected subelements - for (std::vector::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) { - // only handle edges - if ((it->size() > 4 && it->substr(0,4) == "Edge") || - (it->size() > 12 && it->substr(0,12) == "ExternalEdge")) { - int GeoId; - if (it->substr(0,4) == "Edge") - GeoId = std::atoi(it->substr(4,4000).c_str()) - 1; - else - GeoId = -std::atoi(it->substr(12,4000).c_str()) - 2; + for (const auto& GeoId : SubGeoIds) { + int currentgeoid = Obj->getHighestCurveIndex(); - const Part::Geometry *geo = Obj->getGeometry(GeoId); - // Only for supported types - if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId() || - geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || - geo->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId() || - geo->getTypeId() == Part::GeomArcOfParabola::getClassTypeId() || - geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) { + try { + Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Exposing Internal Geometry")); + Gui::cmdAppObjectArgs(Obj, "exposeInternalGeometry(%d)", GeoId); - int currentgeoid = Obj->getHighestCurveIndex(); + int aftergeoid = Obj->getHighestCurveIndex(); - try { - Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Exposing Internal Geometry")); - Gui::cmdAppObjectArgs(Obj, "exposeInternalGeometry(%d)", GeoId); - - int aftergeoid = Obj->getHighestCurveIndex(); - - if(aftergeoid == currentgeoid) { // if we did not expose anything, deleteunused - Gui::cmdAppObjectArgs(Obj, "deleteUnusedInternalGeometry(%d)", GeoId); - } - } - catch (const Base::Exception& e) { - Base::Console().Error("%s\n", e.what()); - Gui::Command::abortCommand(); - - tryAutoRecomputeIfNotSolve(static_cast(Obj)); - - return; - } - - Gui::Command::commitCommand(); - tryAutoRecomputeIfNotSolve(static_cast(Obj)); + if(aftergeoid == currentgeoid) { // if we did not expose anything, deleteunused + Gui::cmdAppObjectArgs(Obj, "deleteUnusedInternalGeometry(%d)", GeoId); } } + catch (const Base::Exception& e) { + Base::Console().Error("%s\n", e.what()); + Gui::Command::abortCommand(); + + tryAutoRecomputeIfNotSolve(static_cast(Obj)); + + return; + } + + Gui::Command::commitCommand(); + tryAutoRecomputeIfNotSolve(static_cast(Obj)); } }