From cd9e4185495f1a7232a976f0af2b64bc4403fbe4 Mon Sep 17 00:00:00 2001 From: Ajinkya Dahale Date: Thu, 22 Aug 2024 22:41:31 +0530 Subject: [PATCH] [Sketcher] Refactor `SketchObject::migrateSketch()` Manipulate some if-else statements, for loops, and possibly replace them with std algorithms. --- src/Mod/Sketcher/App/SketchObject.cpp | 300 +++++++++++++------------- 1 file changed, 154 insertions(+), 146 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 9db00e34da..6639e92af3 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -10814,60 +10814,64 @@ void SketchObject::onSketchRestore() } } +// clang-format on void SketchObject::migrateSketch() { - bool noextensions = false; - for (const auto& g : getInternalGeometry()) - // no extension - legacy file - if (!g->hasExtension(SketchGeometryExtension::getClassTypeId())) - noextensions = true; + const auto& allGeoms = getInternalGeometry(); + bool noextensions = std::ranges::any_of(allGeoms, [](const auto& geo) { + return !geo->hasExtension(SketchGeometryExtension::getClassTypeId()); + }); if (noextensions) { - for (auto c : Constraints.getValues()) { + for (const auto& c : Constraints.getValues()) { addGeometryState(c); // Convert B-Spline controlpoints radius/diameter constraints to Weight constraints - if (c->Type == InternalAlignment && c->AlignmentType == BSplineControlPoint) { - int circlegeoid = c->First; - int bsplinegeoid = c->Second; + if (c->Type != InternalAlignment || c->AlignmentType != BSplineControlPoint) { + continue; + } - auto bsp = static_cast(getGeometry(bsplinegeoid)); + int circleGeoId = c->First; + int bSplineGeoId = c->Second; - std::vector weights = bsp->getWeights(); + auto bsp = static_cast(getGeometry(bSplineGeoId)); - for (auto ccp : Constraints.getValues()) { - if ((ccp->Type == Radius || ccp->Type == Diameter) - && ccp->First == circlegeoid) { - if (c->InternalAlignmentIndex < int(weights.size())) { - ccp->Type = Weight; - ccp->setValue(weights[c->InternalAlignmentIndex]); - } - } + std::vector weights = bsp->getWeights(); + + if (!(c->InternalAlignmentIndex < int(weights.size()))) { + continue; + } + + for (auto& ccp : Constraints.getValues()) { + if ((ccp->Type == Radius || ccp->Type == Diameter) && ccp->First == circleGeoId) { + ccp->Type = Weight; + ccp->setValue(weights[c->InternalAlignmentIndex]); } } } // Construction migration to extension - for (auto g : Geometry.getValues()) { - if (g->hasExtension(Part::GeometryMigrationExtension::getClassTypeId())) { - auto ext = std::static_pointer_cast( - g->getExtension(Part::GeometryMigrationExtension::getClassTypeId()).lock()); - - if (ext->testMigrationType(Part::GeometryMigrationExtension::Construction)) { - // at this point IA geometry is already migrated - auto gf = GeometryFacade::getFacade(g); - - bool oldconstr = ext->getConstruction(); - - if (g->is() && !gf->isInternalAligned()) - oldconstr = true; - - GeometryFacade::setConstruction(g, oldconstr); - } - - g->deleteExtension(Part::GeometryMigrationExtension::getClassTypeId()); + for (auto& g : Geometry.getValues()) { + if (!g->hasExtension(Part::GeometryMigrationExtension::getClassTypeId())) { + continue; } + + auto ext = std::static_pointer_cast( + g->getExtension(Part::GeometryMigrationExtension::getClassTypeId()).lock()); + + if (!ext->testMigrationType(Part::GeometryMigrationExtension::Construction)) { + continue; + } + // at this point IA geometry is already migrated + auto gf = GeometryFacade::getFacade(g); + + bool oldConstr = + ext->getConstruction() || (g->is() && !gf->isInternalAligned()); + + GeometryFacade::setConstruction(g, oldConstr); + + g->deleteExtension(Part::GeometryMigrationExtension::getClassTypeId()); } } @@ -10875,124 +10879,128 @@ void SketchObject::migrateSketch() auto constraints = Constraints.getValues(); auto geometries = getInternalGeometry(); - bool parabolaFound = std::ranges::any_of(geometries, &Part::Geometry::is); + bool parabolaFound = + std::ranges::any_of(geometries, &Part::Geometry::is); - if (parabolaFound) { - bool focalaxisfound = std::ranges::any_of(constraints, [](auto& c) { - return c->Type == InternalAlignment && c->AlignmentType == ParabolaFocalAxis; - }); + if (!parabolaFound) { + return; + } - // There are parabolas and there isn't an IA axis. (1) there are no axis or (2) there is a - // legacy construction line - if (!focalaxisfound) { - // maps parabola geoid to focusgeoid - std::map parabolageoid2focusgeoid; + auto focalAxisFound = std::ranges::any_of(constraints, [](auto c) { + return c->Type == InternalAlignment && c->AlignmentType == ParabolaFocalAxis; + }); - // populate parabola and focus geoids - for (const auto& c : constraints) { - if (c->Type == InternalAlignment && c->AlignmentType == ParabolaFocus) { - parabolageoid2focusgeoid[c->Second] = {c->First}; - } - } + if (focalAxisFound) { + return; + } - // maps axis geoid to parabolageoid - std::map axisgeoid2parabolageoid; + // There are parabolas and there isn't an IA axis. (1) there are no axis or (2) there is a + // legacy construction line - // populate axis geoid - for (const auto& [parabolageoid, focusgeoid] : parabolageoid2focusgeoid) { - // look for a line from focusgeoid:start to Geoid:mid_external - std::vector focusgeoidlistgeoidlist; - std::vector focusposidlist; - getDirectlyCoincidentPoints( - focusgeoid, Sketcher::PointPos::start, focusgeoidlistgeoidlist, focusposidlist); + // maps parabola geoid to focusGeoId + std::map parabolaGeoId2FocusGeoId; - std::vector parabgeoidlistgeoidlist; - std::vector parabposidlist; - getDirectlyCoincidentPoints(parabolageoid, - Sketcher::PointPos::mid, - parabgeoidlistgeoidlist, - parabposidlist); - - if (!focusgeoidlistgeoidlist.empty() && !parabgeoidlistgeoidlist.empty()) { - std::size_t i, j; - for (i = 0; i < focusgeoidlistgeoidlist.size(); i++) { - for (j = 0; j < parabgeoidlistgeoidlist.size(); j++) { - if (focusgeoidlistgeoidlist[i] == parabgeoidlistgeoidlist[j]) { - axisgeoid2parabolageoid[focusgeoidlistgeoidlist[i]] = parabolageoid; - } - } - } - } - } - - std::vector newconstraints; - newconstraints.reserve(constraints.size()); - - for (const auto& c : constraints) { - - if (c->Type != Coincident) { - newconstraints.push_back(c); - } - else { - auto axismajorcoincidentfound = std::ranges::any_of(axisgeoid2parabolageoid, - [&](const auto& pair) { - auto parabolageoid = pair.second; - auto axisgeoid = pair.first; - return (c->First == axisgeoid && c->Second == parabolageoid - && c->SecondPos == PointPos::mid) - || (c->Second == axisgeoid && c->First == parabolageoid - && c->FirstPos == PointPos::mid); - }); - - if (axismajorcoincidentfound) { - // we skip this coincident, the other coincident on axis will be substituted - // by internal geometry constraint - continue; - } - - auto focuscoincidentfound = - std::ranges::find_if(axisgeoid2parabolageoid, - [&](const auto& pair) { - auto parabolageoid = pair.second; - auto axisgeoid = pair.first; - auto focusgeoid = parabolageoid2focusgeoid[parabolageoid]; - return (c->First == axisgeoid && c->Second == focusgeoid - && c->SecondPos == PointPos::start) - || (c->Second == axisgeoid && c->First == focusgeoid - && c->FirstPos == PointPos::start); - }); - - if (focuscoincidentfound != axisgeoid2parabolageoid.end()) { - Sketcher::Constraint* newConstr = new Sketcher::Constraint(); - newConstr->Type = Sketcher::InternalAlignment; - newConstr->AlignmentType = Sketcher::ParabolaFocalAxis; - newConstr->First = focuscoincidentfound->first;// axis geoid - newConstr->FirstPos = Sketcher::PointPos::none; - newConstr->Second = focuscoincidentfound->second;// parabola geoid - newConstr->SecondPos = Sketcher::PointPos::none; - newconstraints.push_back(newConstr); - - addGeometryState(newConstr); - - // we skip the coincident, as we have substituted it by internal geometry - // constraint - continue; - } - - newconstraints.push_back(c); - } - } - - Constraints.setValues(std::move(newconstraints)); - - Base::Console().critical( - this->getFullName(), - QT_TRANSLATE_NOOP("Notifications", - "Parabolas were migrated. Migrated files won't open in previous " - "versions of FreeCAD!!\n")); + // populate parabola and focus geoids + for (const auto& c : constraints) { + if (c->Type == InternalAlignment && c->AlignmentType == ParabolaFocus) { + parabolaGeoId2FocusGeoId[c->Second] = {c->First}; } } + + // maps axis geoid to parabolaGeoId + std::map axisGeoId2ParabolaGeoId; + + // populate axis geoid + for (const auto& [parabolaGeoId, focusGeoId] : parabolaGeoId2FocusGeoId) { + // look for a line from focusGeoId:start to Geoid:mid_external + std::vector focusGeoIdListGeoIdList; + std::vector focusPosIdList; + getDirectlyCoincidentPoints(focusGeoId, + Sketcher::PointPos::start, + focusGeoIdListGeoIdList, + focusPosIdList); + + std::vector parabGeoIdListGeoIdList; + std::vector parabposidlist; + getDirectlyCoincidentPoints(parabolaGeoId, + Sketcher::PointPos::mid, + parabGeoIdListGeoIdList, + parabposidlist); + + for (const auto& parabGeoIdListGeoId : parabGeoIdListGeoIdList) { + auto iterParabolaGeoId = + std::ranges::find(focusGeoIdListGeoIdList, parabGeoIdListGeoId); + if (iterParabolaGeoId != focusGeoIdListGeoIdList.end()) { + axisGeoId2ParabolaGeoId[*iterParabolaGeoId] = parabolaGeoId; + } + } + } + + std::vector newConstraints; + newConstraints.reserve(constraints.size()); + + for (const auto& c : constraints) { + if (c->Type != Coincident) { + newConstraints.push_back(c); + continue; + } + + auto axisMajorCoincidentFound = + std::ranges::any_of(axisGeoId2ParabolaGeoId, [&](const auto& pair) { + auto parabolaGeoId = pair.second; + auto axisgeoid = pair.first; + return (c->First == axisgeoid && c->Second == parabolaGeoId + && c->SecondPos == PointPos::mid) + || (c->Second == axisgeoid && c->First == parabolaGeoId + && c->FirstPos == PointPos::mid); + }); + + if (axisMajorCoincidentFound) { + // we skip this coincident, the other coincident on axis will be substituted + // by internal geometry constraint + continue; + } + + auto focusCoincidentFound = + std::ranges::find_if(axisGeoId2ParabolaGeoId, [&](const auto& pair) { + auto parabolaGeoId = pair.second; + auto axisgeoid = pair.first; + auto focusGeoId = parabolaGeoId2FocusGeoId[parabolaGeoId]; + return (c->First == axisgeoid && c->Second == focusGeoId + && c->SecondPos == PointPos::start) + || (c->Second == axisgeoid && c->First == focusGeoId + && c->FirstPos == PointPos::start); + }); + + if (focusCoincidentFound != axisGeoId2ParabolaGeoId.end()) { + auto* newConstr = new Sketcher::Constraint(); + newConstr->Type = Sketcher::InternalAlignment; + newConstr->AlignmentType = Sketcher::ParabolaFocalAxis; + newConstr->First = focusCoincidentFound->first; // axis geoid + newConstr->FirstPos = Sketcher::PointPos::none; + newConstr->Second = focusCoincidentFound->second; // parabola geoid + newConstr->SecondPos = Sketcher::PointPos::none; + newConstraints.push_back(newConstr); + + addGeometryState(newConstr); + + // we skip the coincident, as we have substituted it by internal geometry + // constraint + continue; + } + + newConstraints.push_back(c); + } + + Constraints.setValues(std::move(newConstraints)); + + Base::Console().critical( + this->getFullName(), + QT_TRANSLATE_NOOP("Notifications", + "Parabolas were migrated. Migrated files won't open in previous " + "versions of FreeCAD!!\n")); } +// clang-format off void SketchObject::getGeoVertexIndex(int VertexId, int& GeoId, PointPos& PosId) const {