From 44109480a1e4a015ee9ea762f7420df7bd3157c2 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Sat, 28 Sep 2024 11:36:03 +0800 Subject: [PATCH] Sketcher: allow copying of external geometry Closes #1006 --- src/Mod/Sketcher/App/SketchObject.cpp | 28 +++++++- src/Mod/Sketcher/Gui/CommandSketcherTools.cpp | 71 ++++++++++--------- 2 files changed, 62 insertions(+), 37 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index f173c5cf1d35..1c3a1a871b75 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -5270,12 +5270,30 @@ int SketchObject::addCopy(const std::vector& geoIdList, const Base::Vector3 newgeoVals.reserve(geovals.size() + geoIdList.size()); } - std::vector newgeoIdList(geoIdList); + std::vector newgeoIdList; - if (newgeoIdList.empty()) {// default option to operate on all the geometry + if (geoIdList.empty()) {// default option to operate on all the geometry for (int i = 0; i < int(geovals.size()); i++) newgeoIdList.push_back(i); } + else { + for (const auto &GeoId : geoIdList) { + if ((GeoId >= 0 && GeoId >= static_cast(geovals.size())) + || (GeoId < 0 && -GeoId-1 >= ExternalGeo.getSize())) { + FC_ERR("Invalid geometry index"); + break; + } + else if (moveonly && GeoId < 0) { + FC_ERR("Cannot move external geometry"); + break; + } + newgeoIdList.push_back(GeoId); + } + if (newgeoIdList.size() != geoIdList.size()) { + return Geometry.getSize() - 1; + } + } + int cgeoid = getHighestCurveIndex() + 1; @@ -5388,6 +5406,12 @@ int SketchObject::addCopy(const std::vector& geoIdList, const Base::Vector3 // moving if (!moveonly) { geocopy = geo->copy(); + if (auto egf = ExternalGeometryFacade::getFacade(geo)) { + if(egf->testFlag(ExternalGeometryExtension::Defining)) { + GeometryFacade::setConstruction(geocopy, false); + } + geocopy->deleteExtension(ExternalGeometryExtension::getClassTypeId()); + } generateId(geocopy); } else geocopy = newgeoVals[*it]; diff --git a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp index 705606fe725b..49f38b43ba40 100644 --- a/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp +++ b/src/Mod/Sketcher/Gui/CommandSketcherTools.cpp @@ -910,16 +910,17 @@ void CmdSketcherSymmetry::activated(int iMsg) for (std::vector::const_iterator it = SubNames.begin(); it != SubNames.end(); ++it) { + bool external = false; // only handle non-external edges - if ((it->size() > 4 && it->substr(0, 4) == "Edge") - || (it->size() > 12 && it->substr(0, 12) == "ExternalEdge")) { + if (boost::starts_with(*it, "Edge") + || (external = boost::starts_with(*it, "ExternalEdge"))) { - if (it->substr(0, 4) == "Edge") { - LastGeoId = std::atoi(it->substr(4, 4000).c_str()) - 1; + if (!external) { + LastGeoId = std::atoi(it->c_str()+4) - 1; LastPointPos = Sketcher::PointPos::none; } else { - LastGeoId = -std::atoi(it->substr(12, 4000).c_str()) - 2; + LastGeoId = -std::atoi(it->c_str()+12) - 2; LastPointPos = Sketcher::PointPos::none; } @@ -932,10 +933,8 @@ void CmdSketcherSymmetry::activated(int iMsg) lastgeotype = invalid; // lines to make symmetric (only non-external) - if (LastGeoId >= 0) { - geoids++; - stream << LastGeoId << ","; - } + geoids++; + stream << LastGeoId << ","; } else if (it->size() > 6 && it->substr(0, 6) == "Vertex") { // only if it is a GeomPoint @@ -950,10 +949,8 @@ void CmdSketcherSymmetry::activated(int iMsg) lastgeotype = point; // points to make symmetric - if (LastGeoId >= 0) { - geoids++; - stream << LastGeoId << ","; - } + geoids++; + stream << LastGeoId << ","; } } } @@ -1288,16 +1285,20 @@ void SketcherCopy::activate(SketcherCopy::Op op) int geoids = 0; for (std::vector::const_iterator it = SubNames.begin(); it != SubNames.end(); ++it) { - // only handle non-external edges - if (it->size() > 4 && it->substr(0, 4) == "Edge") { - LastGeoId = std::atoi(it->substr(4, 4000).c_str()) - 1; + bool external = false; + if (boost::starts_with(*it, "Edge") + || (external = boost::starts_with(*it, "ExternalEdge"))) { + if (!external) { + LastGeoId = std::atoi(it->c_str()+4) - 1; + } + else { + LastGeoId = -std::atoi(it->c_str()+12) - 2; + } LastPointPos = Sketcher::PointPos::none; LastGeo = Obj->getGeometry(LastGeoId); // lines to copy - if (LastGeoId >= 0) { - geoids++; - stream << LastGeoId << ","; - } + geoids++; + stream << LastGeoId << ","; } else if (it->size() > 6 && it->substr(0, 6) == "Vertex") { // only if it is a GeomPoint @@ -1309,10 +1310,8 @@ void SketcherCopy::activate(SketcherCopy::Op op) LastGeoId = GeoId; LastPointPos = Sketcher::PointPos::start; // points to copy - if (LastGeoId >= 0) { - geoids++; - stream << LastGeoId << ","; - } + geoids++; + stream << LastGeoId << ","; } } } @@ -1799,17 +1798,21 @@ void CmdSketcherRectangularArray::activated(int iMsg) for (std::vector::const_iterator it = SubNames.begin(); it != SubNames.end(); ++it) { - // only handle non-external edges - if (it->size() > 4 && it->substr(0, 4) == "Edge") { - LastGeoId = std::atoi(it->substr(4, 4000).c_str()) - 1; + bool external = false; + if (boost::starts_with(*it, "Edge") + || (external = boost::starts_with(*it, "ExternalEdge"))) { + if (!external) { + LastGeoId = std::atoi(it->c_str()+4) - 1; + } + else { + LastGeoId = -std::atoi(it->c_str()+12) - 2; + } LastPointPos = Sketcher::PointPos::none; LastGeo = Obj->getGeometry(LastGeoId); // lines to copy - if (LastGeoId >= 0) { - geoids++; - stream << LastGeoId << ","; - } + geoids++; + stream << LastGeoId << ","; } else if (it->size() > 6 && it->substr(0, 6) == "Vertex") { // only if it is a GeomPoint @@ -1821,10 +1824,8 @@ void CmdSketcherRectangularArray::activated(int iMsg) LastGeoId = GeoId; LastPointPos = Sketcher::PointPos::start; // points to copy - if (LastGeoId >= 0) { - geoids++; - stream << LastGeoId << ","; - } + geoids++; + stream << LastGeoId << ","; } } }