From ae60811fba417a0eca8df708212ce5c582d14a01 Mon Sep 17 00:00:00 2001 From: Florian Foinant-Willig Date: Mon, 28 Aug 2023 17:58:09 +0200 Subject: [PATCH] Sketcher: Point to Circle Distance Constraints (#9559) --- src/Mod/Sketcher/App/Sketch.cpp | 549 ++++++--- src/Mod/Sketcher/App/planegcs/Constraints.cpp | 724 ++++++++---- src/Mod/Sketcher/App/planegcs/Constraints.h | 49 +- src/Mod/Sketcher/App/planegcs/GCS.cpp | 1044 +++++++++++------ src/Mod/Sketcher/App/planegcs/GCS.h | 306 +++-- src/Mod/Sketcher/App/planegcs/Geo.cpp | 51 +- src/Mod/Sketcher/App/planegcs/Geo.h | 23 +- src/Mod/Sketcher/Gui/CommandConstraints.cpp | 900 +++++++++----- .../Gui/EditModeConstraintCoinManager.cpp | 273 +++-- src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 6 + 10 files changed, 2714 insertions(+), 1211 deletions(-) diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp index c4194e334c..43cfc2a038 100644 --- a/src/Mod/Sketcher/App/Sketch.cpp +++ b/src/Mod/Sketcher/App/Sketch.cpp @@ -101,14 +101,19 @@ void Sketch::clear() resolveAfterGeometryUpdated = false; // deleting the doubles allocated with new - for (std::vector::iterator it = Parameters.begin(); it != Parameters.end(); ++it) - if (*it) + for (std::vector::iterator it = Parameters.begin(); it != Parameters.end(); ++it) { + if (*it) { delete *it; + } + } Parameters.clear(); DrivenParameters.clear(); - for (std::vector::iterator it = FixParameters.begin(); it != FixParameters.end(); ++it) - if (*it) + for (std::vector::iterator it = FixParameters.begin(); it != FixParameters.end(); + ++it) { + if (*it) { delete *it; + } + } FixParameters.clear(); param2geoelement.clear(); @@ -118,9 +123,11 @@ void Sketch::clear() internalAlignmentGeometryMap.clear(); // deleting the geometry copied into this sketch - for (std::vector::iterator it = Geoms.begin(); it != Geoms.end(); ++it) - if (it->geo) + for (std::vector::iterator it = Geoms.begin(); it != Geoms.end(); ++it) { + if (it->geo) { delete it->geo; + } + } Geoms.clear(); // deleting the non-Driving constraints copied into this sketch @@ -158,12 +165,14 @@ bool Sketch::analyseBlockedGeometry(const std::vector& internal for (auto c : constraintList) { // is block driving - if (c->Type == Sketcher::Block && c->isDriving && c->First == geoindex) + if (c->Type == Sketcher::Block && c->isDriving && c->First == geoindex) { blockisDriving = true; + } // We have another driving constraint (which may be InternalAlignment) if (c->Type != Sketcher::Block && c->isDriving - && (c->First == geoindex || c->Second == geoindex || c->Third == geoindex)) + && (c->First == geoindex || c->Second == geoindex || c->Third == geoindex)) { blockOnly = false; + } } if (blockisDriving) { @@ -185,17 +194,20 @@ bool Sketch::analyseBlockedGeometry(const std::vector& internal } int Sketch::setUpSketch(const std::vector& GeoList, - const std::vector& ConstraintList, int extGeoCount) + const std::vector& ConstraintList, + int extGeoCount) { Base::TimeInfo start_time; clear(); std::vector intGeoList, extGeoList; - for (int i = 0; i < int(GeoList.size()) - extGeoCount; i++) + for (int i = 0; i < int(GeoList.size()) - extGeoCount; i++) { intGeoList.push_back(GeoList[i]); - for (int i = int(GeoList.size()) - extGeoCount; i < int(GeoList.size()); i++) + } + for (int i = int(GeoList.size()) - extGeoCount; i < int(GeoList.size()); i++) { extGeoList.push_back(GeoList[i]); + } // these geometries are blocked, frozen and sent as fixed parameters to the solver std::vector onlyBlockedGeometry(intGeoList.size(), false); @@ -214,8 +226,9 @@ int Sketch::setUpSketch(const std::vector& GeoList, analyseBlockedGeometry(intGeoList, ConstraintList, onlyBlockedGeometry, blockedGeoIds); #ifdef DEBUG_BLOCK_CONSTRAINT - if (doesBlockAffectOtherConstraints) + if (doesBlockAffectOtherConstraints) { Base::Console().Log("\n Block interferes with other constraints: Post-analysis required"); + } Base::Console().Log("\nOnlyBlocked GeoIds:"); size_t i = 0; @@ -226,15 +239,18 @@ int Sketch::setUpSketch(const std::vector& GeoList, found = true; } } - if (found) + if (found) { Base::Console().Log("\n None"); + } Base::Console().Log("\nNotOnlyBlocked GeoIds:"); i = 0; - for (; i < blockedGeoIds.size(); i++) + for (; i < blockedGeoIds.size(); i++) { Base::Console().Log("\n GeoId=%d", blockedGeoIds[i]); - if (i == 0) + } + if (i == 0) { Base::Console().Log("\n None"); + } Base::Console().Log("\n"); #endif// DEBUG_BLOCK_CONSTRAINT @@ -244,8 +260,9 @@ int Sketch::setUpSketch(const std::vector& GeoList, int extStart = Geoms.size(); addGeometry(extGeoList, true); int extEnd = Geoms.size() - 1; - for (int i = extStart; i <= extEnd; i++) + for (int i = extStart; i <= extEnd; i++) { Geoms[i].external = true; + } // The Geoms list might be empty after an undo/redo if (!Geoms.empty()) { @@ -301,12 +318,13 @@ int Sketch::setUpSketch(const std::vector& GeoList, // Debug code block for (size_t i = 0; i < groups.size(); i++) { Base::Console().Log("\nDepParams: Group %d:", i); - for (size_t j = 0; j < groups[i].size(); j++) + for (size_t j = 0; j < groups[i].size(); j++) { Base::Console().Log( "\n Param=%x ,GeoId=%d, GeoPos=%d", param2geoelement.find(*std::next(groups[i].begin(), j))->first, param2geoelement.find(*std::next(groups[i].begin(), j))->second.first, param2geoelement.find(*std::next(groups[i].begin(), j))->second.second); + } } } #endif// DEBUG_BLOCK_CONSTRAINT @@ -367,7 +385,8 @@ void Sketch::fixParametersAndDiagnose(std::vector& params_to_block) } bool Sketch::analyseBlockedConstraintDependentParameters( - std::vector& blockedGeoIds, std::vector& params_to_block) const + std::vector& blockedGeoIds, + std::vector& params_to_block) const { // 1. Retrieve solver information std::vector> groups; @@ -385,12 +404,13 @@ bool Sketch::analyseBlockedConstraintDependentParameters( #ifdef DEBUG_BLOCK_CONSTRAINT for (size_t i = 0; i < groups.size(); i++) { Base::Console().Log("\nDepParams: Group %d:", i); - for (size_t j = 0; j < groups[i].size(); j++) + for (size_t j = 0; j < groups[i].size(); j++) { Base::Console().Log( "\n Param=%x ,GeoId=%d, GeoPos=%d", param2geoelement.find(*std::next(groups[i].begin(), j))->first, param2geoelement.find(*std::next(groups[i].begin(), j))->second.first, param2geoelement.find(*std::next(groups[i].begin(), j))->second.second); + } } #endif// DEBUG_BLOCK_CONSTRAINT @@ -403,8 +423,9 @@ bool Sketch::analyseBlockedConstraintDependentParameters( if (element != param2geoelement.end()) { - auto blockable = std::find( - blockedGeoIds.begin(), blockedGeoIds.end(), std::get<0>(element->second)); + auto blockable = std::find(blockedGeoIds.begin(), + blockedGeoIds.end(), + std::get<0>(element->second)); if (blockable != blockedGeoIds.end()) { // This dependent parameter group contains at least one parameter that should be @@ -466,16 +487,19 @@ void Sketch::calculateDependentParametersElements() int i = 0; for (auto geo : Geoms) { - if (!geo.geo->hasExtension(Sketcher::SolverGeometryExtension::getClassTypeId())) + if (!geo.geo->hasExtension(Sketcher::SolverGeometryExtension::getClassTypeId())) { geo.geo->setExtension(std::make_unique()); + } auto solvext = std::static_pointer_cast( geo.geo->getExtension(Sketcher::SolverGeometryExtension::getClassTypeId()).lock()); - if (GCSsys.isEmptyDiagnoseMatrix()) + if (GCSsys.isEmptyDiagnoseMatrix()) { solvext->init(SolverGeometryExtension::Dependent); - else + } + else { solvext->init(SolverGeometryExtension::Independent); + } solverExtensions[i] = solvext; i++; @@ -501,22 +525,28 @@ void Sketch::calculateDependentParametersElements() solvext->setEdge(index, SolverGeometryExtension::Dependent); break; case PointPos::start: - if (index == 0) + if (index == 0) { solvext->setStartx(SolverGeometryExtension::Dependent); - else + } + else { solvext->setStarty(SolverGeometryExtension::Dependent); + } break; case PointPos::end: - if (index == 0) + if (index == 0) { solvext->setEndx(SolverGeometryExtension::Dependent); - else + } + else { solvext->setEndy(SolverGeometryExtension::Dependent); + } break; case PointPos::mid: - if (index == 0) + if (index == 0) { solvext->setMidx(SolverGeometryExtension::Dependent); - else + } + else { solvext->setMidy(SolverGeometryExtension::Dependent); + } break; } } @@ -546,12 +576,15 @@ void Sketch::calculateDependentParametersElements() std::set>::iterator begin2, std::set>::iterator end2) { while (begin1 != end1 && begin2 != end2) { - if (*begin1 < *begin2) + if (*begin1 < *begin2) { ++begin1; - else if (*begin2 < *begin1) + } + else if (*begin2 < *begin1) { ++begin2; - else + } + else { return true; + } } return false; @@ -595,8 +628,9 @@ std::set> Sketch::getDependencyGroup(int geoI std::shared_ptr Sketch::getSolverExtension(int geoId) const { - if (geoId >= 0 && geoId < int(solverExtensions.size())) + if (geoId >= 0 && geoId < int(solverExtensions.size())) { return solverExtensions[geoId]; + } return nullptr; } @@ -707,8 +741,9 @@ int Sketch::addGeometry(const Part::Geometry* geo, bool fixed) int Sketch::addGeometry(const std::vector& geo, bool fixed) { int ret = -1; - for (std::vector::const_iterator it = geo.begin(); it != geo.end(); ++it) + for (std::vector::const_iterator it = geo.begin(); it != geo.end(); ++it) { ret = addGeometry(*it, fixed); + } return ret; } @@ -723,8 +758,9 @@ int Sketch::addGeometry(const std::vector& geo, for (it = geo.begin(), bit = blockedGeometry.begin(); it != geo.end() && bit != blockedGeometry.end(); - ++it, ++bit) + ++it, ++bit) { ret = addGeometry(*it, *bit); + } return ret; } @@ -907,8 +943,9 @@ int Sketch::addArc(const Part::GeomArcOfCircle& circleSegment, bool fixed) Geoms.push_back(def); // arcs require an ArcRules constraint for the end points - if (!fixed) + if (!fixed) { GCSsys.addConstraintArcRules(a); + } if (!fixed) { param2geoelement.emplace( @@ -1034,8 +1071,9 @@ int Sketch::addArcOfEllipse(const Part::GeomArcOfEllipse& ellipseSegment, bool f Geoms.push_back(def); // arcs require an ArcRules constraint for the end points - if (!fixed) + if (!fixed) { GCSsys.addConstraintArcOfEllipseRules(a); + } if (!fixed) { param2geoelement.emplace( @@ -1167,8 +1205,9 @@ int Sketch::addArcOfHyperbola(const Part::GeomArcOfHyperbola& hyperbolaSegment, Geoms.push_back(def); // arcs require an ArcRules constraint for the end points - if (!fixed) + if (!fixed) { GCSsys.addConstraintArcOfHyperbolaRules(a); + } if (!fixed) { param2geoelement.emplace( @@ -1291,8 +1330,9 @@ int Sketch::addArcOfParabola(const Part::GeomArcOfParabola& parabolaSegment, boo Geoms.push_back(def); // arcs require an ArcRules constraint for the end points - if (!fixed) + if (!fixed) { GCSsys.addConstraintArcOfParabolaRules(a); + } if (!fixed) { param2geoelement.emplace( @@ -1382,8 +1422,9 @@ int Sketch::addBSpline(const Part::GeomBSplineCurve& bspline, bool fixed) } } - if (countones == 1) + if (countones == 1) { weights[lastoneindex] = (lastnotone * 0.99); + } // end hack @@ -1503,10 +1544,12 @@ int Sketch::addBSpline(const Part::GeomBSplineCurve& bspline, bool fixed) // movable anyway. See #issue 0003176: Sketcher: always over-constrained when referencing // external B-Spline if (!fixed && !bs.periodic) { - if (bs.mult[0] > bs.degree) + if (bs.mult[0] > bs.degree) { GCSsys.addConstraintP2PCoincident(*(bs.poles.begin()), bs.start); - if (bs.mult[mult.size() - 1] > bs.degree) + } + if (bs.mult[mult.size() - 1] > bs.degree) { GCSsys.addConstraintP2PCoincident(*(bs.poles.end() - 1), bs.end); + } } if (!fixed) { @@ -1680,8 +1723,9 @@ std::vector Sketch::extractGeometry(bool withConstructionElemen for (std::vector::const_iterator it = Geoms.begin(); it != Geoms.end(); ++it) { auto gf = GeometryFacade::getFacade(it->geo); if ((!it->external || withExternalElements) - && (!gf->getConstruction() || withConstructionElements)) + && (!gf->getConstruction() || withConstructionElements)) { temp.push_back(it->geo->clone()); + } } return temp; @@ -1695,8 +1739,9 @@ GeoListFacade Sketch::extractGeoListFacade() const for (std::vector::const_iterator it = Geoms.begin(); it != Geoms.end(); ++it) { // GeometryFacade is the owner of this allocation auto gf = GeometryFacade::getFacade(it->geo->clone(), true); - if (!it->external) + if (!it->external) { internalGeometryCount++; + } temp.push_back(std::move(gf)); } @@ -1761,10 +1806,12 @@ Py::Tuple Sketch::getPyGeometry() const int Sketch::checkGeoId(int geoId) const { - if (geoId < 0) + if (geoId < 0) { geoId += Geoms.size();// convert negative external-geometry index to index into Geoms - if (!(geoId >= 0 && geoId < int(Geoms.size()))) + } + if (!(geoId >= 0 && geoId < int(Geoms.size()))) { throw Base::IndexError("Sketch::checkGeoId. GeoId index out range."); + } return geoId; } @@ -1812,9 +1859,10 @@ const GCS::Curve* Sketch::getGCSCurveByGeoId(int geoId) const int Sketch::addConstraint(const Constraint* constraint) { - if (Geoms.empty()) + if (Geoms.empty()) { throw Base::ValueError( "Sketch::addConstraint. Can't add constraint to a sketch with no geometry!"); + } int rtn = -1; ConstrDef c; @@ -1825,8 +1873,9 @@ int Sketch::addConstraint(const Constraint* constraint) case DistanceX: if (constraint->FirstPos == PointPos::none) {// horizontal length of a line c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -1836,20 +1885,24 @@ int Sketch::addConstraint(const Constraint* constraint) } else if (constraint->Second == GeoEnum::GeoUndef) {// point on fixed x-coordinate c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); } - rtn = addCoordinateXConstraint( - constraint->First, constraint->FirstPos, c.value, c.driving); + rtn = addCoordinateXConstraint(constraint->First, + constraint->FirstPos, + c.value, + c.driving); } else if (constraint->SecondPos != PointPos::none) {// point to point horizontal distance c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -1866,8 +1919,9 @@ int Sketch::addConstraint(const Constraint* constraint) case DistanceY: if (constraint->FirstPos == PointPos::none) {// vertical length of a line c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -1877,20 +1931,24 @@ int Sketch::addConstraint(const Constraint* constraint) } else if (constraint->Second == GeoEnum::GeoUndef) {// point on fixed y-coordinate c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); } - rtn = addCoordinateYConstraint( - constraint->First, constraint->FirstPos, c.value, c.driving); + rtn = addCoordinateYConstraint(constraint->First, + constraint->FirstPos, + c.value, + c.driving); } else if (constraint->SecondPos != PointPos::none) {// point to point vertical distance c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -1905,26 +1963,32 @@ int Sketch::addConstraint(const Constraint* constraint) } break; case Horizontal: - if (constraint->Second == GeoEnum::GeoUndef)// horizontal line + if (constraint->Second == GeoEnum::GeoUndef) {// horizontal line rtn = addHorizontalConstraint(constraint->First); - else// two points on the same horizontal line + } + else {// two points on the same horizontal line rtn = addHorizontalConstraint(constraint->First, constraint->FirstPos, constraint->Second, constraint->SecondPos); + } break; case Vertical: - if (constraint->Second == GeoEnum::GeoUndef)// vertical line + if (constraint->Second == GeoEnum::GeoUndef) {// vertical line rtn = addVerticalConstraint(constraint->First); - else// two points on the same vertical line + } + else {// two points on the same vertical line rtn = addVerticalConstraint(constraint->First, constraint->FirstPos, constraint->Second, constraint->SecondPos); + } break; case Coincident: - rtn = addPointCoincidentConstraint( - constraint->First, constraint->FirstPos, constraint->Second, constraint->SecondPos); + rtn = addPointCoincidentConstraint(constraint->First, + constraint->FirstPos, + constraint->Second, + constraint->SecondPos); break; case PointOnObject: if (Geoms[checkGeoId(constraint->Second)].type == BSpline) { @@ -1932,12 +1996,16 @@ int Sketch::addConstraint(const Constraint* constraint) // Driving doesn't make sense here Parameters.push_back(c.value); - rtn = addPointOnObjectConstraint( - constraint->First, constraint->FirstPos, constraint->Second, c.value); + rtn = addPointOnObjectConstraint(constraint->First, + constraint->FirstPos, + constraint->Second, + c.value); + } + else { + rtn = addPointOnObjectConstraint(constraint->First, + constraint->FirstPos, + constraint->Second); } - else - rtn = addPointOnObjectConstraint( - constraint->First, constraint->FirstPos, constraint->Second); break; case Parallel: rtn = addParallelConstraint(constraint->First, constraint->Second); @@ -1951,8 +2019,9 @@ int Sketch::addConstraint(const Constraint* constraint) else { // any other point-wise perpendicularity c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -1995,15 +2064,19 @@ int Sketch::addConstraint(const Constraint* constraint) if (Geoms[linegeoid].type == Line) { if (constraint->SecondPos == PointPos::none) { - rtn = addTangentLineAtBSplineKnotConstraint( - linegeoid, bsplinegeoid, knotgeoId); + rtn = addTangentLineAtBSplineKnotConstraint(linegeoid, + bsplinegeoid, + knotgeoId); isSpecialCase = true; } else if (constraint->SecondPos == PointPos::start || constraint->SecondPos == PointPos::end) { rtn = addTangentLineEndpointAtBSplineKnotConstraint( - linegeoid, constraint->SecondPos, bsplinegeoid, knotgeoId); + linegeoid, + constraint->SecondPos, + bsplinegeoid, + knotgeoId); isSpecialCase = true; } @@ -2015,8 +2088,9 @@ int Sketch::addConstraint(const Constraint* constraint) // any other point-wise tangency (endpoint-to-curve, endpoint-to-endpoint, // tangent-via-point) c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2037,8 +2111,9 @@ int Sketch::addConstraint(const Constraint* constraint) case Distance: if (constraint->SecondPos != PointPos::none) {// point to point distance c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2057,20 +2132,24 @@ int Sketch::addConstraint(const Constraint* constraint) == GeoEnum::GeoUndef) {// circle to circle, circle to arc, etc. c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); } - rtn = addDistanceConstraint( - constraint->First, constraint->Second, c.value, c.driving); + rtn = addDistanceConstraint(constraint->First, + constraint->Second, + c.value, + c.driving); } else if (constraint->Second != GeoEnum::GeoUndef) { if (constraint->FirstPos != PointPos::none) {// point to line distance c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2084,8 +2163,9 @@ int Sketch::addConstraint(const Constraint* constraint) } else {// line length c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2097,8 +2177,9 @@ int Sketch::addConstraint(const Constraint* constraint) case Angle: if (constraint->Third != GeoEnum::GeoUndef) { c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2117,8 +2198,9 @@ int Sketch::addConstraint(const Constraint* constraint) // angle between two lines (with explicit start points) else if (constraint->SecondPos != PointPos::none) { c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2133,8 +2215,9 @@ int Sketch::addConstraint(const Constraint* constraint) } else if (constraint->Second != GeoEnum::GeoUndef) {// angle between two lines c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2144,8 +2227,9 @@ int Sketch::addConstraint(const Constraint* constraint) } else if (constraint->First != GeoEnum::GeoUndef) {// orientation angle of a line c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2156,8 +2240,9 @@ int Sketch::addConstraint(const Constraint* constraint) break; case Radius: { c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2168,8 +2253,9 @@ int Sketch::addConstraint(const Constraint* constraint) } case Diameter: { c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2180,8 +2266,9 @@ int Sketch::addConstraint(const Constraint* constraint) } case Weight: { c.value = new double(constraint->getValue()); - if (c.driving) + if (c.driving) { FixParameters.push_back(c.value); + } else { Parameters.push_back(c.value); DrivenParameters.push_back(c.value); @@ -2194,19 +2281,21 @@ int Sketch::addConstraint(const Constraint* constraint) rtn = addEqualConstraint(constraint->First, constraint->Second); break; case Symmetric: - if (constraint->ThirdPos != PointPos::none) + if (constraint->ThirdPos != PointPos::none) { rtn = addSymmetricConstraint(constraint->First, constraint->FirstPos, constraint->Second, constraint->SecondPos, constraint->Third, constraint->ThirdPos); - else + } + else { rtn = addSymmetricConstraint(constraint->First, constraint->FirstPos, constraint->Second, constraint->SecondPos, constraint->Third); + } break; case InternalAlignment: switch (constraint->AlignmentType) { @@ -2239,12 +2328,15 @@ int Sketch::addConstraint(const Constraint* constraint) rtn = addInternalAlignmentParabolaFocus(constraint->First, constraint->Second); break; case BSplineControlPoint: - rtn = addInternalAlignmentBSplineControlPoint( - constraint->First, constraint->Second, constraint->InternalAlignmentIndex); + rtn = + addInternalAlignmentBSplineControlPoint(constraint->First, + constraint->Second, + constraint->InternalAlignmentIndex); break; case BSplineKnotPoint: - rtn = addInternalAlignmentKnotPoint( - constraint->First, constraint->Second, constraint->InternalAlignmentIndex); + rtn = addInternalAlignmentKnotPoint(constraint->First, + constraint->Second, + constraint->InternalAlignmentIndex); break; case ParabolaFocalAxis: rtn = addInternalAlignmentParabolaFocalDistance(constraint->First, @@ -2502,8 +2594,9 @@ int Sketch::addDistanceXConstraint(int geoId, double* value, bool driving) { geoId = checkGeoId(geoId); - if (Geoms[geoId].type != Line) + if (Geoms[geoId].type != Line) { return -1; + } GCS::Line& l = Lines[Geoms[geoId].index]; @@ -2516,8 +2609,9 @@ int Sketch::addDistanceYConstraint(int geoId, double* value, bool driving) { geoId = checkGeoId(geoId); - if (Geoms[geoId].type != Line) + if (Geoms[geoId].type != Line) { return -1; + } GCS::Line& l = Lines[Geoms[geoId].index]; @@ -2526,8 +2620,12 @@ int Sketch::addDistanceYConstraint(int geoId, double* value, bool driving) return ConstraintsCounter; } -int Sketch::addDistanceXConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, - double* value, bool driving) +int Sketch::addDistanceXConstraint(int geoId1, + PointPos pos1, + int geoId2, + PointPos pos2, + double* value, + bool driving) { geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); @@ -2547,8 +2645,12 @@ int Sketch::addDistanceXConstraint(int geoId1, PointPos pos1, int geoId2, PointP return -1; } -int Sketch::addDistanceYConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, - double* value, bool driving) +int Sketch::addDistanceYConstraint(int geoId1, + PointPos pos1, + int geoId2, + PointPos pos2, + double* value, + bool driving) { geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); @@ -2573,8 +2675,9 @@ int Sketch::addHorizontalConstraint(int geoId) { geoId = checkGeoId(geoId); - if (Geoms[geoId].type != Line) + if (Geoms[geoId].type != Line) { return -1; + } GCS::Line& l = Lines[Geoms[geoId].index]; int tag = ++ConstraintsCounter; @@ -2607,8 +2710,9 @@ int Sketch::addVerticalConstraint(int geoId) { geoId = checkGeoId(geoId); - if (Geoms[geoId].type != Line) + if (Geoms[geoId].type != Line) { return -1; + } GCS::Line& l = Lines[Geoms[geoId].index]; int tag = ++ConstraintsCounter; @@ -2660,8 +2764,9 @@ int Sketch::addParallelConstraint(int geoId1, int geoId2) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != Line || Geoms[geoId2].type != Line) + if (Geoms[geoId1].type != Line || Geoms[geoId2].type != Line) { return -1; + } GCS::Line& l1 = Lines[Geoms[geoId1].index]; GCS::Line& l2 = Lines[Geoms[geoId2].index]; @@ -2688,8 +2793,9 @@ int Sketch::addPerpendicularConstraint(int geoId1, int geoId2) GCSsys.addConstraintPerpendicular(l1, l2, tag); return ConstraintsCounter; } - else + else { std::swap(geoId1, geoId2); + } } if (Geoms[geoId1].type == Line) { @@ -2730,8 +2836,9 @@ int Sketch::addTangentConstraint(int geoId1, int geoId2) GCSsys.addConstraintPointOnLine(l2p2, l1, tag); return ConstraintsCounter; } - else + else { std::swap(geoId1, geoId2); + } } if (Geoms[geoId1].type == Line) { @@ -2817,7 +2924,8 @@ int Sketch::addTangentConstraint(int geoId1, int geoId2) return -1; } -int Sketch::addTangentLineAtBSplineKnotConstraint(int checkedlinegeoId, int checkedbsplinegeoId, +int Sketch::addTangentLineAtBSplineKnotConstraint(int checkedlinegeoId, + int checkedbsplinegeoId, int checkedknotgeoid) { GCS::BSpline& b = BSplines[Geoms[checkedbsplinegeoId].index]; @@ -2922,8 +3030,14 @@ int Sketch::addTangentLineEndpointAtBSplineKnotConstraint(int checkedlinegeoId, // geoid1, geoid2 and geoid3 as in the constraint object. // For perp-ty and tangency, angle is used to lock the direction. // angle==0 - autodetect direction. +pi/2, -pi/2 - specific direction. -int Sketch::addAngleAtPointConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, - int geoId3, PointPos pos3, double* value, ConstraintType cTyp, +int Sketch::addAngleAtPointConstraint(int geoId1, + PointPos pos1, + int geoId2, + PointPos pos2, + int geoId3, + PointPos pos3, + double* value, + ConstraintType cTyp, bool driving) { @@ -2943,8 +3057,9 @@ int Sketch::addAngleAtPointConstraint(int geoId1, PointPos pos1, int geoId2, Poi geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (avp) + if (avp) { geoId3 = checkGeoId(geoId3); + } if (Geoms[geoId1].type == Point || Geoms[geoId2].type == Point) { Base::Console().Error("addAngleAtPointConstraint: one of the curves is a point!\n"); @@ -2959,10 +3074,12 @@ int Sketch::addAngleAtPointConstraint(int geoId1, PointPos pos1, int geoId2, Poi } int pointId = -1; - if (avp) + if (avp) { pointId = getPointId(geoId3, pos3); - else if (e2e || e2c) + } + else if (e2e || e2c) { pointId = getPointId(geoId1, pos1); + } if (pointId < 0 || pointId >= int(Points.size())) { Base::Console().Error("addAngleAtPointConstraint: point index out of range.\n"); @@ -3007,19 +3124,23 @@ int Sketch::addAngleAtPointConstraint(int geoId1, PointPos pos1, int geoId2, Poi if (*value == 0.0) {// autodetect tangency internal/external (and same for perpendicularity) double angleErr = GCSsys.calculateAngleViaPoint(*crv1, *crv2, p) - angleDesire; // bring angleErr to -pi..pi - if (angleErr > M_PI) + if (angleErr > M_PI) { angleErr -= M_PI * 2; - if (angleErr < -M_PI) + } + if (angleErr < -M_PI) { angleErr += M_PI * 2; + } // the autodetector - if (fabs(angleErr) > M_PI / 2) + if (fabs(angleErr) > M_PI / 2) { angleDesire += M_PI; + } *angle = angleDesire; } - else + else { *angle = *value - angleOffset; + } } int tag = -1; @@ -3044,8 +3165,9 @@ int Sketch::addDistanceConstraint(int geoId, double* value, bool driving) { geoId = checkGeoId(geoId); - if (Geoms[geoId].type != Line) + if (Geoms[geoId].type != Line) { return -1; + } GCS::Line& l = Lines[Geoms[geoId].index]; @@ -3055,31 +3177,47 @@ int Sketch::addDistanceConstraint(int geoId, double* value, bool driving) } // point to line distance constraint -int Sketch::addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, double* value, +int Sketch::addDistanceConstraint(int geoId1, + PointPos pos1, + int geoId2, + double* value, bool driving) { geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); int pointId1 = getPointId(geoId1, pos1); - - if (Geoms[geoId2].type != Line) + if (pointId1 < 0 && pointId1 >= int(Points.size())) { return -1; + } + GCS::Point& p1 = Points[pointId1]; - if (pointId1 >= 0 && pointId1 < int(Points.size())) { - GCS::Point& p1 = Points[pointId1]; + if (Geoms[geoId2].type == Line) { GCS::Line& l2 = Lines[Geoms[geoId2].index]; int tag = ++ConstraintsCounter; GCSsys.addConstraintP2LDistance(p1, l2, value, tag, driving); return ConstraintsCounter; } - return -1; + else if (Geoms[geoId2].type == Circle) { + GCS::Circle& c2 = Circles[Geoms[geoId2].index]; + + int tag = ++ConstraintsCounter; + GCSsys.addConstraintP2CDistance(p1, c2, value, tag, driving); + return ConstraintsCounter; + } + else { + return -1; + } } // point to point distance constraint -int Sketch::addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, - double* value, bool driving) +int Sketch::addDistanceConstraint(int geoId1, + PointPos pos1, + int geoId2, + PointPos pos2, + double* value, + bool driving) { geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); @@ -3191,8 +3329,9 @@ int Sketch::addAngleConstraint(int geoId1, int geoId2, double* value, bool drivi geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != Line || Geoms[geoId2].type != Line) + if (Geoms[geoId1].type != Line || Geoms[geoId2].type != Line) { return -1; + } GCS::Line& l1 = Lines[Geoms[geoId1].index]; GCS::Line& l2 = Lines[Geoms[geoId2].index]; @@ -3203,14 +3342,19 @@ int Sketch::addAngleConstraint(int geoId1, int geoId2, double* value, bool drivi } // line to line angle constraint (with explicitly given start points) -int Sketch::addAngleConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double* value, +int Sketch::addAngleConstraint(int geoId1, + PointPos pos1, + int geoId2, + PointPos pos2, + double* value, bool driving) { geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != Line || Geoms[geoId2].type != Line) + if (Geoms[geoId1].type != Line || Geoms[geoId2].type != Line) { return -1; + } GCS::Point *l1p1 = nullptr, *l1p2 = nullptr; if (pos1 == PointPos::start) { @@ -3232,8 +3376,9 @@ int Sketch::addAngleConstraint(int geoId1, PointPos pos1, int geoId2, PointPos p l2p2 = &Points[Geoms[geoId2].startPointId]; } - if (!l1p1 || !l2p1) + if (!l1p1 || !l2p1) { return -1; + } int tag = ++ConstraintsCounter; GCSsys.addConstraintL2LAngle(*l1p1, *l1p2, *l2p1, *l2p2, value, tag, driving); @@ -3263,8 +3408,9 @@ int Sketch::addEqualConstraint(int geoId1, int geoId2) GCSsys.addConstraintEqualRadius(c1, c2, tag); return ConstraintsCounter; } - else + else { std::swap(geoId1, geoId2); + } } if (Geoms[geoId2].type == Ellipse) { @@ -3275,8 +3421,9 @@ int Sketch::addEqualConstraint(int geoId1, int geoId2) GCSsys.addConstraintEqualRadii(e1, e2, tag); return ConstraintsCounter; } - else + else { std::swap(geoId1, geoId2); + } } if (Geoms[geoId1].type == Circle) { @@ -3400,7 +3547,10 @@ int Sketch::addPointOnObjectConstraint(int geoId1, PointPos pos1, int geoId2, bo return -1; } -int Sketch::addPointOnObjectConstraint(int geoId1, PointPos pos1, int geoId2, double* pointparam, +int Sketch::addPointOnObjectConstraint(int geoId1, + PointPos pos1, + int geoId2, + double* pointparam, bool driving) { geoId1 = checkGeoId(geoId1); @@ -3433,8 +3583,9 @@ int Sketch::addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointP geoId2 = checkGeoId(geoId2); geoId3 = checkGeoId(geoId3); - if (Geoms[geoId3].type != Line) + if (Geoms[geoId3].type != Line) { return -1; + } int pointId1 = getPointId(geoId1, pos1); int pointId2 = getPointId(geoId2, pos2); @@ -3451,7 +3602,11 @@ int Sketch::addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointP return -1; } -int Sketch::addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, int geoId3, +int Sketch::addSymmetricConstraint(int geoId1, + PointPos pos1, + int geoId2, + PointPos pos2, + int geoId3, PointPos pos3) { geoId1 = checkGeoId(geoId1); @@ -3474,8 +3629,14 @@ int Sketch::addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointP return -1; } -int Sketch::addSnellsLawConstraint(int geoIdRay1, PointPos posRay1, int geoIdRay2, PointPos posRay2, - int geoIdBnd, double* value, double* secondvalue, bool driving) +int Sketch::addSnellsLawConstraint(int geoIdRay1, + PointPos posRay1, + int geoIdRay2, + PointPos posRay2, + int geoIdBnd, + double* value, + double* secondvalue, + bool driving) { geoIdRay1 = checkGeoId(geoIdRay1); @@ -3546,10 +3707,12 @@ int Sketch::addInternalAlignmentEllipseMajorDiameter(int geoId1, int geoId2) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse) + if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse) { return -1; - if (Geoms[geoId2].type != Line) + } + if (Geoms[geoId2].type != Line) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::start); int pointId2 = getPointId(geoId2, PointPos::end); @@ -3587,10 +3750,12 @@ int Sketch::addInternalAlignmentEllipseMinorDiameter(int geoId1, int geoId2) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse) + if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse) { return -1; - if (Geoms[geoId2].type != Line) + } + if (Geoms[geoId2].type != Line) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::start); int pointId2 = getPointId(geoId2, PointPos::end); @@ -3628,10 +3793,12 @@ int Sketch::addInternalAlignmentEllipseFocus1(int geoId1, int geoId2) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse) + if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse) { return -1; - if (Geoms[geoId2].type != Point) + } + if (Geoms[geoId2].type != Point) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::start); @@ -3667,10 +3834,12 @@ int Sketch::addInternalAlignmentEllipseFocus2(int geoId1, int geoId2) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse) + if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse) { return -1; - if (Geoms[geoId2].type != Point) + } + if (Geoms[geoId2].type != Point) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::start); @@ -3706,10 +3875,12 @@ int Sketch::addInternalAlignmentHyperbolaMajorDiameter(int geoId1, int geoId2) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != ArcOfHyperbola) + if (Geoms[geoId1].type != ArcOfHyperbola) { return -1; - if (Geoms[geoId2].type != Line) + } + if (Geoms[geoId2].type != Line) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::start); int pointId2 = getPointId(geoId2, PointPos::end); @@ -3737,10 +3908,12 @@ int Sketch::addInternalAlignmentHyperbolaMinorDiameter(int geoId1, int geoId2) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != ArcOfHyperbola) + if (Geoms[geoId1].type != ArcOfHyperbola) { return -1; - if (Geoms[geoId2].type != Line) + } + if (Geoms[geoId2].type != Line) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::start); int pointId2 = getPointId(geoId2, PointPos::end); @@ -3768,10 +3941,12 @@ int Sketch::addInternalAlignmentHyperbolaFocus(int geoId1, int geoId2) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != ArcOfHyperbola) + if (Geoms[geoId1].type != ArcOfHyperbola) { return -1; - if (Geoms[geoId2].type != Point) + } + if (Geoms[geoId2].type != Point) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::start); @@ -3794,10 +3969,12 @@ int Sketch::addInternalAlignmentParabolaFocus(int geoId1, int geoId2) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != ArcOfParabola) + if (Geoms[geoId1].type != ArcOfParabola) { return -1; - if (Geoms[geoId2].type != Point) + } + if (Geoms[geoId2].type != Point) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::start); @@ -3820,10 +3997,12 @@ int Sketch::addInternalAlignmentParabolaFocalDistance(int geoId1, int geoId2) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != ArcOfParabola) + if (Geoms[geoId1].type != ArcOfParabola) { return -1; - if (Geoms[geoId2].type != Line) + } + if (Geoms[geoId2].type != Line) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::start); int pointId2 = getPointId(geoId2, PointPos::end); @@ -3858,10 +4037,12 @@ int Sketch::addInternalAlignmentBSplineControlPoint(int geoId1, int geoId2, int geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != BSpline) + if (Geoms[geoId1].type != BSpline) { return -1; - if (Geoms[geoId2].type != Circle) + } + if (Geoms[geoId2].type != Circle) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::mid); @@ -3886,10 +4067,12 @@ int Sketch::addInternalAlignmentKnotPoint(int geoId1, int geoId2, int knotindex) geoId1 = checkGeoId(geoId1); geoId2 = checkGeoId(geoId2); - if (Geoms[geoId1].type != BSpline) + if (Geoms[geoId1].type != BSpline) { return -1; - if (Geoms[geoId2].type != Point) + } + if (Geoms[geoId2].type != Point) { return -1; + } int pointId1 = getPointId(geoId2, PointPos::start); @@ -4156,10 +4339,12 @@ bool Sketch::updateNonDrivingConstraints() auto pos = std::find(FixParameters.begin(), FixParameters.end(), rad); - if (pos != FixParameters.end()) + if (pos != FixParameters.end()) { (*it).constr->setValue(*((*it).value)); - else + } + else { (*it).constr->setValue(2.0 * *((*it).value)); + } } else { (*it).constr->setValue(*((*it).value)); @@ -4279,8 +4464,9 @@ int Sketch::internalSolve(std::string& solvername, int level) it != Parameters.end(); ++it, i++) { InitParameters[i] = **it; - GCSsys.addConstraintEqual( - *it, &InitParameters[i], GCS::DefaultTemporaryConstraint); + GCSsys.addConstraintEqual(*it, + &InitParameters[i], + GCS::DefaultTemporaryConstraint); } GCSsys.initSolution(); ret = GCSsys.solve(isFine); @@ -4311,19 +4497,23 @@ int Sketch::internalSolve(std::string& solvername, int level) } } - if (soltype == 3)// cleanup temporary constraints of the augmented system + if (soltype == 3) {// cleanup temporary constraints of the augmented system clearTemporaryConstraints(); + } if (valid_solution) { - if (soltype == 1) + if (soltype == 1) { Base::Console().Log("Important: the LevenbergMarquardt solver succeeded where " "the DogLeg solver had failed.\n"); - else if (soltype == 2) + } + else if (soltype == 2) { Base::Console().Log("Important: the BFGS solver succeeded where the DogLeg and " "LevenbergMarquardt solvers have failed.\n"); - else if (soltype == 3) + } + else if (soltype == 3) { Base::Console().Log("Important: the SQP solver succeeded where all single " "subsystem solvers have failed.\n"); + } if (soltype > 0) { Base::Console().Log("If you see this message please report a way of " @@ -4651,7 +4841,9 @@ void Sketch::resetInitMove() isInitMove = false; } -int Sketch::initBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& firstPoint, +int Sketch::initBSplinePieceMove(int geoId, + PointPos pos, + const Base::Vector3d& firstPoint, bool fine) { isFine = fine; @@ -4674,8 +4866,9 @@ int Sketch::initBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& GCS::BSpline& bsp = BSplines[Geoms[geoId].index]; // If spline has too few poles, just move all - if (bsp.poles.size() <= std::size_t(bsp.degree + 1)) + if (bsp.poles.size() <= std::size_t(bsp.degree + 1)) { return initMove(geoId, pos, fine); + } // Find the closest knot auto partBsp = static_cast(Geoms[geoId].geo); @@ -4690,8 +4883,9 @@ int Sketch::initBSplinePieceMove(int geoId, PointPos pos, const Base::Vector3d& size_t idx = 0; // skipping the first knot for adjustment // TODO: ensure this works for periodic as well - for (size_t i = 1; i < bsp.mult.size() && knots[i] != *upperknot; ++i) + for (size_t i = 1; i < bsp.mult.size() && knots[i] != *upperknot; ++i) { idx += bsp.mult[i]; + } MoveParameters.resize(2 * (bsp.degree + 1));// x[idx],y[idx],x[idx+1],y[idx+1],... @@ -4721,8 +4915,9 @@ int Sketch::movePoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool rela geoId = checkGeoId(geoId); // don't try to move sketches that contain conflicting constraints - if (hasConflicts()) + if (hasConflicts()) { return -1; + } if (!isInitMove) { initMove(geoId, pos); @@ -4846,8 +5041,9 @@ int Sketch::setDatum(int /*constrId*/, double /*value*/) int Sketch::getPointId(int geoId, PointPos pos) const { // do a range check first - if (geoId < 0 || geoId >= (int)Geoms.size()) + if (geoId < 0 || geoId >= (int)Geoms.size()) { return -1; + } switch (pos) { case PointPos::start: return Geoms[geoId].startPointId; @@ -4865,8 +5061,9 @@ Base::Vector3d Sketch::getPoint(int geoId, PointPos pos) const { geoId = checkGeoId(geoId); int pointId = getPointId(geoId, pos); - if (pointId != -1) + if (pointId != -1) { return Base::Vector3d(*Points[pointId].x, *Points[pointId].y, 0); + } return Base::Vector3d(); } @@ -4904,11 +5101,13 @@ TopoShape Sketch::toShape() const if (it->type != Point) { auto shape = it->geo->toShape(); - if (!shape.IsNull()) + if (!shape.IsNull()) { edge_list.push_back(TopoDS::Edge(shape)); + } } - else + else { vertex_list.push_back(TopoDS::Vertex(it->geo->toShape())); + } } } @@ -4967,11 +5166,13 @@ TopoShape Sketch::toShape() const BRep_Builder builder; TopoDS_Compound comp; builder.MakeCompound(comp); - for (std::list::iterator wt = wires.begin(); wt != wires.end(); ++wt) + for (std::list::iterator wt = wires.begin(); wt != wires.end(); ++wt) { builder.Add(comp, *wt); + } for (std::list::iterator wt = vertex_list.begin(); wt != vertex_list.end(); - ++wt) + ++wt) { builder.Add(comp, *wt); + } result.setShape(comp); } #endif diff --git a/src/Mod/Sketcher/App/planegcs/Constraints.cpp b/src/Mod/Sketcher/App/planegcs/Constraints.cpp index b56e19d1c7..1f1833c4d2 100644 --- a/src/Mod/Sketcher/App/planegcs/Constraints.cpp +++ b/src/Mod/Sketcher/App/planegcs/Constraints.cpp @@ -40,13 +40,13 @@ namespace GCS /////////////////////////////////////// Constraint::Constraint() - : origpvec(0), - pvec(0), - scale(1.), - tag(0), - pvecChangedFlag(true), - driving(true), - internalAlignment(Alignment::NoInternalAlignment) + : origpvec(0) + , pvec(0) + , scale(1.) + , tag(0) + , pvecChangedFlag(true) + , driving(true) + , internalAlignment(Alignment::NoInternalAlignment) {} void Constraint::redirectParams(const MAP_pD_pD& redirectionmap) @@ -54,8 +54,9 @@ void Constraint::redirectParams(const MAP_pD_pD& redirectionmap) int i = 0; for (VEC_pD::iterator param = origpvec.begin(); param != origpvec.end(); ++param, i++) { MAP_pD_pD::const_iterator it = redirectionmap.find(*param); - if (it != redirectionmap.end()) + if (it != redirectionmap.end()) { pvec[i] = it->second; + } } pvecChangedFlag = true; } @@ -133,10 +134,12 @@ double ConstraintEqual::error() double ConstraintEqual::grad(double* param) { double deriv = 0.; - if (param == param1()) + if (param == param1()) { deriv += 1; - if (param == param2()) + } + if (param == param2()) { deriv += -1; + } return scale * deriv; } @@ -144,10 +147,11 @@ double ConstraintEqual::grad(double* param) // -------------------------------------------------------- // Weighted Linear Combination ConstraintWeightedLinearCombination::ConstraintWeightedLinearCombination( - size_t givennumpoles, const std::vector& givenpvec, + size_t givennumpoles, + const std::vector& givenpvec, const std::vector& givenfactors) - : factors(givenfactors), - numpoles(givennumpoles) + : factors(givenfactors) + , numpoles(givennumpoles) { pvec = givenpvec; assert(pvec.size() == 2 * numpoles + 1); @@ -244,8 +248,9 @@ void ConstraintCenterOfGravity::rescale(double coef) double ConstraintCenterOfGravity::error() { double sum = 0; - for (size_t i = 0; i < numpoints; ++i) + for (size_t i = 0; i < numpoints; ++i) { sum += *pointat(i) * weights[i]; + } return scale * (*thecenter() - sum); } @@ -253,12 +258,15 @@ double ConstraintCenterOfGravity::error() double ConstraintCenterOfGravity::grad(double* param) { double deriv = 0.; - if (param == thecenter()) + if (param == thecenter()) { deriv = 1; + } - for (size_t i = 0; i < numpoints; ++i) - if (param == pointat(i)) + for (size_t i = 0; i < numpoints; ++i) { + if (param == pointat(i)) { deriv = -weights[i]; + } + } return scale * deriv; } @@ -280,17 +288,22 @@ ConstraintSlopeAtBSplineKnot::ConstraintSlopeAtBSplineKnot(BSpline& b, Line& l, // `startpole` is the first pole affecting the knot with `knotindex` size_t startpole = 0; // See `System::addConstraintInternalAlignmentKnotPoint()` for some elaboration - for (size_t j = 1; j <= knotindex; ++j) + for (size_t j = 1; j <= knotindex; ++j) { startpole += b.mult[j]; - if (!b.periodic && startpole >= b.poles.size()) + } + if (!b.periodic && startpole >= b.poles.size()) { startpole = b.poles.size() - 1; + } - for (size_t i = 0; i < numpoles; ++i) + for (size_t i = 0; i < numpoles; ++i) { pvec.push_back(b.poles[(startpole + i) % b.poles.size()].x); - for (size_t i = 0; i < numpoles; ++i) + } + for (size_t i = 0; i < numpoles; ++i) { pvec.push_back(b.poles[(startpole + i) % b.poles.size()].y); - for (size_t i = 0; i < numpoles; ++i) + } + for (size_t i = 0; i < numpoles; ++i) { pvec.push_back(b.weights[(startpole + i) % b.weights.size()]); + } pvec.push_back(l.p1.x); pvec.push_back(l.p1.y); pvec.push_back(l.p2.x); @@ -301,9 +314,10 @@ ConstraintSlopeAtBSplineKnot::ConstraintSlopeAtBSplineKnot(BSpline& b, Line& l, factors.resize(numpoles); slopefactors.resize(numpoles); for (size_t i = 0; i < numpoles + 1; ++i) { - tempfactors[i] = - b.getLinCombFactor( - *(b.knots[knotindex]), startpole + b.degree, startpole + i, b.degree - 1) + tempfactors[i] = b.getLinCombFactor(*(b.knots[knotindex]), + startpole + b.degree, + startpole + i, + b.degree - 1) / (b.flattenedknots[startpole + b.degree + i] - b.flattenedknots[startpole + i]); } for (size_t i = 0; i < numpoles; ++i) { @@ -481,7 +495,9 @@ double ConstraintSlopeAtBSplineKnot::grad(double* param) // -------------------------------------------------------- // Point On BSpline -ConstraintPointOnBSpline::ConstraintPointOnBSpline(double* point, double* initparam, int coordidx, +ConstraintPointOnBSpline::ConstraintPointOnBSpline(double* point, + double* initparam, + int coordidx, BSpline& b) : bsp(b) { @@ -495,16 +511,20 @@ ConstraintPointOnBSpline::ConstraintPointOnBSpline(double* point, double* initpa setStartPole(*initparam); for (size_t i = 0; i < b.poles.size(); ++i) { - if (coordidx == 0) + if (coordidx == 0) { pvec.push_back(b.poles[i].x); - else + } + else { pvec.push_back(b.poles[i].y); + } } - for (size_t i = 0; i < b.weights.size(); ++i) + for (size_t i = 0; i < b.weights.size(); ++i) { pvec.push_back(b.weights[i]); + } - if (bsp.flattenedknots.empty()) + if (bsp.flattenedknots.empty()) { bsp.setupFlattenedKnots(); + } origpvec = pvec; rescale(); @@ -521,10 +541,12 @@ void ConstraintPointOnBSpline::setStartPole(double u) // for example in GCS and slope at knot // find relevant poles startpole = 0; - for (size_t j = 1; j < bsp.mult.size() && *(bsp.knots[j]) <= u; ++j) + for (size_t j = 1; j < bsp.mult.size() && *(bsp.knots[j]) <= u; ++j) { startpole += bsp.mult[j]; - if (!bsp.periodic && startpole >= bsp.poles.size()) + } + if (!bsp.periodic && startpole >= bsp.poles.size()) { startpole = bsp.poles.size() - bsp.degree - 1; + } } void ConstraintPointOnBSpline::rescale(double coef) @@ -535,22 +557,31 @@ void ConstraintPointOnBSpline::rescale(double coef) double ConstraintPointOnBSpline::error() { if (*theparam() < bsp.flattenedknots[startpole + bsp.degree] - || *theparam() > bsp.flattenedknots[startpole + bsp.degree + 1]) + || *theparam() > bsp.flattenedknots[startpole + bsp.degree + 1]) { setStartPole(*theparam()); + } double sum = 0; double wsum = 0; // TODO: maybe make it global so it doesn't have to be created every time VEC_D d(numpoints); - for (size_t i = 0; i < numpoints; ++i) + for (size_t i = 0; i < numpoints; ++i) { d[i] = *poleat(i) * *weightat(i); - sum = BSpline::splineValue( - *theparam(), startpole + bsp.degree, bsp.degree, d, bsp.flattenedknots); - for (size_t i = 0; i < numpoints; ++i) + } + sum = BSpline::splineValue(*theparam(), + startpole + bsp.degree, + bsp.degree, + d, + bsp.flattenedknots); + for (size_t i = 0; i < numpoints; ++i) { d[i] = *weightat(i); - wsum = BSpline::splineValue( - *theparam(), startpole + bsp.degree, bsp.degree, d, bsp.flattenedknots); + } + wsum = BSpline::splineValue(*theparam(), + startpole + bsp.degree, + bsp.degree, + d, + bsp.flattenedknots); // TODO: Change the poles as the point moves between pieces @@ -562,10 +593,14 @@ double ConstraintPointOnBSpline::grad(double* gcsparam) double deriv = 0.; if (gcsparam == thepoint()) { VEC_D d(numpoints); - for (size_t i = 0; i < numpoints; ++i) + for (size_t i = 0; i < numpoints; ++i) { d[i] = *weightat(i); - double wsum = BSpline::splineValue( - *theparam(), startpole + bsp.degree, bsp.degree, d, bsp.flattenedknots); + } + double wsum = BSpline::splineValue(*theparam(), + startpole + bsp.degree, + bsp.degree, + d, + bsp.flattenedknots); deriv += wsum; } @@ -576,15 +611,21 @@ double ConstraintPointOnBSpline::grad(double* gcsparam) / (bsp.flattenedknots[startpole + i + bsp.degree] - bsp.flattenedknots[startpole + i]); } - double slopevalue = BSpline::splineValue( - *theparam(), startpole + bsp.degree, bsp.degree - 1, d, bsp.flattenedknots); + double slopevalue = BSpline::splineValue(*theparam(), + startpole + bsp.degree, + bsp.degree - 1, + d, + bsp.flattenedknots); for (size_t i = 1; i < numpoints; ++i) { d[i - 1] = (*weightat(i) - *weightat(i - 1)) / (bsp.flattenedknots[startpole + i + bsp.degree] - bsp.flattenedknots[startpole + i]); } - double wslopevalue = BSpline::splineValue( - *theparam(), startpole + bsp.degree, bsp.degree - 1, d, bsp.flattenedknots); + double wslopevalue = BSpline::splineValue(*theparam(), + startpole + bsp.degree, + bsp.degree - 1, + d, + bsp.flattenedknots); deriv += (*thepoint() * wslopevalue - slopevalue) * bsp.degree; } @@ -632,12 +673,15 @@ double ConstraintDifference::error() double ConstraintDifference::grad(double* param) { double deriv = 0.; - if (param == param1()) + if (param == param1()) { deriv += -1; - if (param == param2()) + } + if (param == param2()) { deriv += 1; - if (param == difference()) + } + if (param == difference()) { deriv += -1; + } return scale * deriv; } @@ -681,17 +725,22 @@ double ConstraintP2PDistance::grad(double* param) double dx = (*p1x() - *p2x()); double dy = (*p1y() - *p2y()); double d = sqrt(dx * dx + dy * dy); - if (param == p1x()) + if (param == p1x()) { deriv += dx / d; - if (param == p1y()) + } + if (param == p1y()) { deriv += dy / d; - if (param == p2x()) + } + if (param == p2x()) { deriv += -dx / d; - if (param == p2y()) + } + if (param == p2y()) { deriv += -dy / d; + } } - if (param == distance()) + if (param == distance()) { deriv += -1.; + } return scale * deriv; } @@ -702,31 +751,37 @@ double ConstraintP2PDistance::maxStep(MAP_pD_D& dir, double lim) // distance() >= 0 it = dir.find(distance()); if (it != dir.end()) { - if (it->second < 0.) + if (it->second < 0.) { lim = std::min(lim, -(*distance()) / it->second); + } } // restrict actual distance change double ddx = 0., ddy = 0.; it = dir.find(p1x()); - if (it != dir.end()) + if (it != dir.end()) { ddx += it->second; + } it = dir.find(p1y()); - if (it != dir.end()) + if (it != dir.end()) { ddy += it->second; + } it = dir.find(p2x()); - if (it != dir.end()) + if (it != dir.end()) { ddx -= it->second; + } it = dir.find(p2y()); - if (it != dir.end()) + if (it != dir.end()) { ddy -= it->second; + } double dd = sqrt(ddx * ddx + ddy * ddy); double dist = *distance(); if (dd > dist) { double dx = (*p1x() - *p2x()); double dy = (*p1y() - *p2y()); double d = sqrt(dx * dx + dy * dy); - if (dd > d) + if (dd > d) { lim = std::min(lim, std::max(d, dist) / dd); + } } return lim; } @@ -782,17 +837,22 @@ double ConstraintP2PAngle::grad(double* param) double r2 = dx * dx + dy * dy; dx = -y / r2; dy = x / r2; - if (param == p1x()) + if (param == p1x()) { deriv += (-ca * dx + sa * dy); - if (param == p1y()) + } + if (param == p1y()) { deriv += (-sa * dx - ca * dy); - if (param == p2x()) + } + if (param == p2x()) { deriv += (ca * dx - sa * dy); - if (param == p2y()) + } + if (param == p2y()) { deriv += (sa * dx + ca * dy); + } } - if (param == angle()) + if (param == angle()) { deriv += -1; + } return scale * deriv; } @@ -803,8 +863,9 @@ double ConstraintP2PAngle::maxStep(MAP_pD_D& dir, double lim) MAP_pD_D::iterator it = dir.find(angle()); if (it != dir.end()) { double step = std::abs(it->second); - if (step > M_PI / 18.0) + if (step > M_PI / 18.0) { lim = std::min(lim, (M_PI / 18.0) / step); + } } return lim; } @@ -864,23 +925,31 @@ double ConstraintP2LDistance::grad(double* param) double d2 = dx * dx + dy * dy; double d = sqrt(d2); double area = -x0 * dy + y0 * dx + x1 * y2 - x2 * y1; - if (param == p0x()) + if (param == p0x()) { deriv += (y1 - y2) / d; - if (param == p0y()) + } + if (param == p0y()) { deriv += (x2 - x1) / d; - if (param == p1x()) + } + if (param == p1x()) { deriv += ((y2 - y0) * d + (dx / d) * area) / d2; - if (param == p1y()) + } + if (param == p1y()) { deriv += ((x0 - x2) * d + (dy / d) * area) / d2; - if (param == p2x()) + } + if (param == p2x()) { deriv += ((y0 - y1) * d - (dx / d) * area) / d2; - if (param == p2y()) + } + if (param == p2y()) { deriv += ((x1 - x0) * d - (dy / d) * area) / d2; - if (area < 0) + } + if (area < 0) { deriv *= -1; + } } - if (param == distance()) + if (param == distance()) { deriv += -1; + } return scale * deriv; } @@ -891,31 +960,38 @@ double ConstraintP2LDistance::maxStep(MAP_pD_D& dir, double lim) // distance() >= 0 it = dir.find(distance()); if (it != dir.end()) { - if (it->second < 0.) + if (it->second < 0.) { lim = std::min(lim, -(*distance()) / it->second); + } } // restrict actual area change double darea = 0.; double x0 = *p0x(), x1 = *p1x(), x2 = *p2x(); double y0 = *p0y(), y1 = *p1y(), y2 = *p2y(); it = dir.find(p0x()); - if (it != dir.end()) + if (it != dir.end()) { darea += (y1 - y2) * it->second; + } it = dir.find(p0y()); - if (it != dir.end()) + if (it != dir.end()) { darea += (x2 - x1) * it->second; + } it = dir.find(p1x()); - if (it != dir.end()) + if (it != dir.end()) { darea += (y2 - y0) * it->second; + } it = dir.find(p1y()); - if (it != dir.end()) + if (it != dir.end()) { darea += (x0 - x2) * it->second; + } it = dir.find(p2x()); - if (it != dir.end()) + if (it != dir.end()) { darea += (y0 - y1) * it->second; + } it = dir.find(p2y()); - if (it != dir.end()) + if (it != dir.end()) { darea += (x1 - x0) * it->second; + } darea = std::abs(darea); if (darea > 0.) { @@ -924,8 +1000,9 @@ double ConstraintP2LDistance::maxStep(MAP_pD_D& dir, double lim) double area = 0.3 * (*distance()) * sqrt(dx * dx + dy * dy); if (darea > area) { area = std::max(area, 0.3 * std::abs(-x0 * dy + y0 * dx + x1 * y2 - x2 * y1)); - if (darea > area) + if (darea > area) { lim = std::min(lim, area / darea); + } } } return lim; @@ -995,18 +1072,24 @@ double ConstraintPointOnLine::grad(double* param) double d2 = dx * dx + dy * dy; double d = sqrt(d2); double area = -x0 * dy + y0 * dx + x1 * y2 - x2 * y1; - if (param == p0x()) + if (param == p0x()) { deriv += (y1 - y2) / d; - if (param == p0y()) + } + if (param == p0y()) { deriv += (x2 - x1) / d; - if (param == p1x()) + } + if (param == p1x()) { deriv += ((y2 - y0) * d + (dx / d) * area) / d2; - if (param == p1y()) + } + if (param == p1y()) { deriv += ((x0 - x2) * d + (dy / d) * area) / d2; - if (param == p2x()) + } + if (param == p2x()) { deriv += ((y0 - y1) * d - (dx / d) * area) / d2; - if (param == p2y()) + } + if (param == p2y()) { deriv += ((x1 - x0) * d - (dy / d) * area) / d2; + } } return scale * deriv; } @@ -1064,10 +1147,12 @@ void ConstraintPointOnPerpBisector::errorgrad(double* err, double* grad, double* double projd2, dprojd2; projd2 = d2.scalarProd(D, &dprojd2); - if (err) + if (err) { *err = projd1 + projd2; - if (grad) + } + if (grad) { *grad = dprojd1 + dprojd2; + } } double ConstraintPointOnPerpBisector::error() @@ -1080,8 +1165,9 @@ double ConstraintPointOnPerpBisector::error() double ConstraintPointOnPerpBisector::grad(double* param) { // first of all, check that we need to compute anything. - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -1132,23 +1218,31 @@ double ConstraintParallel::error() double ConstraintParallel::grad(double* param) { double deriv = 0.; - if (param == l1p1x()) + if (param == l1p1x()) { deriv += (*l2p1y() - *l2p2y());// = dy2 - if (param == l1p2x()) + } + if (param == l1p2x()) { deriv += -(*l2p1y() - *l2p2y());// = -dy2 - if (param == l1p1y()) + } + if (param == l1p1y()) { deriv += -(*l2p1x() - *l2p2x());// = -dx2 - if (param == l1p2y()) + } + if (param == l1p2y()) { deriv += (*l2p1x() - *l2p2x());// = dx2 + } - if (param == l2p1x()) + if (param == l2p1x()) { deriv += -(*l1p1y() - *l1p2y());// = -dy1 - if (param == l2p2x()) + } + if (param == l2p2x()) { deriv += (*l1p1y() - *l1p2y());// = dy1 - if (param == l2p1y()) + } + if (param == l2p1y()) { deriv += (*l1p1x() - *l1p2x());// = dx1 - if (param == l2p2y()) + } + if (param == l2p2y()) { deriv += -(*l1p1x() - *l1p2x());// = -dx1 + } return scale * deriv; } @@ -1210,23 +1304,31 @@ double ConstraintPerpendicular::error() double ConstraintPerpendicular::grad(double* param) { double deriv = 0.; - if (param == l1p1x()) + if (param == l1p1x()) { deriv += (*l2p1x() - *l2p2x());// = dx2 - if (param == l1p2x()) + } + if (param == l1p2x()) { deriv += -(*l2p1x() - *l2p2x());// = -dx2 - if (param == l1p1y()) + } + if (param == l1p1y()) { deriv += (*l2p1y() - *l2p2y());// = dy2 - if (param == l1p2y()) + } + if (param == l1p2y()) { deriv += -(*l2p1y() - *l2p2y());// = -dy2 + } - if (param == l2p1x()) + if (param == l2p1x()) { deriv += (*l1p1x() - *l1p2x());// = dx1 - if (param == l2p2x()) + } + if (param == l2p2x()) { deriv += -(*l1p1x() - *l1p2x());// = -dx1 - if (param == l2p1y()) + } + if (param == l2p1y()) { deriv += (*l1p1y() - *l1p2y());// = dy1 - if (param == l2p2y()) + } + if (param == l2p2y()) { deriv += -(*l1p1y() - *l1p2y());// = -dy1 + } return scale * deriv; } @@ -1249,7 +1351,10 @@ ConstraintL2LAngle::ConstraintL2LAngle(Line& l1, Line& l2, double* a) rescale(); } -ConstraintL2LAngle::ConstraintL2LAngle(Point& l1p1, Point& l1p2, Point& l2p1, Point& l2p2, +ConstraintL2LAngle::ConstraintL2LAngle(Point& l1p1, + Point& l1p2, + Point& l2p1, + Point& l2p2, double* a) { pvec.push_back(l1p1.x); @@ -1296,14 +1401,18 @@ double ConstraintL2LAngle::grad(double* param) double dx1 = (*l1p2x() - *l1p1x()); double dy1 = (*l1p2y() - *l1p1y()); double r2 = dx1 * dx1 + dy1 * dy1; - if (param == l1p1x()) + if (param == l1p1x()) { deriv += -dy1 / r2; - if (param == l1p1y()) + } + if (param == l1p1y()) { deriv += dx1 / r2; - if (param == l1p2x()) + } + if (param == l1p2x()) { deriv += dy1 / r2; - if (param == l1p2y()) + } + if (param == l1p2y()) { deriv += -dx1 / r2; + } } if (param == l2p1x() || param == l2p1y() || param == l2p2x() || param == l2p2y()) { double dx1 = (*l1p2x() - *l1p1x()); @@ -1318,17 +1427,22 @@ double ConstraintL2LAngle::grad(double* param) double r2 = dx2 * dx2 + dy2 * dy2; dx2 = -y2 / r2; dy2 = x2 / r2; - if (param == l2p1x()) + if (param == l2p1x()) { deriv += (-ca * dx2 + sa * dy2); - if (param == l2p1y()) + } + if (param == l2p1y()) { deriv += (-sa * dx2 - ca * dy2); - if (param == l2p2x()) + } + if (param == l2p2x()) { deriv += (ca * dx2 - sa * dy2); - if (param == l2p2y()) + } + if (param == l2p2y()) { deriv += (sa * dx2 + ca * dy2); + } } - if (param == angle()) + if (param == angle()) { deriv += -1; + } return scale * deriv; } @@ -1339,8 +1453,9 @@ double ConstraintL2LAngle::maxStep(MAP_pD_D& dir, double lim) MAP_pD_D::iterator it = dir.find(angle()); if (it != dir.end()) { double step = std::abs(it->second); - if (step > M_PI / 18.0) + if (step > M_PI / 18.0) { lim = std::min(lim, (M_PI / 18.0) / step); + } } return lim; } @@ -1362,7 +1477,9 @@ ConstraintMidpointOnLine::ConstraintMidpointOnLine(Line& l1, Line& l2) rescale(); } -ConstraintMidpointOnLine::ConstraintMidpointOnLine(Point& l1p1, Point& l1p2, Point& l2p1, +ConstraintMidpointOnLine::ConstraintMidpointOnLine(Point& l1p1, + Point& l1p2, + Point& l2p1, Point& l2p2) { pvec.push_back(l1p1.x); @@ -1418,22 +1535,30 @@ double ConstraintMidpointOnLine::grad(double* param) double d2 = dx * dx + dy * dy; double d = sqrt(d2); double area = -x0 * dy + y0 * dx + x1 * y2 - x2 * y1; - if (param == l1p1x()) + if (param == l1p1x()) { deriv += (y1 - y2) / (2 * d); - if (param == l1p1y()) + } + if (param == l1p1y()) { deriv += (x2 - x1) / (2 * d); - if (param == l1p2x()) + } + if (param == l1p2x()) { deriv += (y1 - y2) / (2 * d); - if (param == l1p2y()) + } + if (param == l1p2y()) { deriv += (x2 - x1) / (2 * d); - if (param == l2p1x()) + } + if (param == l2p1x()) { deriv += ((y2 - y0) * d + (dx / d) * area) / d2; - if (param == l2p1y()) + } + if (param == l2p1y()) { deriv += ((x0 - x2) * d + (dy / d) * area) / d2; - if (param == l2p2x()) + } + if (param == l2p2x()) { deriv += ((y0 - y1) * d - (dx / d) * area) / d2; - if (param == l2p2y()) + } + if (param == l2p2y()) { deriv += ((x1 - x0) * d - (dy / d) * area) / d2; + } } return scale * deriv; } @@ -1441,7 +1566,10 @@ double ConstraintMidpointOnLine::grad(double* param) // -------------------------------------------------------- // TangentCircumf -ConstraintTangentCircumf::ConstraintTangentCircumf(Point& p1, Point& p2, double* rad1, double* rad2, +ConstraintTangentCircumf::ConstraintTangentCircumf(Point& p1, + Point& p2, + double* rad1, + double* rad2, bool internal_) { internal = internal_; @@ -1469,10 +1597,12 @@ double ConstraintTangentCircumf::error() { double dx = (*c1x() - *c2x()); double dy = (*c1y() - *c2y()); - if (internal) + if (internal) { return scale * (sqrt(dx * dx + dy * dy) - std::abs(*r1() - *r2())); - else + } + else { return scale * (sqrt(dx * dx + dy * dy) - (*r1() + *r2())); + } } double ConstraintTangentCircumf::grad(double* param) @@ -1483,25 +1613,33 @@ double ConstraintTangentCircumf::grad(double* param) double dx = (*c1x() - *c2x()); double dy = (*c1y() - *c2y()); double d = sqrt(dx * dx + dy * dy); - if (param == c1x()) + if (param == c1x()) { deriv += dx / d; - if (param == c1y()) + } + if (param == c1y()) { deriv += dy / d; - if (param == c2x()) + } + if (param == c2x()) { deriv += -dx / d; - if (param == c2y()) + } + if (param == c2y()) { deriv += -dy / d; + } if (internal) { - if (param == r1()) + if (param == r1()) { deriv += (*r1() > *r2()) ? -1 : 1; - if (param == r2()) + } + if (param == r2()) { deriv += (*r1() > *r2()) ? 1 : -1; + } } else { - if (param == r1()) + if (param == r1()) { deriv += -1; - if (param == r2()) + } + if (param == r2()) { deriv += -1; + } } } return scale * deriv; @@ -1563,34 +1701,41 @@ double ConstraintPointOnEllipse::grad(double* param) double Y_F1 = *f1y(); double b = *rmin(); - if (param == p1x()) + if (param == p1x()) { deriv += (X_0 - X_F1) / sqrt(pow(X_0 - X_F1, 2) + pow(Y_0 - Y_F1, 2)) + (X_0 + X_F1 - 2 * X_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == p1y()) + } + if (param == p1y()) { deriv += (Y_0 - Y_F1) / sqrt(pow(X_0 - X_F1, 2) + pow(Y_0 - Y_F1, 2)) + (Y_0 + Y_F1 - 2 * Y_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == f1x()) + } + if (param == f1x()) { deriv += -(X_0 - X_F1) / sqrt(pow(X_0 - X_F1, 2) + pow(Y_0 - Y_F1, 2)) - 2 * (X_F1 - X_c) / sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) + (X_0 + X_F1 - 2 * X_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == f1y()) + } + if (param == f1y()) { deriv += -(Y_0 - Y_F1) / sqrt(pow(X_0 - X_F1, 2) + pow(Y_0 - Y_F1, 2)) - 2 * (Y_F1 - Y_c) / sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) + (Y_0 + Y_F1 - 2 * Y_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == cx()) + } + if (param == cx()) { deriv += 2 * (X_F1 - X_c) / sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) - 2 * (X_0 + X_F1 - 2 * X_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == cy()) + } + if (param == cy()) { deriv += 2 * (Y_F1 - Y_c) / sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) - 2 * (Y_0 + Y_F1 - 2 * Y_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == rmin()) + } + if (param == rmin()) { deriv += -2 * b / sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)); + } } return scale * deriv; } @@ -1633,8 +1778,9 @@ void ConstraintEllipseTangentLine::errorgrad(double* err, double* grad, double* // DeepSOIC equation // http://forum.freecad.org/viewtopic.php?f=10&t=7520&start=140 - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } DeriVector2 p1(l.p1, param); DeriVector2 p2(l.p2, param); DeriVector2 f1(e.focus1, param); @@ -1656,10 +1802,12 @@ void ConstraintEllipseTangentLine::errorgrad(double* err, double* grad, double* double radmaj, dradmaj; radmaj = e.getRadMaj(c, f1, *e.radmin, dradmin, dradmaj); - if (err) + if (err) { *err = distF1mF2 - 2 * radmaj; - if (grad) + } + if (grad) { *grad = ddistF1mF2 - 2 * dradmaj; + } } double ConstraintEllipseTangentLine::error() @@ -1672,8 +1820,9 @@ double ConstraintEllipseTangentLine::error() double ConstraintEllipseTangentLine::grad(double* param) { // first of all, check that we need to compute anything. - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -1702,7 +1851,9 @@ double ConstraintEllipseTangentLine::grad(double* param) // -------------------------------------------------------- // ConstraintInternalAlignmentPoint2Ellipse ConstraintInternalAlignmentPoint2Ellipse::ConstraintInternalAlignmentPoint2Ellipse( - Ellipse& e, Point& p1, InternalAlignmentType alignmentType) + Ellipse& e, + Point& p1, + InternalAlignmentType alignmentType) { this->p = p1; pvec.push_back(p.x); @@ -1737,8 +1888,9 @@ void ConstraintInternalAlignmentPoint2Ellipse::rescale(double coef) void ConstraintInternalAlignmentPoint2Ellipse::errorgrad(double* err, double* grad, double* param) { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } // todo: prefill only what's needed, not everything @@ -1789,10 +1941,12 @@ void ConstraintInternalAlignmentPoint2Ellipse::errorgrad(double* err, double* gr // shouldn't happen poa = pv;// align to the point itself, doing nothing essentially } - if (err) + if (err) { *err = by_y_not_by_x ? pv.y - poa.y : pv.x - poa.x; - if (grad) + } + if (grad) { *grad = by_y_not_by_x ? pv.dy - poa.dy : pv.dx - poa.dx; + } } double ConstraintInternalAlignmentPoint2Ellipse::error() @@ -1805,8 +1959,9 @@ double ConstraintInternalAlignmentPoint2Ellipse::error() double ConstraintInternalAlignmentPoint2Ellipse::grad(double* param) { // first of all, check that we need to compute anything. - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -1835,7 +1990,9 @@ double ConstraintInternalAlignmentPoint2Ellipse::grad(double* param) // -------------------------------------------------------- // ConstraintInternalAlignmentPoint2Hyperbola ConstraintInternalAlignmentPoint2Hyperbola::ConstraintInternalAlignmentPoint2Hyperbola( - Hyperbola& e, Point& p1, InternalAlignmentType alignmentType) + Hyperbola& e, + Point& p1, + InternalAlignmentType alignmentType) { this->p = p1; pvec.push_back(p.x); @@ -1870,8 +2027,9 @@ void ConstraintInternalAlignmentPoint2Hyperbola::rescale(double coef) void ConstraintInternalAlignmentPoint2Hyperbola::errorgrad(double* err, double* grad, double* param) { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } // todo: prefill only what's needed, not everything @@ -1927,10 +2085,12 @@ void ConstraintInternalAlignmentPoint2Hyperbola::errorgrad(double* err, double* poa = pv;// align to the point itself, doing nothing essentially } - if (err) + if (err) { *err = by_y_not_by_x ? pv.y - poa.y : pv.x - poa.x; - if (grad) + } + if (grad) { *grad = by_y_not_by_x ? pv.dy - poa.dy : pv.dx - poa.dx; + } } double ConstraintInternalAlignmentPoint2Hyperbola::error() @@ -1943,8 +2103,9 @@ double ConstraintInternalAlignmentPoint2Hyperbola::error() double ConstraintInternalAlignmentPoint2Hyperbola::grad(double* param) { // first of all, check that we need to compute anything. - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -1987,16 +2148,19 @@ void ConstraintEqualMajorAxesConic::rescale(double coef) void ConstraintEqualMajorAxesConic::errorgrad(double* err, double* grad, double* param) { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } double a1, da1; a1 = e1->getRadMaj(param, da1); double a2, da2; a2 = e2->getRadMaj(param, da2); - if (err) + if (err) { *err = a2 - a1; - if (grad) + } + if (grad) { *grad = da2 - da1; + } } double ConstraintEqualMajorAxesConic::error() @@ -2009,8 +2173,9 @@ double ConstraintEqualMajorAxesConic::error() double ConstraintEqualMajorAxesConic::grad(double* param) { // first of all, check that we need to compute anything. - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -2050,8 +2215,9 @@ void ConstraintEqualFocalDistance::rescale(double coef) void ConstraintEqualFocalDistance::errorgrad(double* err, double* grad, double* param) { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } DeriVector2 focus1(this->e1->focus1, param); DeriVector2 vertex1(this->e1->vertex, param); @@ -2071,10 +2237,12 @@ void ConstraintEqualFocalDistance::errorgrad(double* err, double* grad, double* focal2 = focalvect2.length(dfocal2); - if (err) + if (err) { *err = focal2 - focal1; - if (grad) + } + if (grad) { *grad = dfocal2 - dfocal1; + } } double ConstraintEqualFocalDistance::error() @@ -2087,8 +2255,9 @@ double ConstraintEqualFocalDistance::error() double ConstraintEqualFocalDistance::grad(double* param) { // first of all, check that we need to compute anything. - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -2143,8 +2312,9 @@ void ConstraintCurveValue::rescale(double coef) void ConstraintCurveValue::errorgrad(double* err, double* grad, double* param) { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } double u, du; u = *(this->u()); @@ -2158,16 +2328,20 @@ void ConstraintCurveValue::errorgrad(double* err, double* grad, double* param) DeriVector2 err_vec = P_from.subtr(P_to); if (this->pcoord() == this->p.x) {// this constraint is for X projection - if (err) + if (err) { *err = err_vec.x; - if (grad) + } + if (grad) { *grad = err_vec.dx; + } } else if (this->pcoord() == this->p.y) {// this constraint is for Y projection - if (err) + if (err) { *err = err_vec.y; - if (grad) + } + if (grad) { *grad = err_vec.dy; + } } else { assert(false /*this constraint is neither X nor Y. Nothing to do..*/); @@ -2184,8 +2358,9 @@ double ConstraintCurveValue::error() double ConstraintCurveValue::grad(double* param) { // first of all, check that we need to compute anything. - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -2289,34 +2464,41 @@ double ConstraintPointOnHyperbola::grad(double* param) double Y_F1 = *f1y(); double b = *rmin(); - if (param == p1x()) + if (param == p1x()) { deriv += -(X_0 - X_F1) / sqrt(pow(X_0 - X_F1, 2) + pow(Y_0 - Y_F1, 2)) + (X_0 + X_F1 - 2 * X_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == p1y()) + } + if (param == p1y()) { deriv += -(Y_0 - Y_F1) / sqrt(pow(X_0 - X_F1, 2) + pow(Y_0 - Y_F1, 2)) + (Y_0 + Y_F1 - 2 * Y_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == f1x()) + } + if (param == f1x()) { deriv += (X_0 - X_F1) / sqrt(pow(X_0 - X_F1, 2) + pow(Y_0 - Y_F1, 2)) - 2 * (X_F1 - X_c) / sqrt(-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) + (X_0 + X_F1 - 2 * X_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == f1y()) + } + if (param == f1y()) { deriv += (Y_0 - Y_F1) / sqrt(pow(X_0 - X_F1, 2) + pow(Y_0 - Y_F1, 2)) - 2 * (Y_F1 - Y_c) / sqrt(-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) + (Y_0 + Y_F1 - 2 * Y_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == cx()) + } + if (param == cx()) { deriv += 2 * (X_F1 - X_c) / sqrt(-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) - 2 * (X_0 + X_F1 - 2 * X_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == cy()) + } + if (param == cy()) { deriv += 2 * (Y_F1 - Y_c) / sqrt(-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)) - 2 * (Y_0 + Y_F1 - 2 * Y_c) / sqrt(pow(X_0 + X_F1 - 2 * X_c, 2) + pow(Y_0 + Y_F1 - 2 * Y_c, 2)); - if (param == rmin()) + } + if (param == rmin()) { deriv += 2 * b / sqrt(-pow(b, 2) + pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)); + } } return scale * deriv; } @@ -2375,8 +2557,9 @@ void ConstraintPointOnParabola::rescale(double coef) void ConstraintPointOnParabola::errorgrad(double* err, double* grad, double* param) { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } DeriVector2 focus(this->parab->focus1, param); DeriVector2 vertex(this->parab->vertex, param); @@ -2401,10 +2584,12 @@ void ConstraintPointOnParabola::errorgrad(double* err, double* grad, double* par proj = point_to_focus.scalarProd(xdir, &dproj); - if (err) + if (err) { *err = pf - 2 * focal - proj; - if (grad) + } + if (grad) { *grad = dpf - 2 * dfocal - dproj; + } } double ConstraintPointOnParabola::error() @@ -2417,8 +2602,9 @@ double ConstraintPointOnParabola::error() double ConstraintPointOnParabola::grad(double* param) { // first of all, check that we need to compute anything. - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -2476,8 +2662,9 @@ void ConstraintAngleViaPoint::rescale(double coef) double ConstraintAngleViaPoint::error() { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } double ang = *angle(); DeriVector2 n1 = crv1->CalculateNormal(poa); DeriVector2 n2 = crv2->CalculateNormal(poa); @@ -2497,16 +2684,19 @@ double ConstraintAngleViaPoint::error() double ConstraintAngleViaPoint::grad(double* param) { // first of all, check that we need to compute anything. - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv = 0.; - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } - if (param == angle()) + if (param == angle()) { deriv += -1.0; + } DeriVector2 n1 = crv1->CalculateNormal(poa, param); DeriVector2 n2 = crv2->CalculateNormal(poa, param); deriv -= ((-n1.dx) * n1.y / pow(n1.length(), 2) + n1.dy * n1.x / pow(n1.length(), 2)); @@ -2536,8 +2726,14 @@ double ConstraintAngleViaPoint::grad(double* param) // -------------------------------------------------------- // ConstraintSnell -ConstraintSnell::ConstraintSnell(Curve& ray1, Curve& ray2, Curve& boundary, Point p, double* n1, - double* n2, bool flipn1, bool flipn2) +ConstraintSnell::ConstraintSnell(Curve& ray1, + Curve& ray2, + Curve& boundary, + Point p, + double* n1, + double* n2, + bool flipn1, + bool flipn2) { pvec.push_back(n1); pvec.push_back(n2); @@ -2596,8 +2792,9 @@ void ConstraintSnell::rescale(double coef) // error and gradient combined. Values are returned through pointers. void ConstraintSnell::errorgrad(double* err, double* grad, double* param) { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } DeriVector2 tang1 = ray1->CalculateNormal(poa, param).rotate90cw().getNormalized(); DeriVector2 tang2 = ray2->CalculateNormal(poa, param).rotate90cw().getNormalized(); DeriVector2 tangB = boundary->CalculateNormal(poa, param).rotate90cw().getNormalized(); @@ -2615,10 +2812,12 @@ void ConstraintSnell::errorgrad(double* err, double* grad, double* param) double dn1 = (param == n1()) ? 1.0 : 0.0; double dn2 = (param == n2()) ? 1.0 : 0.0; - if (err) + if (err) { *err = *n1() * sin1 - *n2() * sin2; - if (grad) + } + if (grad) { *grad = dn1 * sin1 + *n1() * dsin1 - dn2 * sin2 - *n2() * dsin2; + } } double ConstraintSnell::error() @@ -2631,8 +2830,9 @@ double ConstraintSnell::error() double ConstraintSnell::grad(double* param) { // first of all, check that we need to compute anything. - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -2692,8 +2892,9 @@ void ConstraintEqualLineLength::rescale(double coef) void ConstraintEqualLineLength::errorgrad(double* err, double* grad, double* param) { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } DeriVector2 p1(l1.p1, param); DeriVector2 p2(l1.p2, param); @@ -2709,8 +2910,9 @@ void ConstraintEqualLineLength::errorgrad(double* err, double* grad, double* par double length2, dlength2; length2 = v2.length(dlength2); - if (err) + if (err) { *err = length2 - length1; + } if (grad) { *grad = dlength2 - dlength1; @@ -2723,22 +2925,30 @@ void ConstraintEqualLineLength::errorgrad(double* err, double* grad, double* par // or just locked into a maximum/minimum if (fabs(*grad) < 1e-10) { double surrogate = 1e-10; - if (param == l1.p1.x) + if (param == l1.p1.x) { *grad = v1.x > 0 ? surrogate : -surrogate; - if (param == l1.p1.y) + } + if (param == l1.p1.y) { *grad = v1.y > 0 ? surrogate : -surrogate; - if (param == l1.p2.x) + } + if (param == l1.p2.x) { *grad = v1.x > 0 ? -surrogate : surrogate; - if (param == l1.p2.y) + } + if (param == l1.p2.y) { *grad = v1.y > 0 ? -surrogate : surrogate; - if (param == l2.p1.x) + } + if (param == l2.p1.x) { *grad = v2.x > 0 ? surrogate : -surrogate; - if (param == l2.p1.y) + } + if (param == l2.p1.y) { *grad = v2.y > 0 ? surrogate : -surrogate; - if (param == l2.p2.x) + } + if (param == l2.p2.x) { *grad = v2.x > 0 ? -surrogate : surrogate; - if (param == l2.p2.y) + } + if (param == l2.p2.y) { *grad = v2.y > 0 ? -surrogate : surrogate; + } } } } @@ -2752,8 +2962,9 @@ double ConstraintEqualLineLength::error() double ConstraintEqualLineLength::grad(double* param) { - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -2801,8 +3012,9 @@ void ConstraintC2CDistance::rescale(double coef) void ConstraintC2CDistance::errorgrad(double* err, double* grad, double* param) { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } DeriVector2 ct1(c1.center, param); DeriVector2 ct2(c2.center, param); @@ -2863,8 +3075,9 @@ double ConstraintC2CDistance::error() double ConstraintC2CDistance::grad(double* param) { - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); @@ -2911,8 +3124,9 @@ void ConstraintC2LDistance::ReconstructGeomPointers() void ConstraintC2LDistance::errorgrad(double* err, double* grad, double* param) { - if (pvecChangedFlag) + if (pvecChangedFlag) { ReconstructGeomPointers(); + } DeriVector2 ct(circle.center, param); DeriVector2 p1(line.p1, param); @@ -2965,8 +3179,100 @@ double ConstraintC2LDistance::error() double ConstraintC2LDistance::grad(double* param) { - if (findParamInPvec(param) == -1) + if (findParamInPvec(param) == -1) { return 0.0; + } + + double deriv; + errorgrad(nullptr, &deriv, param); + + return deriv * scale; +} + +// -------------------------------------------------------- +// ConstraintP2CDistance +ConstraintP2CDistance::ConstraintP2CDistance(Point& p, Circle& c, double* d) +{ + this->d = d; + pvec.push_back(d); + + this->circle = c; + this->circle.PushOwnParams(pvec); + + this->pt = p; + this->pt.PushOwnParams(pvec); + + origpvec = pvec; + pvecChangedFlag = true; + rescale(); +} + +ConstraintType ConstraintP2CDistance::getTypeId() +{ + return P2CDistance; +} + +void ConstraintP2CDistance::rescale(double coef) +{ + scale = coef; +} + +void ConstraintP2CDistance::ReconstructGeomPointers() +{ + int i = 0; + i++;// skip the first parameter as there is the inline function distance for it + circle.ReconstructOnNewPvec(pvec, i); + pt.ReconstructOnNewPvec(pvec, i); + pvecChangedFlag = false; +} + +void ConstraintP2CDistance::errorgrad(double* err, double* grad, double* param) +{ + if (pvecChangedFlag) { + ReconstructGeomPointers(); + } + + DeriVector2 ct(circle.center, param); + DeriVector2 p(pt, param); + DeriVector2 v_length = ct.subtr(p); + + double dlength; + double length = v_length.length(dlength); + + if (err) { + *err = *circle.rad + *distance() - length; + if (length < *circle.rad) { + *err = *circle.rad - *distance() - length; + } + } + else if (grad) { + if (param == distance()) { + *grad = 1.0; + if (length < *circle.rad) { + *grad = -1.0; + } + } + else if (param == circle.rad) { + *grad = 1.0; + } + else { + *grad = -dlength; + } + } +} + +double ConstraintP2CDistance::error() +{ + double err; + errorgrad(&err, nullptr, nullptr); + return scale * err; +} + +double ConstraintP2CDistance::grad(double* param) +{ + if (findParamInPvec(param) == -1) { + return 0.0; + } double deriv; errorgrad(nullptr, &deriv, param); diff --git a/src/Mod/Sketcher/App/planegcs/Constraints.h b/src/Mod/Sketcher/App/planegcs/Constraints.h index 7173de74be..f052b35872 100644 --- a/src/Mod/Sketcher/App/planegcs/Constraints.h +++ b/src/Mod/Sketcher/App/planegcs/Constraints.h @@ -77,7 +77,8 @@ enum ConstraintType SlopeAtBSplineKnot = 28, PointOnBSpline = 29, C2CDistance = 30, - C2LDistance = 31 + C2LDistance = 31, + P2CDistance = 32 }; enum InternalAlignmentType @@ -821,7 +822,10 @@ private: bool internal; public: - ConstraintTangentCircumf(Point& p1, Point& p2, double* rd1, double* rd2, + ConstraintTangentCircumf(Point& p1, + Point& p2, + double* rd1, + double* rd2, bool internal_ = false); #ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_ inline ConstraintTangentCircumf(bool internal_) @@ -905,7 +909,8 @@ public: class ConstraintInternalAlignmentPoint2Ellipse: public Constraint { public: - ConstraintInternalAlignmentPoint2Ellipse(Ellipse& e, Point& p1, + ConstraintInternalAlignmentPoint2Ellipse(Ellipse& e, + Point& p1, InternalAlignmentType alignmentType); ConstraintType getTypeId() override; void rescale(double coef = 1.) override; @@ -925,7 +930,8 @@ private: class ConstraintInternalAlignmentPoint2Hyperbola: public Constraint { public: - ConstraintInternalAlignmentPoint2Hyperbola(Hyperbola& e, Point& p1, + ConstraintInternalAlignmentPoint2Hyperbola(Hyperbola& e, + Point& p1, InternalAlignmentType alignmentType); ConstraintType getTypeId() override; void rescale(double coef = 1.) override; @@ -1152,8 +1158,14 @@ private: public: // n1dn2 = n1 divided by n2. from n1 to n2. flipn1 = true instructs to flip ray1's tangent - ConstraintSnell(Curve& ray1, Curve& ray2, Curve& boundary, Point p, double* n1, double* n2, - bool flipn1, bool flipn2); + ConstraintSnell(Curve& ray1, + Curve& ray2, + Curve& boundary, + Point p, + double* n1, + double* n2, + bool flipn1, + bool flipn2); ~ConstraintSnell() override; ConstraintType getTypeId() override; void rescale(double coef = 1.) override; @@ -1226,6 +1238,31 @@ public: double grad(double*) override; }; +// P2CDistance +class ConstraintP2CDistance: public Constraint +{ +private: + Circle circle; + Point pt; + double* d; + inline double* distance() + { + return pvec[0]; + } + void ReconstructGeomPointers();// writes pointers in pvec to the parameters of c + void + errorgrad(double* err, + double* grad, + double* param);// error and gradient combined. Values are returned through pointers. +public: + ConstraintP2CDistance(Point& p, Circle& c, double* d); + ConstraintType getTypeId() override; + void rescale(double coef = 1.) override; + double error() override; + double grad(double*) override; +}; + + }// namespace GCS #endif// PLANEGCS_CONSTRAINTS_H diff --git a/src/Mod/Sketcher/App/planegcs/GCS.cpp b/src/Mod/Sketcher/App/planegcs/GCS.cpp index b8a98734e9..d14a1ff730 100644 --- a/src/Mod/Sketcher/App/planegcs/GCS.cpp +++ b/src/Mod/Sketcher/App/planegcs/GCS.cpp @@ -150,8 +150,9 @@ FullPivLU& FullPivLU::compute(const MatrixdType& matri // when k==0, biggest_in_corner is the biggest coeff absolute value in the original // matrix - if (k == 0) + if (k == 0) { cutoff = biggest_in_corner * NumTraits::epsilon(); + } // if the pivot (hence the corner) is "zero", terminate to avoid generating nan/inf // values. Notice that using an exact comparison (biggest_in_corner==0) here, as @@ -168,8 +169,9 @@ FullPivLU& FullPivLU::compute(const MatrixdType& matri break; } - if (biggest_in_corner > m_maxpivot) + if (biggest_in_corner > m_maxpivot) { m_maxpivot = biggest_in_corner; + } // Now that we've found the pivot, we need to apply the row/col swaps to // bring it to the location (k,k). @@ -188,23 +190,27 @@ FullPivLU& FullPivLU::compute(const MatrixdType& matri // Now that the pivot is at the right location, we update the remaining // bottom-right corner by Gaussian elimination. - if (k < rows - 1) + if (k < rows - 1) { m_lu.col(k).tail(rows - k - 1) /= m_lu.coeff(k, k); - if (k < size - 1) + } + if (k < size - 1) { m_lu.block(k + 1, k + 1, rows - k - 1, cols - k - 1).noalias() -= m_lu.col(k).tail(rows - k - 1) * m_lu.row(k).tail(cols - k - 1); + } } // the main loop is over, we still have to accumulate the transpositions to find the // permutations P and Q m_p.setIdentity(rows); - for (Index k = size - 1; k >= 0; --k) + for (Index k = size - 1; k >= 0; --k) { m_p.applyTranspositionOnTheRight(k, m_rowsTranspositions.coeff(k)); + } m_q.setIdentity(cols); - for (Index k = 0; k < size; ++k) + for (Index k = 0; k < size; ++k) { m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k)); + } m_det_pq = (number_of_transpositions % 2) ? -1 : 1; return *this; @@ -232,7 +238,9 @@ public: inline void LogToFile(const std::string& str); - void LogQRSystemInformation(const System& system, int paramsNum = 0, int constrNum = 0, + void LogQRSystemInformation(const System& system, + int paramsNum = 0, + int constrNum = 0, int rank = 0); void LogGroupOfConstraints(const std::string& str, @@ -323,8 +331,10 @@ void SolverReportingManager::LogString(const std::string& str) #endif } -void SolverReportingManager::LogQRSystemInformation(const System& system, int paramsNum, - int constrNum, int rank) +void SolverReportingManager::LogQRSystemInformation(const System& system, + int paramsNum, + int constrNum, + int rank) { std::stringstream tempstream; @@ -359,7 +369,8 @@ void SolverReportingManager::LogQRSystemInformation(const System& system, int pa } void SolverReportingManager::LogGroupOfConstraints( - const std::string& str, std::vector> constraintgroups) + const std::string& str, + std::vector> constraintgroups) { std::stringstream tempstream; @@ -368,8 +379,9 @@ void SolverReportingManager::LogGroupOfConstraints( for (const auto& group : constraintgroups) { tempstream << "["; - for (auto c : group) + for (auto c : group) { tempstream << c->getTag() << " "; + } tempstream << "]" << '\n'; } @@ -384,8 +396,9 @@ void SolverReportingManager::LogSetOfConstraints(const std::string& str, tempstream << str << ": ["; - for (auto c : constraintset) + for (auto c : constraintset) { tempstream << c->getTag() << " "; + } tempstream << "]" << '\n'; @@ -402,8 +415,9 @@ void SolverReportingManager::LogGroupOfParameters(const std::string& str, for (size_t i = 0; i < parametergroups.size(); i++) { tempstream << "["; - for (auto p : parametergroups[i]) + for (auto p : parametergroups[i]) { tempstream << std::hex << p << " "; + } tempstream << "]" << '\n'; } @@ -446,42 +460,42 @@ using Graph = boost::adjacency_list constrvec; for (std::vector::const_iterator constr = clist.begin(); constr != clist.end(); ++constr) { - if ((*constr)->getTag() == tagId) + if ((*constr)->getTag() == tagId) { constrvec.push_back(*constr); + } } for (std::vector::const_iterator constr = constrvec.begin(); constr != constrvec.end(); @@ -614,8 +629,9 @@ void System::clearByTag(int tagId) int System::addConstraint(Constraint* constr) { isInit = false; - if (constr->getTag() >= 0)// negatively tagged constraints have no impact - hasDiagnosis = false; // on the diagnosis + if (constr->getTag() >= 0) {// negatively tagged constraints have no impact + hasDiagnosis = false; // on the diagnosis + } clist.push_back(constr); VEC_pD constr_params = constr->params(); @@ -632,12 +648,14 @@ void System::removeConstraint(Constraint* constr) { std::vector::iterator it; it = std::find(clist.begin(), clist.end(), constr); - if (it == clist.end()) + if (it == clist.end()) { return; + } clist.erase(it); - if (constr->getTag() >= 0) + if (constr->getTag() >= 0) { hasDiagnosis = false; + } clearSubSystems(); VEC_pD constr_params = c2p[constr]; @@ -654,7 +672,10 @@ void System::removeConstraint(Constraint* constr) // basic constraints -int System::addConstraintEqual(double* param1, double* param2, int tagId, bool driving, +int System::addConstraintEqual(double* param1, + double* param2, + int tagId, + bool driving, Constraint::Alignment internalalignment) { Constraint* constr = new ConstraintEqual(param1, param2); @@ -664,7 +685,10 @@ int System::addConstraintEqual(double* param1, double* param2, int tagId, bool d return addConstraint(constr); } -int System::addConstraintProportional(double* param1, double* param2, double ratio, int tagId, +int System::addConstraintProportional(double* param1, + double* param2, + double ratio, + int tagId, bool driving) { Constraint* constr = new ConstraintEqual(param1, param2, ratio); @@ -673,7 +697,10 @@ int System::addConstraintProportional(double* param1, double* param2, double rat return addConstraint(constr); } -int System::addConstraintDifference(double* param1, double* param2, double* difference, int tagId, +int System::addConstraintDifference(double* param1, + double* param2, + double* difference, + int tagId, bool driving) { Constraint* constr = new ConstraintDifference(param1, param2, difference); @@ -682,7 +709,10 @@ int System::addConstraintDifference(double* param1, double* param2, double* diff return addConstraint(constr); } -int System::addConstraintP2PDistance(Point& p1, Point& p2, double* distance, int tagId, +int System::addConstraintP2PDistance(Point& p1, + Point& p2, + double* distance, + int tagId, bool driving) { Constraint* constr = new ConstraintP2PDistance(p1, p2, distance); @@ -691,7 +721,11 @@ int System::addConstraintP2PDistance(Point& p1, Point& p2, double* distance, int return addConstraint(constr); } -int System::addConstraintP2PAngle(Point& p1, Point& p2, double* angle, double incrAngle, int tagId, +int System::addConstraintP2PAngle(Point& p1, + Point& p2, + double* angle, + double incrAngle, + int tagId, bool driving) { Constraint* constr = new ConstraintP2PAngle(p1, p2, angle, incrAngle); @@ -737,7 +771,10 @@ int System::addConstraintPointOnPerpBisector(Point& p, Line& l, int tagId, bool return addConstraint(constr); } -int System::addConstraintPointOnPerpBisector(Point& p, Point& lp1, Point& lp2, int tagId, +int System::addConstraintPointOnPerpBisector(Point& p, + Point& lp1, + Point& lp2, + int tagId, bool driving) { Constraint* constr = new ConstraintPointOnPerpBisector(p, lp1, lp2); @@ -762,8 +799,12 @@ int System::addConstraintPerpendicular(Line& l1, Line& l2, int tagId, bool drivi return addConstraint(constr); } -int System::addConstraintPerpendicular(Point& l1p1, Point& l1p2, Point& l2p1, Point& l2p2, - int tagId, bool driving) +int System::addConstraintPerpendicular(Point& l1p1, + Point& l1p2, + Point& l2p1, + Point& l2p2, + int tagId, + bool driving) { Constraint* constr = new ConstraintPerpendicular(l1p1, l1p2, l2p1, l2p2); constr->setTag(tagId); @@ -779,8 +820,13 @@ int System::addConstraintL2LAngle(Line& l1, Line& l2, double* angle, int tagId, return addConstraint(constr); } -int System::addConstraintL2LAngle(Point& l1p1, Point& l1p2, Point& l2p1, Point& l2p2, double* angle, - int tagId, bool driving) +int System::addConstraintL2LAngle(Point& l1p1, + Point& l1p2, + Point& l2p1, + Point& l2p2, + double* angle, + int tagId, + bool driving) { Constraint* constr = new ConstraintL2LAngle(l1p1, l1p2, l2p1, l2p2, angle); constr->setTag(tagId); @@ -788,7 +834,11 @@ int System::addConstraintL2LAngle(Point& l1p1, Point& l1p2, Point& l2p1, Point& return addConstraint(constr); } -int System::addConstraintAngleViaPoint(Curve& crv1, Curve& crv2, Point& p, double* angle, int tagId, +int System::addConstraintAngleViaPoint(Curve& crv1, + Curve& crv2, + Point& p, + double* angle, + int tagId, bool driving) { Constraint* constr = new ConstraintAngleViaPoint(crv1, crv2, p, angle); @@ -805,8 +855,12 @@ int System::addConstraintMidpointOnLine(Line& l1, Line& l2, int tagId, bool driv return addConstraint(constr); } -int System::addConstraintMidpointOnLine(Point& l1p1, Point& l1p2, Point& l2p1, Point& l2p2, - int tagId, bool driving) +int System::addConstraintMidpointOnLine(Point& l1p1, + Point& l1p2, + Point& l2p1, + Point& l2p2, + int tagId, + bool driving) { Constraint* constr = new ConstraintMidpointOnLine(l1p1, l1p2, l2p1, l2p2); constr->setTag(tagId); @@ -814,8 +868,13 @@ int System::addConstraintMidpointOnLine(Point& l1p1, Point& l1p2, Point& l2p1, P return addConstraint(constr); } -int System::addConstraintTangentCircumf(Point& p1, Point& p2, double* rad1, double* rad2, - bool internal, int tagId, bool driving) +int System::addConstraintTangentCircumf(Point& p1, + Point& p2, + double* rad1, + double* rad2, + bool internal, + int tagId, + bool driving) { Constraint* constr = new ConstraintTangentCircumf(p1, p2, rad1, rad2, internal); constr->setTag(tagId); @@ -823,8 +882,11 @@ int System::addConstraintTangentCircumf(Point& p1, Point& p2, double* rad1, doub return addConstraint(constr); } -int System::addConstraintTangentAtBSplineKnot(BSpline& b, Line& l, unsigned int knotindex, - int tagId, bool driving) +int System::addConstraintTangentAtBSplineKnot(BSpline& b, + Line& l, + unsigned int knotindex, + int tagId, + bool driving) { Constraint* constr = new ConstraintSlopeAtBSplineKnot(b, l, knotindex); constr->setTag(tagId); @@ -848,6 +910,14 @@ int System::addConstraintC2LDistance(Circle& c, Line& l, double* dist, int tagId return addConstraint(constr); } +int System::addConstraintP2CDistance(Point& p, Circle& c, double* distance, int tagId, bool driving) +{ + Constraint* constr = new ConstraintP2CDistance(p, c, distance); + constr->setTag(tagId); + constr->setDriving(driving); + return addConstraint(constr); +} + // derived constraints int System::addConstraintP2PCoincident(Point& p1, Point& p2, int tagId, bool driving) @@ -921,7 +991,10 @@ int System::addConstraintPointOnParabolicArc(Point& p, ArcOfParabola& e, int tag return addConstraint(constr); } -int System::addConstraintPointOnBSpline(Point& p, BSpline& b, double* pointparam, int tagId, +int System::addConstraintPointOnBSpline(Point& p, + BSpline& b, + double* pointparam, + int tagId, bool driving) { Constraint* constr = new ConstraintPointOnBSpline(p.x, pointparam, 0, b); @@ -970,31 +1043,44 @@ int System::addConstraintPointOnArc(Point& p, Arc& a, int tagId, bool driving) return addConstraintP2PDistance(p, a.center, a.rad, tagId, driving); } -int System::addConstraintPerpendicularLine2Arc(Point& p1, Point& p2, Arc& a, int tagId, +int System::addConstraintPerpendicularLine2Arc(Point& p1, + Point& p2, + Arc& a, + int tagId, bool driving) { addConstraintP2PCoincident(p2, a.start, tagId, driving); double dx = *(p2.x) - *(p1.x); double dy = *(p2.y) - *(p1.y); - if (dx * cos(*(a.startAngle)) + dy * sin(*(a.startAngle)) > 0) + if (dx * cos(*(a.startAngle)) + dy * sin(*(a.startAngle)) > 0) { return addConstraintP2PAngle(p1, p2, a.startAngle, 0, tagId, driving); - else + } + else { return addConstraintP2PAngle(p1, p2, a.startAngle, M_PI, tagId, driving); + } } -int System::addConstraintPerpendicularArc2Line(Arc& a, Point& p1, Point& p2, int tagId, +int System::addConstraintPerpendicularArc2Line(Arc& a, + Point& p1, + Point& p2, + int tagId, bool driving) { addConstraintP2PCoincident(p1, a.end, tagId, driving); double dx = *(p2.x) - *(p1.x); double dy = *(p2.y) - *(p1.y); - if (dx * cos(*(a.endAngle)) + dy * sin(*(a.endAngle)) > 0) + if (dx * cos(*(a.endAngle)) + dy * sin(*(a.endAngle)) > 0) { return addConstraintP2PAngle(p1, p2, a.endAngle, 0, tagId, driving); - else + } + else { return addConstraintP2PAngle(p1, p2, a.endAngle, M_PI, tagId, driving); + } } -int System::addConstraintPerpendicularCircle2Arc(Point& center, double* radius, Arc& a, int tagId, +int System::addConstraintPerpendicularCircle2Arc(Point& center, + double* radius, + Arc& a, + int tagId, bool driving) { addConstraintP2PDistance(a.start, center, radius, tagId, driving); @@ -1002,13 +1088,18 @@ int System::addConstraintPerpendicularCircle2Arc(Point& center, double* radius, double tangAngle = *a.startAngle + incrAngle; double dx = *(a.start.x) - *(center.x); double dy = *(a.start.y) - *(center.y); - if (dx * cos(tangAngle) + dy * sin(tangAngle) > 0) + if (dx * cos(tangAngle) + dy * sin(tangAngle) > 0) { return addConstraintP2PAngle(center, a.start, a.startAngle, incrAngle, tagId, driving); - else + } + else { return addConstraintP2PAngle(center, a.start, a.startAngle, -incrAngle, tagId, driving); + } } -int System::addConstraintPerpendicularArc2Circle(Arc& a, Point& center, double* radius, int tagId, +int System::addConstraintPerpendicularArc2Circle(Arc& a, + Point& center, + double* radius, + int tagId, bool driving) { addConstraintP2PDistance(a.end, center, radius, tagId, driving); @@ -1016,14 +1107,20 @@ int System::addConstraintPerpendicularArc2Circle(Arc& a, Point& center, double* double tangAngle = *a.endAngle + incrAngle; double dx = *(a.end.x) - *(center.x); double dy = *(a.end.y) - *(center.y); - if (dx * cos(tangAngle) + dy * sin(tangAngle) > 0) + if (dx * cos(tangAngle) + dy * sin(tangAngle) > 0) { return addConstraintP2PAngle(center, a.end, a.endAngle, incrAngle, tagId, driving); - else + } + else { return addConstraintP2PAngle(center, a.end, a.endAngle, -incrAngle, tagId, driving); + } } -int System::addConstraintPerpendicularArc2Arc(Arc& a1, bool reverse1, Arc& a2, bool reverse2, - int tagId, bool driving) +int System::addConstraintPerpendicularArc2Arc(Arc& a1, + bool reverse1, + Arc& a2, + bool reverse2, + int tagId, + bool driving) { Point& p1 = reverse1 ? a1.start : a1.end; Point& p2 = reverse2 ? a2.end : a2.start; @@ -1054,8 +1151,13 @@ int System::addConstraintTangent(Circle& c1, Circle& c2, int tagId, bool driving double dx = *(c2.center.x) - *(c1.center.x); double dy = *(c2.center.y) - *(c1.center.y); double d = sqrt(dx * dx + dy * dy); - return addConstraintTangentCircumf( - c1.center, c2.center, c1.rad, c2.rad, (d < *c1.rad || d < *c2.rad), tagId, driving); + return addConstraintTangentCircumf(c1.center, + c2.center, + c1.rad, + c2.rad, + (d < *c1.rad || d < *c2.rad), + tagId, + driving); } int System::addConstraintTangent(Arc& a1, Arc& a2, int tagId, bool driving) @@ -1063,8 +1165,13 @@ int System::addConstraintTangent(Arc& a1, Arc& a2, int tagId, bool driving) double dx = *(a2.center.x) - *(a1.center.x); double dy = *(a2.center.y) - *(a1.center.y); double d = sqrt(dx * dx + dy * dy); - return addConstraintTangentCircumf( - a1.center, a2.center, a1.rad, a2.rad, (d < *a1.rad || d < *a2.rad), tagId, driving); + return addConstraintTangentCircumf(a1.center, + a2.center, + a1.rad, + a2.rad, + (d < *a1.rad || d < *a2.rad), + tagId, + driving); } int System::addConstraintTangent(Circle& c, Arc& a, int tagId, bool driving) @@ -1072,8 +1179,13 @@ int System::addConstraintTangent(Circle& c, Arc& a, int tagId, bool driving) double dx = *(a.center.x) - *(c.center.x); double dy = *(a.center.y) - *(c.center.y); double d = sqrt(dx * dx + dy * dy); - return addConstraintTangentCircumf( - c.center, a.center, c.rad, a.rad, (d < *c.rad || d < *a.rad), tagId, driving); + return addConstraintTangentCircumf(c.center, + a.center, + c.rad, + a.rad, + (d < *c.rad || d < *a.rad), + tagId, + driving); } int System::addConstraintCircleRadius(Circle& c, double* radius, int tagId, bool driving) @@ -1159,8 +1271,16 @@ int System::addConstraintP2PSymmetric(Point& p1, Point& p2, Point& p, int tagId, return addConstraintPointOnLine(p, p1, p2, tagId, driving); } -int System::addConstraintSnellsLaw(Curve& ray1, Curve& ray2, Curve& boundary, Point p, double* n1, - double* n2, bool flipn1, bool flipn2, int tagId, bool driving) +int System::addConstraintSnellsLaw(Curve& ray1, + Curve& ray2, + Curve& boundary, + Point p, + double* n1, + double* n2, + bool flipn1, + bool flipn2, + int tagId, + bool driving) { Constraint* constr = new ConstraintSnell(ray1, ray2, boundary, p, n1, n2, flipn1, flipn2); constr->setTag(tagId); @@ -1168,9 +1288,11 @@ int System::addConstraintSnellsLaw(Curve& ray1, Curve& ray2, Curve& boundary, Po return addConstraint(constr); } -int System::addConstraintInternalAlignmentPoint2Ellipse(Ellipse& e, Point& p1, +int System::addConstraintInternalAlignmentPoint2Ellipse(Ellipse& e, + Point& p1, InternalAlignmentType alignmentType, - int tagId, bool driving) + int tagId, + bool driving) { Constraint* constr = new ConstraintInternalAlignmentPoint2Ellipse(e, p1, alignmentType); constr->setTag(tagId); @@ -1179,9 +1301,11 @@ int System::addConstraintInternalAlignmentPoint2Ellipse(Ellipse& e, Point& p1, return addConstraint(constr); } -int System::addConstraintInternalAlignmentPoint2Hyperbola(Hyperbola& e, Point& p1, +int System::addConstraintInternalAlignmentPoint2Hyperbola(Hyperbola& e, + Point& p1, InternalAlignmentType alignmentType, - int tagId, bool driving) + int tagId, + bool driving) { Constraint* constr = new ConstraintInternalAlignmentPoint2Hyperbola(e, p1, alignmentType); constr->setTag(tagId); @@ -1190,8 +1314,11 @@ int System::addConstraintInternalAlignmentPoint2Hyperbola(Hyperbola& e, Point& p return addConstraint(constr); } -int System::addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse& e, Point& p1, Point& p2, - int tagId, bool driving) +int System::addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse& e, + Point& p1, + Point& p2, + int tagId, + bool driving) { double X_1 = *p1.x; double Y_1 = *p1.y; @@ -1234,21 +1361,30 @@ int System::addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse& e, Point addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipsePositiveMajorX, tagId, driving); addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipsePositiveMajorY, tagId, driving); addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipseNegativeMajorX, tagId, driving); - return addConstraintInternalAlignmentPoint2Ellipse( - e, p1, EllipseNegativeMajorY, tagId, driving); + return addConstraintInternalAlignmentPoint2Ellipse(e, + p1, + EllipseNegativeMajorY, + tagId, + driving); } else { // p1 is closer to positivemajor addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipsePositiveMajorX, tagId, driving); addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipsePositiveMajorY, tagId, driving); addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipseNegativeMajorX, tagId, driving); - return addConstraintInternalAlignmentPoint2Ellipse( - e, p2, EllipseNegativeMajorY, tagId, driving); + return addConstraintInternalAlignmentPoint2Ellipse(e, + p2, + EllipseNegativeMajorY, + tagId, + driving); } } -int System::addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse& e, Point& p1, Point& p2, - int tagId, bool driving) +int System::addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse& e, + Point& p1, + Point& p2, + int tagId, + bool driving) { double X_1 = *p1.x; double Y_1 = *p1.y; @@ -1272,35 +1408,51 @@ int System::addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse& e, Point addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipsePositiveMinorX, tagId, driving); addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipsePositiveMinorY, tagId, driving); addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipseNegativeMinorX, tagId, driving); - return addConstraintInternalAlignmentPoint2Ellipse( - e, p1, EllipseNegativeMinorY, tagId, driving); + return addConstraintInternalAlignmentPoint2Ellipse(e, + p1, + EllipseNegativeMinorY, + tagId, + driving); } else { addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipsePositiveMinorX, tagId, driving); addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipsePositiveMinorY, tagId, driving); addConstraintInternalAlignmentPoint2Ellipse(e, p2, EllipseNegativeMinorX, tagId, driving); - return addConstraintInternalAlignmentPoint2Ellipse( - e, p2, EllipseNegativeMinorY, tagId, driving); + return addConstraintInternalAlignmentPoint2Ellipse(e, + p2, + EllipseNegativeMinorY, + tagId, + driving); } } -int System::addConstraintInternalAlignmentEllipseFocus1(Ellipse& e, Point& p1, int tagId, +int System::addConstraintInternalAlignmentEllipseFocus1(Ellipse& e, + Point& p1, + int tagId, bool driving) { addConstraintEqual(e.focus1.x, p1.x, tagId, driving, Constraint::Alignment::InternalAlignment); - return addConstraintEqual( - e.focus1.y, p1.y, tagId, driving, Constraint::Alignment::InternalAlignment); + return addConstraintEqual(e.focus1.y, + p1.y, + tagId, + driving, + Constraint::Alignment::InternalAlignment); } -int System::addConstraintInternalAlignmentEllipseFocus2(Ellipse& e, Point& p1, int tagId, +int System::addConstraintInternalAlignmentEllipseFocus2(Ellipse& e, + Point& p1, + int tagId, bool driving) { addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipseFocus2X, tagId, driving); return addConstraintInternalAlignmentPoint2Ellipse(e, p1, EllipseFocus2Y, tagId, driving); } -int System::addConstraintInternalAlignmentHyperbolaMajorDiameter(Hyperbola& e, Point& p1, Point& p2, - int tagId, bool driving) +int System::addConstraintInternalAlignmentHyperbolaMajorDiameter(Hyperbola& e, + Point& p1, + Point& p2, + int tagId, + bool driving) { double X_1 = *p1.x; double Y_1 = *p1.y; @@ -1340,30 +1492,57 @@ int System::addConstraintInternalAlignmentHyperbolaMajorDiameter(Hyperbola& e, P if (closertopositivemajor > 0) { // p2 is closer to positivemajor. Assign constraints back-to-front. - addConstraintInternalAlignmentPoint2Hyperbola( - e, p2, HyperbolaPositiveMajorX, tagId, driving); - addConstraintInternalAlignmentPoint2Hyperbola( - e, p2, HyperbolaPositiveMajorY, tagId, driving); - addConstraintInternalAlignmentPoint2Hyperbola( - e, p1, HyperbolaNegativeMajorX, tagId, driving); - return addConstraintInternalAlignmentPoint2Hyperbola( - e, p1, HyperbolaNegativeMajorY, tagId, driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p2, + HyperbolaPositiveMajorX, + tagId, + driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p2, + HyperbolaPositiveMajorY, + tagId, + driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p1, + HyperbolaNegativeMajorX, + tagId, + driving); + return addConstraintInternalAlignmentPoint2Hyperbola(e, + p1, + HyperbolaNegativeMajorY, + tagId, + driving); } else { // p1 is closer to positivemajor - addConstraintInternalAlignmentPoint2Hyperbola( - e, p1, HyperbolaPositiveMajorX, tagId, driving); - addConstraintInternalAlignmentPoint2Hyperbola( - e, p1, HyperbolaPositiveMajorY, tagId, driving); - addConstraintInternalAlignmentPoint2Hyperbola( - e, p2, HyperbolaNegativeMajorX, tagId, driving); - return addConstraintInternalAlignmentPoint2Hyperbola( - e, p2, HyperbolaNegativeMajorY, tagId, driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p1, + HyperbolaPositiveMajorX, + tagId, + driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p1, + HyperbolaPositiveMajorY, + tagId, + driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p2, + HyperbolaNegativeMajorX, + tagId, + driving); + return addConstraintInternalAlignmentPoint2Hyperbola(e, + p2, + HyperbolaNegativeMajorY, + tagId, + driving); } } -int System::addConstraintInternalAlignmentHyperbolaMinorDiameter(Hyperbola& e, Point& p1, Point& p2, - int tagId, bool driving) +int System::addConstraintInternalAlignmentHyperbolaMinorDiameter(Hyperbola& e, + Point& p1, + Point& p2, + int tagId, + bool driving) { double X_1 = *p1.x; double Y_1 = *p1.y; @@ -1396,57 +1575,105 @@ int System::addConstraintInternalAlignmentHyperbolaMinorDiameter(Hyperbola& e, P 2); if (closertopositiveminor < 0) { - addConstraintInternalAlignmentPoint2Hyperbola( - e, p2, HyperbolaPositiveMinorX, tagId, driving); - addConstraintInternalAlignmentPoint2Hyperbola( - e, p2, HyperbolaPositiveMinorY, tagId, driving); - addConstraintInternalAlignmentPoint2Hyperbola( - e, p1, HyperbolaNegativeMinorX, tagId, driving); - return addConstraintInternalAlignmentPoint2Hyperbola( - e, p1, HyperbolaNegativeMinorY, tagId, driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p2, + HyperbolaPositiveMinorX, + tagId, + driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p2, + HyperbolaPositiveMinorY, + tagId, + driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p1, + HyperbolaNegativeMinorX, + tagId, + driving); + return addConstraintInternalAlignmentPoint2Hyperbola(e, + p1, + HyperbolaNegativeMinorY, + tagId, + driving); } else { - addConstraintInternalAlignmentPoint2Hyperbola( - e, p1, HyperbolaPositiveMinorX, tagId, driving); - addConstraintInternalAlignmentPoint2Hyperbola( - e, p1, HyperbolaPositiveMinorY, tagId, driving); - addConstraintInternalAlignmentPoint2Hyperbola( - e, p2, HyperbolaNegativeMinorX, tagId, driving); - return addConstraintInternalAlignmentPoint2Hyperbola( - e, p2, HyperbolaNegativeMinorY, tagId, driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p1, + HyperbolaPositiveMinorX, + tagId, + driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p1, + HyperbolaPositiveMinorY, + tagId, + driving); + addConstraintInternalAlignmentPoint2Hyperbola(e, + p2, + HyperbolaNegativeMinorX, + tagId, + driving); + return addConstraintInternalAlignmentPoint2Hyperbola(e, + p2, + HyperbolaNegativeMinorY, + tagId, + driving); } } -int System::addConstraintInternalAlignmentHyperbolaFocus(Hyperbola& e, Point& p1, int tagId, +int System::addConstraintInternalAlignmentHyperbolaFocus(Hyperbola& e, + Point& p1, + int tagId, bool driving) { addConstraintEqual(e.focus1.x, p1.x, tagId, driving, Constraint::Alignment::InternalAlignment); - return addConstraintEqual( - e.focus1.y, p1.y, tagId, driving, Constraint::Alignment::InternalAlignment); + return addConstraintEqual(e.focus1.y, + p1.y, + tagId, + driving, + Constraint::Alignment::InternalAlignment); } -int System::addConstraintInternalAlignmentParabolaFocus(Parabola& e, Point& p1, int tagId, +int System::addConstraintInternalAlignmentParabolaFocus(Parabola& e, + Point& p1, + int tagId, bool driving) { addConstraintEqual(e.focus1.x, p1.x, tagId, driving, Constraint::Alignment::InternalAlignment); - return addConstraintEqual( - e.focus1.y, p1.y, tagId, driving, Constraint::Alignment::InternalAlignment); + return addConstraintEqual(e.focus1.y, + p1.y, + tagId, + driving, + Constraint::Alignment::InternalAlignment); } -int System::addConstraintInternalAlignmentBSplineControlPoint(BSpline& b, Circle& c, - unsigned int poleindex, int tagId, +int System::addConstraintInternalAlignmentBSplineControlPoint(BSpline& b, + Circle& c, + unsigned int poleindex, + int tagId, bool driving) { - addConstraintEqual( - b.poles[poleindex].x, c.center.x, tagId, driving, Constraint::Alignment::InternalAlignment); - addConstraintEqual( - b.poles[poleindex].y, c.center.y, tagId, driving, Constraint::Alignment::InternalAlignment); - return addConstraintEqual( - b.weights[poleindex], c.rad, tagId, driving, Constraint::Alignment::InternalAlignment); + addConstraintEqual(b.poles[poleindex].x, + c.center.x, + tagId, + driving, + Constraint::Alignment::InternalAlignment); + addConstraintEqual(b.poles[poleindex].y, + c.center.y, + tagId, + driving, + Constraint::Alignment::InternalAlignment); + return addConstraintEqual(b.weights[poleindex], + c.rad, + tagId, + driving, + Constraint::Alignment::InternalAlignment); } -int System::addConstraintInternalAlignmentKnotPoint(BSpline& b, Point& p, unsigned int knotindex, - int tagId, bool driving) +int System::addConstraintInternalAlignmentKnotPoint(BSpline& b, + Point& p, + unsigned int knotindex, + int tagId, + bool driving) { if (b.periodic && knotindex == 0) { // This is done here since knotpoints themselves aren't stored @@ -1455,8 +1682,9 @@ int System::addConstraintInternalAlignmentKnotPoint(BSpline& b, Point& p, unsign } size_t numpoles = b.degree - b.mult[knotindex] + 1; - if (numpoles == 0) + if (numpoles == 0) { numpoles = 1; + } // `startpole` is the first pole affecting the knot with `knotindex` size_t startpole = 0; @@ -1473,31 +1701,37 @@ int System::addConstraintInternalAlignmentKnotPoint(BSpline& b, Point& p, unsign // The `knotindex` gives us the intervals, so work backwards and find // the affecting poles. // Note that this works also for periodic B-splines, just that the poles wrap around if needed. - for (size_t j = 1; j <= knotindex; ++j) + for (size_t j = 1; j <= knotindex; ++j) { startpole += b.mult[j]; + } // For the last knot, even the upper limit of the last interval range // is included. So offset for that. // For periodic B-splines the `flattenedknots` are defined differently, // so this is not needed for them. - if (!b.periodic && startpole >= b.poles.size()) + if (!b.periodic && startpole >= b.poles.size()) { startpole = b.poles.size() - 1; + } // Calculate the factors to be passed to weighted linear combination constraint. // The if condition has a small performance benefit, but that is not why it is here. // One case when numpoles <= 1 is for the last knot of a non-periodic B-spline. // In this case, the interval `k` passed to `getLinCombFactor` is degenerate, and this is the // cleanest way to handle it. - if (numpoles > 1) - for (size_t i = 0; i < numpoles; ++i) + if (numpoles > 1) { + for (size_t i = 0; i < numpoles; ++i) { factors[i] = b.getLinCombFactor(*(b.knots[knotindex]), startpole + b.degree, startpole + i); + } + } // The mod operation is to adjust for periodic B-splines. // This can be separated for performance reasons but it will be less readable. - for (size_t i = 0; i < numpoles; ++i) + for (size_t i = 0; i < numpoles; ++i) { pvec.push_back(b.poles[(startpole + i) % b.poles.size()].x); - for (size_t i = 0; i < numpoles; ++i) + } + for (size_t i = 0; i < numpoles; ++i) { pvec.push_back(b.weights[(startpole + i) % b.poles.size()]); + } Constraint* constr = new ConstraintWeightedLinearCombination(numpoles, pvec, factors); constr->setTag(tagId); @@ -1507,10 +1741,12 @@ int System::addConstraintInternalAlignmentKnotPoint(BSpline& b, Point& p, unsign pvec.clear(); pvec.push_back(p.y); - for (size_t i = 0; i < numpoles; ++i) + for (size_t i = 0; i < numpoles; ++i) { pvec.push_back(b.poles[(startpole + i) % b.poles.size()].y); - for (size_t i = 0; i < numpoles; ++i) + } + for (size_t i = 0; i < numpoles; ++i) { pvec.push_back(b.weights[(startpole + i) % b.poles.size()]); + } constr = new ConstraintWeightedLinearCombination(numpoles, pvec, factors); constr->setTag(tagId); @@ -1528,15 +1764,17 @@ double System::calculateAngleViaPoint(const Curve& crv1, const Curve& crv2, Poin return calculateAngleViaPoint(crv1, crv2, p, p); } -double System::calculateAngleViaPoint(const Curve& crv1, const Curve& crv2, Point& p1, - Point& p2) const +double +System::calculateAngleViaPoint(const Curve& crv1, const Curve& crv2, Point& p1, Point& p2) const { GCS::DeriVector2 n1 = crv1.CalculateNormal(p1); GCS::DeriVector2 n2 = crv2.CalculateNormal(p2); return atan2(-n2.x * n1.y + n2.y * n1.x, n2.x * n1.x + n2.y * n1.y); } -void System::calculateNormalAtPoint(const Curve& crv, const Point& p, double& rtnX, +void System::calculateNormalAtPoint(const Curve& crv, + const Point& p, + double& rtnX, double& rtnY) const { GCS::DeriVector2 n1 = crv.CalculateNormal(p); @@ -1572,18 +1810,21 @@ double System::calculateConstraintErrorByTag(int tagId) void System::rescaleConstraint(int id, double coeff) { - if (id >= static_cast(clist.size()) || id < 0) + if (id >= static_cast(clist.size()) || id < 0) { return; - if (clist[id]) + } + if (clist[id]) { clist[id]->rescale(coeff); + } } void System::declareUnknowns(VEC_pD& params) { plist = params; pIndex.clear(); - for (int i = 0; i < int(plist.size()); ++i) + for (int i = 0; i < int(plist.size()); ++i) { pIndex[plist[i]] = i; + } hasUnknowns = true; } @@ -1606,8 +1847,9 @@ void System::initSolution(Algorithm alg) // system reduction specified in the previous step isInit = false; - if (!hasUnknowns) + if (!hasUnknowns) { return; + } // storing reference configuration setReference(); @@ -1615,15 +1857,17 @@ void System::initSolution(Algorithm alg) // diagnose conflicting or redundant constraints if (!hasDiagnosis) { diagnose(alg); - if (!hasDiagnosis) + if (!hasDiagnosis) { return; + } } std::vector clistR; if (!redundant.empty()) { for (std::vector::const_iterator constr = clist.begin(); constr != clist.end(); ++constr) { - if (redundant.count(*constr) == 0) + if (redundant.count(*constr) == 0) { clistR.push_back(*constr); + } } } else { @@ -1632,8 +1876,9 @@ void System::initSolution(Algorithm alg) // partitioning into decoupled components Graph g; - for (int i = 0; i < int(plist.size() + clistR.size()); i++) + for (int i = 0; i < int(plist.size() + clistR.size()); i++) { boost::add_vertex(g); + } int cvtid = int(plist.size()); for (std::vector::const_iterator constr = clistR.begin(); constr != clistR.end(); @@ -1641,15 +1886,17 @@ void System::initSolution(Algorithm alg) VEC_pD& cparams = c2p[*constr]; for (VEC_pD::const_iterator param = cparams.begin(); param != cparams.end(); ++param) { MAP_pD_I::const_iterator it = pIndex.find(*param); - if (it != pIndex.end()) + if (it != pIndex.end()) { boost::add_edge(cvtid, it->second, g); + } } } VEC_I components(boost::num_vertices(g)); int componentsSize = 0; - if (!components.empty()) + if (!components.empty()) { componentsSize = boost::connected_components(g, &components[0]); + } // identification of equality constraints and parameter reduction std::set reducedConstrs;// constraints that will be eliminated through reduction @@ -1670,17 +1917,19 @@ void System::initSolution(Algorithm alg) double* p_kept = reducedParams[it1->second]; double* p_replaced = reducedParams[it2->second]; for (int i = 0; i < int(plist.size()); ++i) { - if (reducedParams[i] == p_replaced) + if (reducedParams[i] == p_replaced) { reducedParams[i] = p_kept; + } } } } } - for (int i = 0; i < int(plist.size()); ++i) + for (int i = 0; i < int(plist.size()); ++i) { if (plist[i] != reducedParams[i]) { int cid = components[i]; reductionmaps[cid][plist[i]] = reducedParams[i]; } + } } clists.clear(); // destroy any lists @@ -1708,18 +1957,22 @@ void System::initSolution(Algorithm alg) for (std::vector::const_iterator constr = clists[cid].begin(); constr != clists[cid].end(); ++constr) { - if ((*constr)->getTag() >= 0) + if ((*constr)->getTag() >= 0) { clist0.push_back(*constr); - else// move or distance from reference constraints + } + else {// move or distance from reference constraints clist1.push_back(*constr); + } } subSystems.push_back(nullptr); subSystemsAux.push_back(nullptr); - if (!clist0.empty()) + if (!clist0.empty()) { subSystems[cid] = new SubSystem(clist0, plists[cid], reductionmaps[cid]); - if (!clist1.empty()) + } + if (!clist1.empty()) { subSystemsAux[cid] = new SubSystem(clist1, plists[cid], reductionmaps[cid]); + } } isInit = true; @@ -1729,8 +1982,9 @@ void System::setReference() { reference.clear(); reference.reserve(plist.size()); - for (VEC_pD::const_iterator param = plist.begin(); param != plist.end(); ++param) + for (VEC_pD::const_iterator param = plist.begin(); param != plist.end(); ++param) { reference.push_back(**param); + } } void System::resetToReference() @@ -1738,8 +1992,9 @@ void System::resetToReference() if (reference.size() == plist.size()) { VEC_D::const_iterator ref = reference.begin(); VEC_pD::iterator param = plist.begin(); - for (; ref != reference.end(); ++ref, ++param) + for (; ref != reference.end(); ++ref, ++param) { **param = *ref; + } } } @@ -1752,8 +2007,9 @@ int System::solve(VEC_pD& params, bool isFine, Algorithm alg, bool isRedundantso int System::solve(bool isFine, Algorithm alg, bool isRedundantsolving) { - if (!isInit) + if (!isInit) { return Failed; + } bool isReset = false; // return success by default in order to permit coincidence constraints to be applied @@ -1764,13 +2020,16 @@ int System::solve(bool isFine, Algorithm alg, bool isRedundantsolving) resetToReference(); isReset = true; } - if (subSystems[cid] && subSystemsAux[cid]) + if (subSystems[cid] && subSystemsAux[cid]) { res = std::max(res, solve(subSystems[cid], subSystemsAux[cid], isFine, isRedundantsolving)); - else if (subSystems[cid]) + } + else if (subSystems[cid]) { res = std::max(res, solve(subSystems[cid], isFine, alg, isRedundantsolving)); - else if (subSystemsAux[cid]) + } + else if (subSystemsAux[cid]) { res = std::max(res, solve(subSystemsAux[cid], isFine, alg, isRedundantsolving)); + } } if (res == Success) { for (std::set::const_iterator constr = redundant.begin(); @@ -1791,14 +2050,18 @@ int System::solve(bool isFine, Algorithm alg, bool isRedundantsolving) int System::solve(SubSystem* subsys, bool isFine, Algorithm alg, bool isRedundantsolving) { - if (alg == BFGS) + if (alg == BFGS) { return solve_BFGS(subsys, isFine, isRedundantsolving); - else if (alg == LevenbergMarquardt) + } + else if (alg == LevenbergMarquardt) { return solve_LM(subsys, isRedundantsolving); - else if (alg == DogLeg) + } + else if (alg == DogLeg) { return solve_DL(subsys, isRedundantsolving); - else + } + else { return Failed; + } } int System::solve_BFGS(SubSystem* subsys, bool /*isFine*/, bool isRedundantsolving) @@ -1808,8 +2071,9 @@ int System::solve_BFGS(SubSystem* subsys, bool /*isFine*/, bool isRedundantsolvi #endif int xsize = subsys->pSize(); - if (xsize == 0) + if (xsize == 0) { return Success; + } subsys->redirectParams(); @@ -1883,8 +2147,9 @@ int System::solve_BFGS(SubSystem* subsys, bool /*isFine*/, bool isRedundantsolvi double hty = h.dot(y); // make sure that hty is never 0 - if (hty == 0) + if (hty == 0) { hty = .0000000001; + } Dy = D * y; @@ -1914,10 +2179,12 @@ int System::solve_BFGS(SubSystem* subsys, bool /*isFine*/, bool isRedundantsolvi subsys->revertParams(); - if (err <= smallF) + if (err <= smallF) { return Success; - if (h.norm() <= (isRedundantsolving ? convergenceRedundant : convergence)) + } + if (h.norm() <= (isRedundantsolving ? convergenceRedundant : convergence)) { return Converged; + } return Failed; } @@ -1930,8 +2197,9 @@ int System::solve_LM(SubSystem* subsys, bool isRedundantsolving) int xsize = subsys->pSize(); int csize = subsys->cSize(); - if (xsize == 0) + if (xsize == 0) { return Success; + } Eigen::VectorXd e(csize), e_new(csize);// vector of all function errors (every constraint is one function) @@ -1999,16 +2267,18 @@ int System::solve_LM(SubSystem* subsys, bool isRedundantsolving) } // compute initial damping factor - if (iter == 0) + if (iter == 0) { mu = tau * diag_A.lpNorm(); + } double h_norm; // determine increment using adaptive damping int k = 0; while (k < 50) { // augment normal equations A = A+uI - for (int i = 0; i < xsize; ++i) + for (int i = 0; i < xsize; ++i) { A(i, i) += mu; + } // solve augmented functions A*h=-g h = A.fullPivLu().solve(g); @@ -2019,8 +2289,9 @@ int System::solve_LM(SubSystem* subsys, bool isRedundantsolving) // restrict h according to maxStep double scale = subsys->maxStep(h); - if (scale < 1.) + if (scale < 1.) { h *= scale; + } // compute par's new estimate and ||d_par||^2 x_new = x + h; @@ -2060,8 +2331,9 @@ int System::solve_LM(SubSystem* subsys, bool isRedundantsolving) mu *= nu; nu *= 2.0; - for (int i = 0; i < xsize; ++i)// restore diagonal J^T J entries + for (int i = 0; i < xsize; ++i) {// restore diagonal J^T J entries A(i, i) = diag_A(i); + } k++; } @@ -2081,8 +2353,9 @@ int System::solve_LM(SubSystem* subsys, bool isRedundantsolving) } } - if (iter >= maxIterNumber) + if (iter >= maxIterNumber) { stop = 5; + } subsys->revertParams(); @@ -2103,8 +2376,9 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving) int xsize = subsys->pSize(); int csize = subsys->cSize(); - if (xsize == 0) + if (xsize == 0) { return Success; + } int maxIterNumber = (isRedundantsolving @@ -2154,14 +2428,18 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving) while (!stop) { // check if finished - if (fx_inf <= tolf)// Success + if (fx_inf <= tolf) {// Success stop = 1; - else if (g_inf <= tolg) + } + else if (g_inf <= tolg) { stop = 2; - else if (delta <= tolx * (tolx + x.norm())) + } + else if (delta <= tolx * (tolx + x.norm())) { stop = 2; - else if (iter >= maxIterNumber) + } + else if (iter >= maxIterNumber) { stop = 4; + } else if (err > divergingLim || err != err) {// check for diverging and NaN stop = 6; } @@ -2186,8 +2464,9 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving) } double rel_error = (Jx * h_gn + fx).norm() / fx.norm(); - if (rel_error > 1e15) + if (rel_error > 1e15) { break; + } // compute the dogleg step if (h_gn.norm() < delta) { @@ -2208,10 +2487,12 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving) double gb = (h_sd.transpose() * b).norm(); double c = (delta + h_sd.norm()) * (delta - h_sd.norm()); - if (gb > 0) + if (gb > 0) { beta = c / (gb + sqrt(gb * gb + c * bb)); - else + } + else { beta = (sqrt(gb * gb + c * bb) - gb) / bb; + } // and update h_dl and dL with beta h_dl = h_sd + beta * b; @@ -2219,8 +2500,9 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving) } // see if we are already finished - if (stop) + if (stop) { break; + } // it didn't work in some tests // // restrict h_dl according to maxStep @@ -2252,8 +2534,9 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving) g_inf = g.lpNorm(); fx_inf = fx.lpNorm(); } - else + else { rho = -1; + } // update delta if (fabs(rho - 1.) < 0.2 && h_dl.norm() > delta / 3. && reduce <= 0) { @@ -2266,8 +2549,9 @@ int System::solve_DL(SubSystem* subsys, bool isRedundantsolving) nu = 2 * nu; reduce = 2; } - else + else { reduce--; + } if (debugMode == IterationLevel) { std::stringstream stream; @@ -4446,8 +4730,11 @@ int System::solve(SubSystem* subsysA, SubSystem* subsysB, bool /*isFine*/, bool std::sort(plistB.begin(), plistB.end()); VEC_pD::const_iterator it; - it = std::set_union( - plistA.begin(), plistA.end(), plistB.begin(), plistB.end(), plistAB.begin()); + it = std::set_union(plistA.begin(), + plistA.end(), + plistB.begin(), + plistB.end(), + plistAB.begin()); plistAB.resize(it - plistAB.begin()); } int xsize = plistAB.size(); @@ -4488,8 +4775,9 @@ int System::solve(SubSystem* subsysA, SubSystem* subsysB, bool /*isFine*/, bool lambda.setZero(); for (int iter = 1; iter < maxIterNumber; iter++) { int status = qp_eq(B, grad, JA, resA, xdir, Y, Z); - if (status) + if (status) { break; + } x0 = x; lambda0 = lambda; @@ -4540,19 +4828,22 @@ int System::solve(SubSystem* subsysA, SubSystem* subsysB, bool /*isFine*/, bool subsysB->setParams(plistAB, x); subsysA->calcResidual(resA); f = subsysB->error() + mu * resA.lpNorm<1>(); - if (f < f0 + eta * alpha * deriv) + if (f < f0 + eta * alpha * deriv) { break; + } } alpha = tau * alpha; - if (alpha < 1e-8)// let the linesearch fail + if (alpha < 1e-8) {// let the linesearch fail alpha = 0.; + } x = x0 + alpha * xdir; subsysA->setParams(plistAB, x); subsysB->setParams(plistAB, x); subsysA->calcResidual(resA); f = subsysB->error() + mu * resA.lpNorm<1>(); - if (alpha < 1e-8)// let the linesearch fail + if (alpha < 1e-8) {// let the linesearch fail break; + } } lambda = lambda0 + alpha * lambdadir; } @@ -4577,19 +4868,25 @@ int System::solve(SubSystem* subsysA, SubSystem* subsysB, bool /*isFine*/, bool } double err = subsysA->error(); - if (h.norm() <= (isRedundantsolving ? convergenceRedundant : convergence) && err <= smallF) + if (h.norm() <= (isRedundantsolving ? convergenceRedundant : convergence) + && err <= smallF) { break; - if (err > divergingLim || err != err)// check for diverging and NaN + } + if (err > divergingLim || err != err) {// check for diverging and NaN break; + } } int ret; - if (subsysA->error() <= smallF) + if (subsysA->error() <= smallF) { ret = Success; - else if (h.norm() <= (isRedundantsolving ? convergenceRedundant : convergence)) + } + else if (h.norm() <= (isRedundantsolving ? convergenceRedundant : convergence)) { ret = Converged; - else + } + else { ret = Failed; + } subsysA->revertParams(); subsysB->revertParams(); @@ -4599,14 +4896,17 @@ int System::solve(SubSystem* subsysA, SubSystem* subsysB, bool /*isFine*/, bool void System::applySolution() { for (int cid = 0; cid < int(subSystems.size()); cid++) { - if (subSystemsAux[cid]) + if (subSystemsAux[cid]) { subSystemsAux[cid]->applySolution(); - if (subSystems[cid]) + } + if (subSystems[cid]) { subSystems[cid]->applySolution(); + } for (MAP_pD_pD::const_iterator it = reductionmaps[cid].begin(); it != reductionmaps[cid].end(); - ++it) + ++it) { *(it->first) = *(it->second); + } } } @@ -4615,8 +4915,10 @@ void System::undoSolution() resetToReference(); } -void System::makeReducedJacobian(Eigen::MatrixXd& J, std::map& jacobianconstraintmap, - GCS::VEC_pD& pdiagnoselist, std::map& tagmultiplicity) +void System::makeReducedJacobian(Eigen::MatrixXd& J, + std::map& jacobianconstraintmap, + GCS::VEC_pD& pdiagnoselist, + std::map& tagmultiplicity) { // construct specific parameter list for diagonose ignoring driven constraint parameters for (int j = 0; j < int(plist.size()); j++) { @@ -4643,17 +4945,20 @@ void System::makeReducedJacobian(Eigen::MatrixXd& J, std::map& jacobia } // parallel processing: create tag multiplicity map - if (tagmultiplicity.find((*constr)->getTag()) == tagmultiplicity.end()) + if (tagmultiplicity.find((*constr)->getTag()) == tagmultiplicity.end()) { tagmultiplicity[(*constr)->getTag()] = 0; - else + } + else { tagmultiplicity[(*constr)->getTag()]++; + } jacobianconstraintmap[jacobianconstraintcount - 1] = allcount - 1; } } - if (jacobianconstraintcount == 0)// only driven constraints + if (jacobianconstraintcount == 0) {// only driven constraints J.resize(0, 0); + } } int System::diagnose(Algorithm alg) @@ -4730,54 +5035,55 @@ int System::diagnose(Algorithm alg) hasDiagnosis = true; dofs = pdiagnoselist.size(); - if (J.rows() > 0) + if (J.rows() > 0) { emptyDiagnoseMatrix = false; + } - // There is a legacy decision to use QR decomposition. I (abdullah) do not know all the - // consideration taken in that decisions. I see that: - // - QR decomposition is able to provide information about the rank and - // redundant/conflicting - // constraints - // - The QR decomposition of J and the QR decomposition of the transpose of J are unrelated - // (for reasons see below): - // https://mathoverflow.net/questions/338729/translate-between-qr-decomposition-of-a-and-a-transpose - // - QR is cheaper than a SVD decomposition - // - QR is more expensive than a rank revealing LU factorization - // - QR is less stable than SVD with respect to rank - // - It is unclear whether it is possible to obtain information about redundancy with SVD - // and LU + // There is a legacy decision to use QR decomposition. I (abdullah) do not know all the + // consideration taken in that decisions. I see that: + // - QR decomposition is able to provide information about the rank and + // redundant/conflicting + // constraints + // - The QR decomposition of J and the QR decomposition of the transpose of J are unrelated + // (for reasons see below): + // https://mathoverflow.net/questions/338729/translate-between-qr-decomposition-of-a-and-a-transpose + // - QR is cheaper than a SVD decomposition + // - QR is more expensive than a rank revealing LU factorization + // - QR is less stable than SVD with respect to rank + // - It is unclear whether it is possible to obtain information about redundancy with SVD + // and LU - // Given this legacy decision, the following is observed: - // - A = QR decomposition can be used for the diagonise of dependency of the "columns" of A. - // the reason is that matrix R is upper triangular with columns of A showing the - // dependencies. - // - The same does not apply to the "rows". - // - For this reason, to enable a full diagnose of constraints, a QR decomposition must be - // done - // on the transpose of the Jacobian matrix (J), this is JT. + // Given this legacy decision, the following is observed: + // - A = QR decomposition can be used for the diagonise of dependency of the "columns" of A. + // the reason is that matrix R is upper triangular with columns of A showing the + // dependencies. + // - The same does not apply to the "rows". + // - For this reason, to enable a full diagnose of constraints, a QR decomposition must be + // done + // on the transpose of the Jacobian matrix (J), this is JT. - // Eigen capabilities: - // - If Eigen full pivoting QR decomposition is used, it is possible to track the rows of JT - // during the decomposition. This can be leveraged to identify a set of independent rows - // of JT (geometry) that form a rank N basis. However, because the R matrix is of the JT - // decomposition and not the J decomposition, it is not possible to reduce the system to - // identify exactly which rows are dependent. - // - The effect is that it provides a set of parameters of geometry that are not constraint, - // but it does not identify ALL geometries that are not fixed. - // - If SpareQR is used, then it is not possible to track the rows of JT during - // decomposition. - // I do not know if it is still possible to obtain geometry information at all from - // SparseQR. After several years these questions remain open: - // https://stackoverflow.com/questions/49009771/getting-rows-transpositions-with-sparse-qr - // https://forum.kde.org/viewtopic.php?f=74&t=151239 - // - // Implementation below: - // - // Two QR decompositions are used below. One for diagnosis of constraints and a second one - // for diagnosis of parameters, i.e. to identify whether the parameter is fully constraint - // (independent) or not (i.e. it is dependent). + // Eigen capabilities: + // - If Eigen full pivoting QR decomposition is used, it is possible to track the rows of JT + // during the decomposition. This can be leveraged to identify a set of independent rows + // of JT (geometry) that form a rank N basis. However, because the R matrix is of the JT + // decomposition and not the J decomposition, it is not possible to reduce the system to + // identify exactly which rows are dependent. + // - The effect is that it provides a set of parameters of geometry that are not constraint, + // but it does not identify ALL geometries that are not fixed. + // - If SpareQR is used, then it is not possible to track the rows of JT during + // decomposition. + // I do not know if it is still possible to obtain geometry information at all from + // SparseQR. After several years these questions remain open: + // https://stackoverflow.com/questions/49009771/getting-rows-transpositions-with-sparse-qr + // https://forum.kde.org/viewtopic.php?f=74&t=151239 + // + // Implementation below: + // + // Two QR decompositions are used below. One for diagnosis of constraints and a second one + // for diagnosis of parameters, i.e. to identify whether the parameter is fully constraint + // (independent) or not (i.e. it is dependent). - // QR decomposition method selection: SparseQR vs DenseQR + // QR decomposition method selection: SparseQR vs DenseQR #ifndef EIGEN_SPARSEQR_COMPATIBLE if (qrAlgorithm == EigenSparseQR) { @@ -4841,8 +5147,9 @@ int System::diagnose(Algorithm alg) constrNum, rank, nonredundantconstrNum); - if (paramsNum == rank && nonredundantconstrNum > rank)// over-constrained + if (paramsNum == rank && nonredundantconstrNum > rank) {// over-constrained dofs = paramsNum - nonredundantconstrNum; + } } } #ifdef PROFILE_DIAGNOSE @@ -4886,8 +5193,13 @@ int System::diagnose(Algorithm alg) pdiagnoselist, /*silent=*/true); - makeSparseQRDecomposition( - J, jacobianconstraintmap, SqrJT, rank, R, /*transposed=*/true, /*silent=*/false); + makeSparseQRDecomposition(J, + jacobianconstraintmap, + SqrJT, + rank, + R, + /*transposed=*/true, + /*silent=*/false); int paramsNum = SqrJT.rows(); int constrNum = SqrJT.cols(); @@ -4911,8 +5223,9 @@ int System::diagnose(Algorithm alg) rank, nonredundantconstrNum); - if (paramsNum == rank && nonredundantconstrNum > rank)// over-constrained + if (paramsNum == rank && nonredundantconstrNum > rank) {// over-constrained dofs = paramsNum - nonredundantconstrNum; + } } } @@ -4931,13 +5244,17 @@ int System::diagnose(Algorithm alg) void System::makeDenseQRDecomposition(const Eigen::MatrixXd& J, const std::map& jacobianconstraintmap, - Eigen::FullPivHouseholderQR& qrJT, int& rank, - Eigen::MatrixXd& R, bool transposeJ, bool silent) + Eigen::FullPivHouseholderQR& qrJT, + int& rank, + Eigen::MatrixXd& R, + bool transposeJ, + bool silent) { #ifdef _GCS_DEBUG - if (!silent) + if (!silent) { SolverReportingManager::Manager().LogMatrix("J", J); + } #endif #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX @@ -4953,10 +5270,12 @@ void System::makeDenseQRDecomposition(const Eigen::MatrixXd& J, if (J.rows() > 0) { Eigen::MatrixXd JG; - if (transposeJ) + if (transposeJ) { JG = J.topRows(jacobianconstraintmap.size()).transpose(); - else + } + else { JG = J.topRows(jacobianconstraintmap.size()); + } if (JG.rows() > 0 && JG.cols() > 0) { @@ -4967,10 +5286,12 @@ void System::makeDenseQRDecomposition(const Eigen::MatrixXd& J, qrJT.setThreshold(qrpivotThreshold); rank = qrJT.rank(); - if (colsNum >= rowsNum) + if (colsNum >= rowsNum) { R = qrJT.matrixQR().triangularView(); - else + } + else { R = qrJT.matrixQR().topRows(colsNum).triangularView(); + } } else { rowsNum = JG.rows(); @@ -5001,9 +5322,13 @@ void System::makeDenseQRDecomposition(const Eigen::MatrixXd& J, #ifdef EIGEN_SPARSEQR_COMPATIBLE void System::makeSparseQRDecomposition( - const Eigen::MatrixXd& J, const std::map& jacobianconstraintmap, - Eigen::SparseQR, Eigen::COLAMDOrdering>& SqrJT, int& rank, - Eigen::MatrixXd& R, bool transposeJ, bool silent) + const Eigen::MatrixXd& J, + const std::map& jacobianconstraintmap, + Eigen::SparseQR, Eigen::COLAMDOrdering>& SqrJT, + int& rank, + Eigen::MatrixXd& R, + bool transposeJ, + bool silent) { Eigen::SparseMatrix SJ; @@ -5015,8 +5340,9 @@ void System::makeSparseQRDecomposition( SJ.makeCompressed(); #ifdef _GCS_DEBUG - if (!silent) + if (!silent) { SolverReportingManager::Manager().LogMatrix("J", J); + } #endif #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX @@ -5032,10 +5358,12 @@ void System::makeSparseQRDecomposition( if (SJ.rows() > 0) { Eigen::SparseMatrix SJG; - if (transposeJ) + if (transposeJ) { SJG = SJ.topRows(jacobianconstraintmap.size()).transpose(); - else + } + else { SJG = SJ.topRows(jacobianconstraintmap.size()); + } if (SJG.rows() > 0 && SJG.cols() > 0) { SqrJT.compute(SJG); @@ -5052,10 +5380,12 @@ void System::makeSparseQRDecomposition( SqrJT.setPivotThreshold(qrpivotThreshold); rank = SqrJT.rank(); - if (colsNum >= rowsNum) + if (colsNum >= rowsNum) { R = SqrJT.matrixR().triangularView(); - else + } + else { R = SqrJT.matrixR().topRows(colsNum).triangularView(); + } #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX R2 = SqrJT.matrixR(); @@ -5067,8 +5397,9 @@ void System::makeSparseQRDecomposition( } } - if (debugMode == IterationLevel && !silent) + if (debugMode == IterationLevel && !silent) { SolverReportingManager::Manager().LogQRSystemInformation(*this, rowsNum, colsNum, rank); + } #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX if (J.rows() > 0 && !silent) { @@ -5087,7 +5418,8 @@ void System::makeSparseQRDecomposition( void System::identifyDependentParametersDenseQR(const Eigen::MatrixXd& J, const std::map& jacobianconstraintmap, - const GCS::VEC_pD& pdiagnoselist, bool silent) + const GCS::VEC_pD& pdiagnoselist, + bool silent) { Eigen::FullPivHouseholderQR qrJ; Eigen::MatrixXd Rparams; @@ -5102,7 +5434,8 @@ void System::identifyDependentParametersDenseQR(const Eigen::MatrixXd& J, #ifdef EIGEN_SPARSEQR_COMPATIBLE void System::identifyDependentParametersSparseQR(const Eigen::MatrixXd& J, const std::map& jacobianconstraintmap, - const GCS::VEC_pD& pdiagnoselist, bool silent) + const GCS::VEC_pD& pdiagnoselist, + bool silent) { Eigen::SparseQR, Eigen::COLAMDOrdering> SqrJ; Eigen::MatrixXd Rparams; @@ -5122,8 +5455,11 @@ void System::identifyDependentParametersSparseQR(const Eigen::MatrixXd& J, #endif template -void System::identifyDependentParameters(T& qrJ, Eigen::MatrixXd& Rparams, int rank, - const GCS::VEC_pD& pdiagnoselist, bool silent) +void System::identifyDependentParameters(T& qrJ, + Eigen::MatrixXd& Rparams, + int rank, + const GCS::VEC_pD& pdiagnoselist, + bool silent) { (void)silent;// silent is only used in debug code, but it is important as Base::Console is not // thread-safe. Removes warning in non Debug mode. @@ -5134,8 +5470,9 @@ void System::identifyDependentParameters(T& qrJ, Eigen::MatrixXd& Rparams, int r eliminateNonZerosOverPivotInUpperTriangularMatrix(Rparams, rank); #ifdef _GCS_DEBUG - if (!silent) + if (!silent) { SolverReportingManager::Manager().LogMatrix("Rparams_nonzeros_over_pilot", Rparams); + } #endif pDependentParametersGroups.resize(qrJ.cols() - rank); @@ -5167,8 +5504,10 @@ void System::identifyDependentParameters(T& qrJ, Eigen::MatrixXd& Rparams, int r } void System::identifyDependentGeometryParametersInTransposedJacobianDenseQRDecomposition( - const Eigen::FullPivHouseholderQR& qrJT, const GCS::VEC_pD& pdiagnoselist, - int paramsNum, int rank) + const Eigen::FullPivHouseholderQR& qrJT, + const GCS::VEC_pD& pdiagnoselist, + int paramsNum, + int rank) { // DETECTING CONSTRAINT SOLVER PARAMETERS // @@ -5189,8 +5528,9 @@ void System::identifyDependentGeometryParametersInTransposedJacobianDenseQRDecom // P.J.P' = Q.R see https://eigen.tuxfamily.org/dox/classEigen_1_1FullPivHouseholderQR.html const MatrixIndexType rowTranspositions = qrJT.rowsTranspositions(); - for (int k = 0; k < rank; ++k) + for (int k = 0; k < rank; ++k) { rowPermutations.applyTranspositionOnTheRight(k, rowTranspositions.coeff(k)); + } #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX std::stringstream stream; @@ -5231,13 +5571,15 @@ void System::identifyDependentGeometryParametersInTransposedJacobianDenseQRDecom stream.flush(); stream << "Indep params: ["; - for (auto indep : indepParamCols) + for (auto indep : indepParamCols) { stream << indep; + } stream << "]" << std::endl; stream << "Dep params: ["; - for (auto dep : depParamCols) + for (auto dep : depParamCols) { stream << dep; + } stream << "]" << std::endl; tmp = stream.str(); @@ -5268,9 +5610,15 @@ void System::eliminateNonZerosOverPivotInUpperTriangularMatrix(Eigen::MatrixXd& template void System::identifyConflictingRedundantConstraints( - Algorithm alg, const T& qrJT, const std::map& jacobianconstraintmap, - const std::map& tagmultiplicity, GCS::VEC_pD& pdiagnoselist, Eigen::MatrixXd& R, - int constrNum, int rank, int& nonredundantconstrNum) + Algorithm alg, + const T& qrJT, + const std::map& jacobianconstraintmap, + const std::map& tagmultiplicity, + GCS::VEC_pD& pdiagnoselist, + Eigen::MatrixXd& R, + int constrNum, + int rank, + int& nonredundantconstrNum) { eliminateNonZerosOverPivotInUpperTriangularMatrix(R, rank); @@ -5291,7 +5639,8 @@ void System::identifyConflictingRedundantConstraints( // Augment the information regarding the group of constraints that are conflicting or redundant. if (debugMode == IterationLevel) { SolverReportingManager::Manager().LogGroupOfConstraints( - "Analysing groups of constraints of special interest", conflictGroups); + "Analysing groups of constraints of special interest", + conflictGroups); } // try to remove the conflicting constraints and solve the @@ -5313,16 +5662,18 @@ void System::identifyConflictingRedundantConstraints( bool isinternalalignment = (constr->isInternalAlignment() == Constraint::Alignment::InternalAlignment); bool priorityconstraint = (constr->getTag() == 0); - if (!priorityconstraint - && !isinternalalignment)// exclude constraints tagged with zero and internal - // alignment + if (!priorityconstraint && !isinternalalignment) {// exclude constraints tagged + // with zero and internal + // alignment conflictingMap[constr].insert(i); + } } } } - if (conflictingMap.empty()) + if (conflictingMap.empty()) { break; + } int maxPopularity = 0; Constraint* mostPopular = nullptr; @@ -5395,8 +5746,9 @@ void System::identifyConflictingRedundantConstraints( clistTmp.reserve(clist.size()); for (std::vector::iterator constr = clist.begin(); constr != clist.end(); ++constr) { - if ((*constr)->isDriving() && skipped.count(*constr) == 0) + if ((*constr)->isDriving() && skipped.count(*constr) == 0) { clistTmp.push_back(*constr); + } } SubSystem* subSysTmp = new SubSystem(clistTmp, pdiagnoselist); @@ -5425,8 +5777,9 @@ void System::identifyConflictingRedundantConstraints( constr != skipped.end(); ++constr) { double err = (*constr)->error(); - if (err * err < convergenceRedundant) + if (err * err < convergenceRedundant) { redundant.insert(*constr); + } } resetToReference(); @@ -5452,10 +5805,12 @@ void System::identifyConflictingRedundantConstraints( break; } } - if (!isRedundant) + if (!isRedundant) { conflictGroups.push_back(conflictGroupsOrig[i]); - else + } + else { constrNum--; + } } } delete subSysTmp; @@ -5467,9 +5822,10 @@ void System::identifyConflictingRedundantConstraints( bool isinternalalignment = (conflictGroups[i][j]->isInternalAlignment() == Constraint::Alignment::InternalAlignment); if (conflictGroups[i][j]->getTag() != 0 - && !isinternalalignment)// exclude constraints tagged with zero and internal - // alignment + && !isinternalalignment) {// exclude constraints tagged with zero and internal + // alignment conflictingTagsSet.insert(conflictGroups[i][j]->getTag()); + } } } @@ -5485,15 +5841,19 @@ void System::identifyConflictingRedundantConstraints( } // remove tags represented at least in one non-redundant constraint - for (std::vector::iterator constr = clist.begin(); constr != clist.end(); ++constr) - if (redundant.count(*constr) == 0) + for (std::vector::iterator constr = clist.begin(); constr != clist.end(); + ++constr) { + if (redundant.count(*constr) == 0) { redundantTagsSet.erase((*constr)->getTag()); + } + } redundantTags.resize(redundantTagsSet.size()); std::copy(redundantTagsSet.begin(), redundantTagsSet.end(), redundantTags.begin()); - for (auto r : redundantTagsSet) + for (auto r : redundantTagsSet) { partiallyRedundantTagsSet.erase(r); + } partiallyRedundantTags.resize(partiallyRedundantTagsSet.size()); std::copy(partiallyRedundantTagsSet.begin(), @@ -5554,8 +5914,9 @@ double lineSearch(SubSystem* subsys, Eigen::VectorXd& xdir) f2 = subsys->error(); } else if (f2 > f3) { - if (alpha3 >= alphaMax) + if (alpha3 >= alphaMax) { break; + } // If f2 is greater than f3 then we increase alpha2 and alpha3 away from f1 // Effectively both are lengthened by a factor of two. alpha2 = alpha3; @@ -5570,14 +5931,17 @@ double lineSearch(SubSystem* subsys, Eigen::VectorXd& xdir) alphaStar = alpha2 + ((alpha2 - alpha1) * (f1 - f3)) / (3 * (f1 - 2 * f2 + f3)); // Guarantee that the new alphaStar is within the bracket - if (alphaStar >= alpha3 || alphaStar <= alpha1) + if (alphaStar >= alpha3 || alphaStar <= alpha1) { alphaStar = alpha2; + } - if (alphaStar > alphaMax) + if (alphaStar > alphaMax) { alphaStar = alphaMax; + } - if (alphaStar != alphaStar) + if (alphaStar != alphaStar) { alphaStar = 0.; + } // Take a final step to alphaStar x = x0 + alphaStar * xdir; @@ -5590,8 +5954,9 @@ double lineSearch(SubSystem* subsys, Eigen::VectorXd& xdir) void free(VEC_pD& doublevec) { for (VEC_pD::iterator it = doublevec.begin(); it != doublevec.end(); ++it) { - if (*it) + if (*it) { delete *it; + } } doublevec.clear(); } @@ -5644,8 +6009,9 @@ void free(std::vector& constrvec) void free(std::vector& subsysvec) { for (std::vector::iterator it = subsysvec.begin(); it != subsysvec.end(); ++it) { - if (*it) + if (*it) { delete *it; + } } } diff --git a/src/Mod/Sketcher/App/planegcs/GCS.h b/src/Mod/Sketcher/App/planegcs/GCS.h index b8a379bfd9..fb8f28312d 100644 --- a/src/Mod/Sketcher/App/planegcs/GCS.h +++ b/src/Mod/Sketcher/App/planegcs/GCS.h @@ -147,33 +147,47 @@ private: int solve_LM(SubSystem* subsys, bool isRedundantsolving = false); int solve_DL(SubSystem* subsys, bool isRedundantsolving = false); - void makeReducedJacobian(Eigen::MatrixXd& J, std::map& jacobianconstraintmap, - GCS::VEC_pD& pdiagnoselist, std::map& tagmultiplicity); + void makeReducedJacobian(Eigen::MatrixXd& J, + std::map& jacobianconstraintmap, + GCS::VEC_pD& pdiagnoselist, + std::map& tagmultiplicity); void makeDenseQRDecomposition(const Eigen::MatrixXd& J, const std::map& jacobianconstraintmap, - Eigen::FullPivHouseholderQR& qrJT, int& rank, - Eigen::MatrixXd& R, bool transposeJ = true, bool silent = false); + Eigen::FullPivHouseholderQR& qrJT, + int& rank, + Eigen::MatrixXd& R, + bool transposeJ = true, + bool silent = false); #ifdef EIGEN_SPARSEQR_COMPATIBLE void makeSparseQRDecomposition( - const Eigen::MatrixXd& J, const std::map& jacobianconstraintmap, - Eigen::SparseQR, Eigen::COLAMDOrdering>& SqrJT, int& rank, - Eigen::MatrixXd& R, bool transposeJ = true, bool silent = false); + const Eigen::MatrixXd& J, + const std::map& jacobianconstraintmap, + Eigen::SparseQR, Eigen::COLAMDOrdering>& SqrJT, + int& rank, + Eigen::MatrixXd& R, + bool transposeJ = true, + bool silent = false); #endif // This function name is long for a reason: // - Only for DenseQR // - Only for Transposed Jacobian QR decomposition void identifyDependentGeometryParametersInTransposedJacobianDenseQRDecomposition( - const Eigen::FullPivHouseholderQR& qrJT, const GCS::VEC_pD& pdiagnoselist, - int paramsNum, int rank); + const Eigen::FullPivHouseholderQR& qrJT, + const GCS::VEC_pD& pdiagnoselist, + int paramsNum, + int rank); template - void identifyConflictingRedundantConstraints(Algorithm alg, const T& qrJT, + void identifyConflictingRedundantConstraints(Algorithm alg, + const T& qrJT, const std::map& jacobianconstraintmap, const std::map& tagmultiplicity, - GCS::VEC_pD& pdiagnoselist, Eigen::MatrixXd& R, - int constrNum, int rank, + GCS::VEC_pD& pdiagnoselist, + Eigen::MatrixXd& R, + int constrNum, + int rank, int& nonredundantconstrNum); void eliminateNonZerosOverPivotInUpperTriangularMatrix(Eigen::MatrixXd& R, int rank); @@ -181,16 +195,21 @@ private: #ifdef EIGEN_SPARSEQR_COMPATIBLE void identifyDependentParametersSparseQR(const Eigen::MatrixXd& J, const std::map& jacobianconstraintmap, - const GCS::VEC_pD& pdiagnoselist, bool silent = true); + const GCS::VEC_pD& pdiagnoselist, + bool silent = true); #endif void identifyDependentParametersDenseQR(const Eigen::MatrixXd& J, const std::map& jacobianconstraintmap, - const GCS::VEC_pD& pdiagnoselist, bool silent = true); + const GCS::VEC_pD& pdiagnoselist, + bool silent = true); template - void identifyDependentParameters(T& qrJ, Eigen::MatrixXd& Rparams, int rank, - const GCS::VEC_pD& pdiagnoselist, bool silent = true); + void identifyDependentParameters(T& qrJ, + Eigen::MatrixXd& Rparams, + int rank, + const GCS::VEC_pD& pdiagnoselist, + bool silent = true); #ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_ void extractSubsystem(SubSystem* subsys, bool isRedundantsolving); @@ -233,43 +252,90 @@ public: // basic constraints int addConstraintEqual( - double* param1, double* param2, int tagId = 0, bool driving = true, + double* param1, + double* param2, + int tagId = 0, + bool driving = true, Constraint::Alignment internalalignment = Constraint::Alignment::NoInternalAlignment); - int addConstraintProportional(double* param1, double* param2, double ratio, int tagId, + int addConstraintProportional(double* param1, + double* param2, + double ratio, + int tagId, bool driving = true); - int addConstraintDifference(double* param1, double* param2, double* difference, int tagId = 0, + int addConstraintDifference(double* param1, + double* param2, + double* difference, + int tagId = 0, bool driving = true); - int addConstraintP2PDistance(Point& p1, Point& p2, double* distance, int tagId = 0, + int addConstraintP2PDistance(Point& p1, + Point& p2, + double* distance, + int tagId = 0, bool driving = true); - int addConstraintP2PAngle(Point& p1, Point& p2, double* angle, double incrAngle, int tagId = 0, + int addConstraintP2PAngle(Point& p1, + Point& p2, + double* angle, + double incrAngle, + int tagId = 0, bool driving = true); - int addConstraintP2PAngle(Point& p1, Point& p2, double* angle, int tagId = 0, - bool driving = true); - int addConstraintP2LDistance(Point& p, Line& l, double* distance, int tagId = 0, + int + addConstraintP2PAngle(Point& p1, Point& p2, double* angle, int tagId = 0, bool driving = true); + int addConstraintP2LDistance(Point& p, + Line& l, + double* distance, + int tagId = 0, bool driving = true); int addConstraintPointOnLine(Point& p, Line& l, int tagId = 0, bool driving = true); - int addConstraintPointOnLine(Point& p, Point& lp1, Point& lp2, int tagId = 0, - bool driving = true); + int + addConstraintPointOnLine(Point& p, Point& lp1, Point& lp2, int tagId = 0, bool driving = true); int addConstraintPointOnPerpBisector(Point& p, Line& l, int tagId = 0, bool driving = true); - int addConstraintPointOnPerpBisector(Point& p, Point& lp1, Point& lp2, int tagId = 0, + int addConstraintPointOnPerpBisector(Point& p, + Point& lp1, + Point& lp2, + int tagId = 0, bool driving = true); int addConstraintParallel(Line& l1, Line& l2, int tagId = 0, bool driving = true); int addConstraintPerpendicular(Line& l1, Line& l2, int tagId = 0, bool driving = true); - int addConstraintPerpendicular(Point& l1p1, Point& l1p2, Point& l2p1, Point& l2p2, - int tagId = 0, bool driving = true); - int addConstraintL2LAngle(Line& l1, Line& l2, double* angle, int tagId = 0, + int addConstraintPerpendicular(Point& l1p1, + Point& l1p2, + Point& l2p1, + Point& l2p2, + int tagId = 0, + bool driving = true); + int + addConstraintL2LAngle(Line& l1, Line& l2, double* angle, int tagId = 0, bool driving = true); + int addConstraintL2LAngle(Point& l1p1, + Point& l1p2, + Point& l2p1, + Point& l2p2, + double* angle, + int tagId = 0, bool driving = true); - int addConstraintL2LAngle(Point& l1p1, Point& l1p2, Point& l2p1, Point& l2p2, double* angle, - int tagId = 0, bool driving = true); - int addConstraintAngleViaPoint(Curve& crv1, Curve& crv2, Point& p, double* angle, int tagId = 0, + int addConstraintAngleViaPoint(Curve& crv1, + Curve& crv2, + Point& p, + double* angle, + int tagId = 0, bool driving = true); int addConstraintMidpointOnLine(Line& l1, Line& l2, int tagId = 0, bool driving = true); - int addConstraintMidpointOnLine(Point& l1p1, Point& l1p2, Point& l2p1, Point& l2p2, - int tagId = 0, bool driving = true); - int addConstraintTangentCircumf(Point& p1, Point& p2, double* rd1, double* rd2, - bool internal = false, int tagId = 0, bool driving = true); - int addConstraintTangentAtBSplineKnot(BSpline& b, Line& l, unsigned int knotindex, - int tagId = 0, bool driving = true); + int addConstraintMidpointOnLine(Point& l1p1, + Point& l1p2, + Point& l2p1, + Point& l2p2, + int tagId = 0, + bool driving = true); + int addConstraintTangentCircumf(Point& p1, + Point& p2, + double* rd1, + double* rd2, + bool internal = false, + int tagId = 0, + bool driving = true); + int addConstraintTangentAtBSplineKnot(BSpline& b, + Line& l, + unsigned int knotindex, + int tagId = 0, + bool driving = true); // derived constraints int addConstraintP2PCoincident(Point& p1, Point& p2, int tagId = 0, bool driving = true); @@ -282,27 +348,50 @@ public: int addConstraintArcRules(Arc& a, int tagId = 0, bool driving = true); int addConstraintPointOnCircle(Point& p, Circle& c, int tagId = 0, bool driving = true); int addConstraintPointOnEllipse(Point& p, Ellipse& e, int tagId = 0, bool driving = true); - int addConstraintPointOnHyperbolicArc(Point& p, ArcOfHyperbola& e, int tagId = 0, + int addConstraintPointOnHyperbolicArc(Point& p, + ArcOfHyperbola& e, + int tagId = 0, bool driving = true); - int addConstraintPointOnParabolicArc(Point& p, ArcOfParabola& e, int tagId = 0, + int addConstraintPointOnParabolicArc(Point& p, + ArcOfParabola& e, + int tagId = 0, bool driving = true); - int addConstraintPointOnBSpline(Point& p, BSpline& b, double* pointparam, int tagId, + int addConstraintPointOnBSpline(Point& p, + BSpline& b, + double* pointparam, + int tagId, bool driving = true); int addConstraintArcOfEllipseRules(ArcOfEllipse& a, int tagId = 0, bool driving = true); int addConstraintCurveValue(Point& p, Curve& a, double* u, int tagId = 0, bool driving = true); int addConstraintArcOfHyperbolaRules(ArcOfHyperbola& a, int tagId = 0, bool driving = true); int addConstraintArcOfParabolaRules(ArcOfParabola& a, int tagId = 0, bool driving = true); int addConstraintPointOnArc(Point& p, Arc& a, int tagId = 0, bool driving = true); - int addConstraintPerpendicularLine2Arc(Point& p1, Point& p2, Arc& a, int tagId = 0, + int addConstraintPerpendicularLine2Arc(Point& p1, + Point& p2, + Arc& a, + int tagId = 0, bool driving = true); - int addConstraintPerpendicularArc2Line(Arc& a, Point& p1, Point& p2, int tagId = 0, + int addConstraintPerpendicularArc2Line(Arc& a, + Point& p1, + Point& p2, + int tagId = 0, bool driving = true); - int addConstraintPerpendicularCircle2Arc(Point& center, double* radius, Arc& a, int tagId = 0, + int addConstraintPerpendicularCircle2Arc(Point& center, + double* radius, + Arc& a, + int tagId = 0, bool driving = true); - int addConstraintPerpendicularArc2Circle(Arc& a, Point& center, double* radius, int tagId = 0, + int addConstraintPerpendicularArc2Circle(Arc& a, + Point& center, + double* radius, + int tagId = 0, bool driving = true); - int addConstraintPerpendicularArc2Arc(Arc& a1, bool reverse1, Arc& a2, bool reverse2, - int tagId = 0, bool driving = true); + int addConstraintPerpendicularArc2Arc(Arc& a1, + bool reverse1, + Arc& a2, + bool reverse2, + int tagId = 0, + bool driving = true); int addConstraintTangent(Line& l, Circle& c, int tagId = 0, bool driving = true); int addConstraintTangent(Line& l, Ellipse& e, int tagId = 0, bool driving = true); int addConstraintTangent(Line& l, Arc& a, int tagId = 0, bool driving = true); @@ -312,58 +401,103 @@ public: int addConstraintCircleRadius(Circle& c, double* radius, int tagId = 0, bool driving = true); int addConstraintArcRadius(Arc& a, double* radius, int tagId = 0, bool driving = true); - int addConstraintCircleDiameter(Circle& c, double* diameter, int tagId = 0, - bool driving = true); + int + addConstraintCircleDiameter(Circle& c, double* diameter, int tagId = 0, bool driving = true); int addConstraintArcDiameter(Arc& a, double* diameter, int tagId = 0, bool driving = true); int addConstraintEqualLength(Line& l1, Line& l2, int tagId = 0, bool driving = true); int addConstraintEqualRadius(Circle& c1, Circle& c2, int tagId = 0, bool driving = true); int addConstraintEqualRadii(Ellipse& e1, Ellipse& e2, int tagId = 0, bool driving = true); - int addConstraintEqualRadii(ArcOfHyperbola& a1, ArcOfHyperbola& a2, int tagId = 0, + int addConstraintEqualRadii(ArcOfHyperbola& a1, + ArcOfHyperbola& a2, + int tagId = 0, bool driving = true); int addConstraintEqualRadius(Circle& c1, Arc& a2, int tagId = 0, bool driving = true); int addConstraintEqualRadius(Arc& a1, Arc& a2, int tagId = 0, bool driving = true); - int addConstraintEqualFocus(ArcOfParabola& a1, ArcOfParabola& a2, int tagId = 0, + int addConstraintEqualFocus(ArcOfParabola& a1, + ArcOfParabola& a2, + int tagId = 0, bool driving = true); - int addConstraintP2PSymmetric(Point& p1, Point& p2, Line& l, int tagId = 0, - bool driving = true); - int addConstraintP2PSymmetric(Point& p1, Point& p2, Point& p, int tagId = 0, - bool driving = true); - int addConstraintSnellsLaw(Curve& ray1, Curve& ray2, Curve& boundary, Point p, double* n1, - double* n2, bool flipn1, bool flipn2, int tagId, + int + addConstraintP2PSymmetric(Point& p1, Point& p2, Line& l, int tagId = 0, bool driving = true); + int + addConstraintP2PSymmetric(Point& p1, Point& p2, Point& p, int tagId = 0, bool driving = true); + int addConstraintSnellsLaw(Curve& ray1, + Curve& ray2, + Curve& boundary, + Point p, + double* n1, + double* n2, + bool flipn1, + bool flipn2, + int tagId, bool driving = true); - int addConstraintC2CDistance(Circle& c1, Circle& c2, double* dist, int tagId, - bool driving = true); + int + addConstraintC2CDistance(Circle& c1, Circle& c2, double* dist, int tagId, bool driving = true); int addConstraintC2LDistance(Circle& c, Line& l, double* dist, int tagId, bool driving = true); + int addConstraintP2CDistance(Point& p, + Circle& c, + double* distance, + int tagId = 0, + bool driving = true); // internal alignment constraints - int addConstraintInternalAlignmentPoint2Ellipse(Ellipse& e, Point& p1, + int addConstraintInternalAlignmentPoint2Ellipse(Ellipse& e, + Point& p1, InternalAlignmentType alignmentType, - int tagId = 0, bool driving = true); - int addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse& e, Point& p1, Point& p2, - int tagId = 0, bool driving = true); - int addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse& e, Point& p1, Point& p2, - int tagId = 0, bool driving = true); - int addConstraintInternalAlignmentEllipseFocus1(Ellipse& e, Point& p1, int tagId = 0, + int tagId = 0, bool driving = true); - int addConstraintInternalAlignmentEllipseFocus2(Ellipse& e, Point& p1, int tagId = 0, + int addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse& e, + Point& p1, + Point& p2, + int tagId = 0, + bool driving = true); + int addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse& e, + Point& p1, + Point& p2, + int tagId = 0, + bool driving = true); + int addConstraintInternalAlignmentEllipseFocus1(Ellipse& e, + Point& p1, + int tagId = 0, bool driving = true); - int addConstraintInternalAlignmentPoint2Hyperbola(Hyperbola& e, Point& p1, + int addConstraintInternalAlignmentEllipseFocus2(Ellipse& e, + Point& p1, + int tagId = 0, + bool driving = true); + int addConstraintInternalAlignmentPoint2Hyperbola(Hyperbola& e, + Point& p1, InternalAlignmentType alignmentType, - int tagId = 0, bool driving = true); - int addConstraintInternalAlignmentHyperbolaMajorDiameter(Hyperbola& e, Point& p1, Point& p2, - int tagId = 0, bool driving = true); - int addConstraintInternalAlignmentHyperbolaMinorDiameter(Hyperbola& e, Point& p1, Point& p2, - int tagId = 0, bool driving = true); - int addConstraintInternalAlignmentHyperbolaFocus(Hyperbola& e, Point& p1, int tagId = 0, + int tagId = 0, + bool driving = true); + int addConstraintInternalAlignmentHyperbolaMajorDiameter(Hyperbola& e, + Point& p1, + Point& p2, + int tagId = 0, + bool driving = true); + int addConstraintInternalAlignmentHyperbolaMinorDiameter(Hyperbola& e, + Point& p1, + Point& p2, + int tagId = 0, + bool driving = true); + int addConstraintInternalAlignmentHyperbolaFocus(Hyperbola& e, + Point& p1, + int tagId = 0, bool driving = true); - int addConstraintInternalAlignmentParabolaFocus(Parabola& e, Point& p1, int tagId = 0, + int addConstraintInternalAlignmentParabolaFocus(Parabola& e, + Point& p1, + int tagId = 0, bool driving = true); - int addConstraintInternalAlignmentBSplineControlPoint(BSpline& b, Circle& c, - unsigned int poleindex, int tag = 0, + int addConstraintInternalAlignmentBSplineControlPoint(BSpline& b, + Circle& c, + unsigned int poleindex, + int tag = 0, bool driving = true); - int addConstraintInternalAlignmentKnotPoint(BSpline& b, Point& p, unsigned int knotindex, - int tagId = 0, bool driving = true); + int addConstraintInternalAlignmentKnotPoint(BSpline& b, + Point& p, + unsigned int knotindex, + int tagId = 0, + bool driving = true); double calculateAngleViaPoint(const Curve& crv1, const Curve& crv2, Point& p) const; double calculateAngleViaPoint(const Curve& crv1, const Curve& crv2, Point& p1, Point& p2) const; @@ -383,11 +517,17 @@ public: void initSolution(Algorithm alg = DogLeg); int solve(bool isFine = true, Algorithm alg = DogLeg, bool isRedundantsolving = false); - int solve(VEC_pD& params, bool isFine = true, Algorithm alg = DogLeg, + int solve(VEC_pD& params, + bool isFine = true, + Algorithm alg = DogLeg, bool isRedundantsolving = false); - int solve(SubSystem* subsys, bool isFine = true, Algorithm alg = DogLeg, + int solve(SubSystem* subsys, + bool isFine = true, + Algorithm alg = DogLeg, bool isRedundantsolving = false); - int solve(SubSystem* subsysA, SubSystem* subsysB, bool isFine = true, + int solve(SubSystem* subsysA, + SubSystem* subsysB, + bool isFine = true, bool isRedundantsolving = false); void applySolution(); diff --git a/src/Mod/Sketcher/App/planegcs/Geo.cpp b/src/Mod/Sketcher/App/planegcs/Geo.cpp index a10d65c242..07da3f10b8 100644 --- a/src/Mod/Sketcher/App/planegcs/Geo.cpp +++ b/src/Mod/Sketcher/App/planegcs/Geo.cpp @@ -32,16 +32,38 @@ namespace GCS { +//----------------Point +int Point::PushOwnParams(VEC_pD& pvec) +{ + int cnt = 0; + pvec.push_back(x); + cnt++; + pvec.push_back(y); + cnt++; + return cnt; +} + +void Point::ReconstructOnNewPvec(VEC_pD& pvec, int& cnt) +{ + x = pvec[cnt]; + cnt++; + y = pvec[cnt]; + cnt++; +} + +//----------------DeriVector2 DeriVector2::DeriVector2(const Point& p, const double* derivparam) { x = *p.x; y = *p.y; dx = 0.0; dy = 0.0; - if (derivparam == p.x) + if (derivparam == p.x) { dx = 1.0; - if (derivparam == p.y) + } + if (derivparam == p.y) { dy = 1.0; + } } double DeriVector2::length(double& dlength) const @@ -88,8 +110,10 @@ double DeriVector2::scalarProd(const DeriVector2& v2, double* dprd) const DeriVector2 DeriVector2::divD(double val, double dval) const { - return DeriVector2( - x / val, y / val, dx / val - x * dval / (val * val), dy / val - y * dval / (val * val)); + return DeriVector2(x / val, + y / val, + dx / val - x * dval / (val * val), + dy / val - y * dval / (val * val)); } double DeriVector2::crossProdNorm(const DeriVector2& v2, double& dprd) const @@ -252,7 +276,10 @@ Arc* Arc::Copy() //--------------ellipse // this function is exposed to allow reusing pre-filled derivectors in constraints code -double Ellipse::getRadMaj(const DeriVector2& center, const DeriVector2& f1, double b, double db, +double Ellipse::getRadMaj(const DeriVector2& center, + const DeriVector2& f1, + double b, + double db, double& ret_dRadMaj) const { double cf, dcf; @@ -436,7 +463,10 @@ ArcOfEllipse* ArcOfEllipse::Copy() //---------------hyperbola // this function is exposed to allow reusing pre-filled derivectors in constraints code -double Hyperbola::getRadMaj(const DeriVector2& center, const DeriVector2& f1, double b, double db, +double Hyperbola::getRadMaj(const DeriVector2& center, + const DeriVector2& f1, + double b, + double db, double& ret_dRadMaj) const { double cf, dcf; @@ -848,14 +878,16 @@ double BSpline::getLinCombFactor(double x, size_t k, size_t i, unsigned int p) // as well, when alternatives may be needed to keep `flattenedknots` updated. // Slightly more detailed discussion here: // https://github.com/FreeCAD/FreeCAD/pull/7484#discussion_r1020858392 - if (flattenedknots.empty()) + if (flattenedknots.empty()) { setupFlattenedKnots(); + } std::vector d(p + 1, 0.0); // Ensure this is within range int idxOfPole = static_cast(i) + p - static_cast(k); - if (idxOfPole < 0 || idxOfPole > static_cast(p)) + if (idxOfPole < 0 || idxOfPole > static_cast(p)) { return 0.0; + } d[idxOfPole] = 1.0; for (size_t r = 1; r < p + 1; ++r) { @@ -886,8 +918,9 @@ void BSpline::setupFlattenedKnots() { flattenedknots.clear(); - for (size_t i = 0; i < knots.size(); ++i) + for (size_t i = 0; i < knots.size(); ++i) { flattenedknots.insert(flattenedknots.end(), mult[i], *knots[i]); + } // Adjust for periodic: see OCC documentation for explanation if (periodic) { diff --git a/src/Mod/Sketcher/App/planegcs/Geo.h b/src/Mod/Sketcher/App/planegcs/Geo.h index a66bebe144..136897618c 100644 --- a/src/Mod/Sketcher/App/planegcs/Geo.h +++ b/src/Mod/Sketcher/App/planegcs/Geo.h @@ -45,6 +45,8 @@ public: } double* x; double* y; + int PushOwnParams(VEC_pD& pvec); + void ReconstructOnNewPvec(VEC_pD& pvec, int& cnt); }; using VEC_P = std::vector; @@ -132,8 +134,10 @@ public: } DeriVector2 linCombi(double m1, const DeriVector2& v2, double m2) const {// linear combination of two vectors - return DeriVector2( - x * m1 + v2.x * m2, y * m1 + v2.y * m2, dx * m1 + v2.dx * m2, dy * m1 + v2.dy * m2); + return DeriVector2(x * m1 + v2.x * m2, + y * m1 + v2.y * m2, + dx * m1 + v2.dx * m2, + dy * m1 + v2.dy * m2); } }; @@ -236,7 +240,10 @@ class MajorRadiusConic: public Curve public: ~MajorRadiusConic() override {} - virtual double getRadMaj(const DeriVector2& center, const DeriVector2& f1, double b, double db, + virtual double getRadMaj(const DeriVector2& center, + const DeriVector2& f1, + double b, + double db, double& ret_dRadMaj) const = 0; virtual double getRadMaj(double* derivparam, double& ret_dRadMaj) const = 0; virtual double getRadMaj() const = 0; @@ -255,7 +262,10 @@ public: Point center; Point focus1; double* radmin; - double getRadMaj(const DeriVector2& center, const DeriVector2& f1, double b, double db, + double getRadMaj(const DeriVector2& center, + const DeriVector2& f1, + double b, + double db, double& ret_dRadMaj) const override; double getRadMaj(double* derivparam, double& ret_dRadMaj) const override; double getRadMaj() const override; @@ -302,7 +312,10 @@ public: Point center; Point focus1; double* radmin; - double getRadMaj(const DeriVector2& center, const DeriVector2& f1, double b, double db, + double getRadMaj(const DeriVector2& center, + const DeriVector2& f1, + double b, + double db, double& ret_dRadMaj) const override; double getRadMaj(double* derivparam, double& ret_dRadMaj) const override; double getRadMaj() const override; diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index fe7d5c0111..bf4fd0fac4 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -77,8 +77,9 @@ bool isCreateConstraintActive(Gui::Document* doc) if (static_cast(doc->getInEdit())->getSketchMode() == ViewProviderSketch::STATUS_NONE) { if (Gui::Selection().countObjectsOfType(Sketcher::SketchObject::getClassTypeId()) - > 0) + > 0) { return true; + } } } } @@ -86,7 +87,9 @@ bool isCreateConstraintActive(Gui::Document* doc) } // Utility method to avoid repeating the same code over and over again -void finishDatumConstraint(Gui::Command* cmd, Sketcher::SketchObject* sketch, bool isDriving = true, +void finishDatumConstraint(Gui::Command* cmd, + Sketcher::SketchObject* sketch, + bool isDriving = true, unsigned int numberofconstraints = 1) { ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( @@ -113,10 +116,11 @@ void finishDatumConstraint(Gui::Command* cmd, Sketcher::SketchObject* sketch, bo // Adds a random value around the base angle, so that possibly overlapping labels get likely // a different position. - if (labelPositionRandomness != 0.0) + if (labelPositionRandomness != 0.0) { labelPosition = labelPosition + labelPositionRandomness * (static_cast(std::rand()) / static_cast(RAND_MAX) - 0.5); + } } if (doc && doc->getInEdit() @@ -132,8 +136,9 @@ void finishDatumConstraint(Gui::Command* cmd, Sketcher::SketchObject* sketch, bo if (lastConstraintType == Radius || lastConstraintType == Diameter) { const Part::Geometry* geo = sketch->getGeometry(ConStr[i]->First); - if (geo && geo->getTypeId() == Part::GeomCircle::getClassTypeId()) + if (geo && geo->getTypeId() == Part::GeomCircle::getClassTypeId()) { ConStr[i]->LabelPosition = labelPosition; + } } } vp->draw(false, false);// Redraw @@ -194,7 +199,8 @@ bool isGeoConcentricCompatible(const Part::Geometry* geo) /// other code e.g. "Autoconstraints" in DrawSketchHandler.cpp void SketcherGui::makeTangentToEllipseviaNewPoint(Sketcher::SketchObject* Obj, const Part::GeomEllipse* ellipse, - const Part::Geometry* geom2, int geoId1, + const Part::Geometry* geom2, + int geoId1, int geoId2) { @@ -205,14 +211,18 @@ void SketcherGui::makeTangentToEllipseviaNewPoint(Sketcher::SketchObject* Obj, Base::Vector3d center2; - if (geom2->getTypeId() == Part::GeomEllipse::getClassTypeId()) + if (geom2->getTypeId() == Part::GeomEllipse::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomCircle::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomCircle::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); + } Base::Vector3d direction = center2 - center; double tapprox = @@ -249,8 +259,9 @@ void SketcherGui::makeTangentToEllipseviaNewPoint(Sketcher::SketchObject* Obj, static_cast(Sketcher::PointPos::start)); } catch (const Base::Exception& e) { - Gui::NotifyUserError( - Obj, QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), e.what()); + Gui::NotifyUserError(Obj, + QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), + e.what()); Gui::Command::abortCommand(); tryAutoRecompute(Obj); @@ -271,7 +282,8 @@ void SketcherGui::makeTangentToEllipseviaNewPoint(Sketcher::SketchObject* Obj, /// other code e.g. "Autoconstraints" in DrawSketchHandler.cpp void SketcherGui::makeTangentToArcOfEllipseviaNewPoint(Sketcher::SketchObject* Obj, const Part::GeomArcOfEllipse* aoe, - const Part::Geometry* geom2, int geoId1, + const Part::Geometry* geom2, + int geoId1, int geoId2) { @@ -282,12 +294,15 @@ void SketcherGui::makeTangentToArcOfEllipseviaNewPoint(Sketcher::SketchObject* O Base::Vector3d center2; - if (geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) + if (geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomCircle::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomCircle::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); + } Base::Vector3d direction = center2 - center; double tapprox = @@ -324,8 +339,9 @@ void SketcherGui::makeTangentToArcOfEllipseviaNewPoint(Sketcher::SketchObject* O static_cast(Sketcher::PointPos::start)); } catch (const Base::Exception& e) { - Gui::NotifyUserError( - Obj, QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), e.what()); + Gui::NotifyUserError(Obj, + QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), + e.what()); Gui::Command::abortCommand(); tryAutoRecompute(Obj); @@ -346,7 +362,8 @@ void SketcherGui::makeTangentToArcOfEllipseviaNewPoint(Sketcher::SketchObject* O /// other code e.g. "Autoconstraints" in DrawSketchHandler.cpp void SketcherGui::makeTangentToArcOfHyperbolaviaNewPoint(Sketcher::SketchObject* Obj, const Part::GeomArcOfHyperbola* aoh, - const Part::Geometry* geom2, int geoId1, + const Part::Geometry* geom2, + int geoId1, int geoId2) { @@ -368,14 +385,18 @@ void SketcherGui::makeTangentToArcOfHyperbolaviaNewPoint(Sketcher::SketchObject* double df2 = sqrt(majord2 * majord2 + minord2 * minord2); center2 = aoh2->getCenter() + df2 * dirmaj2;// positive focus } - else if (geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) + else if (geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomEllipse::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomEllipse::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomCircle::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomCircle::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); + } else if (geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment* l2 = static_cast(geom2); center2 = (l2->getStartPoint() + l2->getEndPoint()) / 2; @@ -415,8 +436,9 @@ void SketcherGui::makeTangentToArcOfHyperbolaviaNewPoint(Sketcher::SketchObject* static_cast(Sketcher::PointPos::start)); } catch (const Base::Exception& e) { - Gui::NotifyUserError( - Obj, QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), e.what()); + Gui::NotifyUserError(Obj, + QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), + e.what()); Gui::Command::abortCommand(); tryAutoRecompute(Obj); @@ -437,7 +459,8 @@ void SketcherGui::makeTangentToArcOfHyperbolaviaNewPoint(Sketcher::SketchObject* /// DrawSketchHandler.cpp void SketcherGui::makeTangentToArcOfParabolaviaNewPoint(Sketcher::SketchObject* Obj, const Part::GeomArcOfParabola* aop, - const Part::Geometry* geom2, int geoId1, + const Part::Geometry* geom2, + int geoId1, int geoId2) { @@ -445,8 +468,9 @@ void SketcherGui::makeTangentToArcOfParabolaviaNewPoint(Sketcher::SketchObject* Base::Vector3d center2; - if (geom2->getTypeId() == Part::GeomArcOfParabola::getClassTypeId()) + if (geom2->getTypeId() == Part::GeomArcOfParabola::getClassTypeId()) { center2 = (static_cast(geom2))->getFocus(); + } else if (geom2->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId()) { const Part::GeomArcOfHyperbola* aoh2 = static_cast(geom2); Base::Vector3d dirmaj2 = aoh2->getMajorAxisDir(); @@ -455,14 +479,18 @@ void SketcherGui::makeTangentToArcOfParabolaviaNewPoint(Sketcher::SketchObject* double df2 = sqrt(majord2 * majord2 + minord2 * minord2); center2 = aoh2->getCenter() + df2 * dirmaj2;// positive focus } - else if (geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) + else if (geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomEllipse::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomEllipse::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomCircle::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomCircle::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); - else if (geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) + } + else if (geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { center2 = (static_cast(geom2))->getCenter(); + } else if (geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment* l2 = static_cast(geom2); center2 = (l2->getStartPoint() + l2->getEndPoint()) / 2; @@ -498,8 +526,9 @@ void SketcherGui::makeTangentToArcOfParabolaviaNewPoint(Sketcher::SketchObject* static_cast(Sketcher::PointPos::start)); } catch (const Base::Exception& e) { - Gui::NotifyUserError( - Obj, QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), e.what()); + Gui::NotifyUserError(Obj, + QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), + e.what()); Gui::Command::abortCommand(); @@ -511,8 +540,11 @@ void SketcherGui::makeTangentToArcOfParabolaviaNewPoint(Sketcher::SketchObject* tryAutoRecompute(Obj); } -void SketcherGui::doEndpointTangency(Sketcher::SketchObject* Obj, int GeoId1, int GeoId2, - PointPos PosId1, PointPos PosId2) +void SketcherGui::doEndpointTangency(Sketcher::SketchObject* Obj, + int GeoId1, + int GeoId2, + PointPos PosId1, + PointPos PosId2) { // This code supports simple B-spline endpoint tangency to any other geometric curve const Part::Geometry* geom1 = Obj->getGeometry(GeoId1); @@ -537,7 +569,9 @@ void SketcherGui::doEndpointTangency(Sketcher::SketchObject* Obj, int GeoId1, in static_cast(PosId2)); } -void SketcherGui::doEndpointToEdgeTangency(Sketcher::SketchObject* Obj, int GeoId1, PointPos PosId1, +void SketcherGui::doEndpointToEdgeTangency(Sketcher::SketchObject* Obj, + int GeoId1, + PointPos PosId1, int GeoId2) { Gui::cmdAppObjectArgs(Obj, @@ -569,8 +603,9 @@ bool addConstraintSafely(SketchObject* obj, std::function constraintaddi // Exceptions originating in Python have already been reported by the Interpreter as // Untranslated developer intended messages (i.e. to the Report View) // Example of exception carrying a static string with a pair in the "Notifications" context - Gui::NotifyUserError( - obj, QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), e.what()); + Gui::NotifyUserError(obj, + QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), + e.what()); Gui::Command::abortCommand(); @@ -724,26 +759,30 @@ public: bool allow(App::Document*, App::DocumentObject* pObj, const char* sSubName) override { - if (pObj != this->object) + if (pObj != this->object) { return false; - if (!sSubName || sSubName[0] == '\0') + } + if (!sSubName || sSubName[0] == '\0') { return false; + } std::string element(sSubName); if ((allowedSelTypes & (SelRoot | SelVertexOrRoot) && element.substr(0, 9) == "RootPoint") || (allowedSelTypes & (SelVertex | SelVertexOrRoot) && element.substr(0, 6) == "Vertex") || (allowedSelTypes & (SelEdge | SelEdgeOrAxis) && element.substr(0, 4) == "Edge") || (allowedSelTypes & (SelHAxis | SelEdgeOrAxis) && element.substr(0, 6) == "H_Axis") || (allowedSelTypes & (SelVAxis | SelEdgeOrAxis) && element.substr(0, 6) == "V_Axis") - || (allowedSelTypes & SelExternalEdge && element.substr(0, 12) == "ExternalEdge")) + || (allowedSelTypes & SelExternalEdge && element.substr(0, 12) == "ExternalEdge")) { return true; + } return false; } void setAllowedSelTypes(unsigned int types) { - if (types < 256) + if (types < 256) { allowedSelTypes = types; + } } protected: @@ -930,8 +969,10 @@ private: qreal fullIconWidth = 32 * pixelRatio; qreal iconWidth = 16 * pixelRatio; - QPixmap cursorPixmap = Gui::BitmapFactory().pixmapFromSvg( - "Sketcher_Crosshair", QSizeF(fullIconWidth, fullIconWidth), colorMapping), + QPixmap cursorPixmap = + Gui::BitmapFactory().pixmapFromSvg("Sketcher_Crosshair", + QSizeF(fullIconWidth, fullIconWidth), + colorMapping), icon = Gui::BitmapFactory().pixmapFromSvg(cmd->getPixmap(), QSizeF(iconWidth, iconWidth)); QPainter cursorPainter; @@ -2361,8 +2402,9 @@ void CmdSketcherConstrainHorizontal::activated(int iMsg) else if (isVertex(GeoId, PosId)) { // can be a point, a construction point, an external point or root - if (isPointOrSegmentFixed(Obj, GeoId)) + if (isPointOrSegmentFixed(Obj, GeoId)) { fixedpoints++; + } pointgeoids.push_back(GeoId); pointpos.push_back(PosId); @@ -2646,8 +2688,9 @@ void CmdSketcherConstrainVertical::activated(int iMsg) } else if (isVertex(GeoId, PosId)) { // can be a point, a construction point, an external point, root or a blocked geometry - if (isPointOrSegmentFixed(Obj, GeoId)) + if (isPointOrSegmentFixed(Obj, GeoId)) { fixedpoints++; + } pointgeoids.push_back(GeoId); pointpos.push_back(PosId); @@ -2668,8 +2711,9 @@ void CmdSketcherConstrainVertical::activated(int iMsg) openCommand(QT_TRANSLATE_NOOP("Command", "Add vertical constraint")); for (std::vector::iterator it = edgegeoids.begin(); it != edgegeoids.end(); it++) { // issue the actual commands to create the constraint - Gui::cmdAppObjectArgs( - selection[0].getObject(), "addConstraint(Sketcher.Constraint('Vertical',%d))", *it); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "addConstraint(Sketcher.Constraint('Vertical',%d))", + *it); } } else if (fixedpoints <= 1) {// vertex mode, maximum one fixed point @@ -2938,11 +2982,15 @@ void CmdSketcherConstrainLock::activated(int iMsg) || constraintCreationMode == Reference) { // it is a constraint on a external line, make it non-driving - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", lastconstraintindex - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + lastconstraintindex - 1, + "False"); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", lastconstraintindex, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + lastconstraintindex, + "False"); } } else { @@ -2954,16 +3002,18 @@ void CmdSketcherConstrainLock::activated(int iMsg) // check if the edge already has a Block constraint bool refpointfixed = false; - if (isPointOrSegmentFixed(Obj, GeoId.back())) + if (isPointOrSegmentFixed(Obj, GeoId.back())) { refpointfixed = true; + } for (itg = GeoId.begin(), itp = PosId.begin(); itg != std::prev(GeoId.end()) && itp != std::prev(PosId.end()); ++itp, ++itg) { bool pointfixed = false; - if (isPointOrSegmentFixed(Obj, *itg)) + if (isPointOrSegmentFixed(Obj, *itg)) { pointfixed = true; + } Base::Vector3d pnt = Obj->getPoint(*itg, *itp); @@ -2994,8 +3044,10 @@ void CmdSketcherConstrainLock::activated(int iMsg) lastconstraintindex - 1, "False"); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", lastconstraintindex, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + lastconstraintindex, + "False"); } } } @@ -3020,8 +3072,9 @@ void CmdSketcherConstrainLock::applyConstraint(std::vector& selSeq, i // check if the edge already has a Block constraint bool pointfixed = false; - if (isPointOrSegmentFixed(Obj, selSeq.front().GeoId)) + if (isPointOrSegmentFixed(Obj, selSeq.front().GeoId)) { pointfixed = true; + } Base::Vector3d pnt = Obj->getPoint(selSeq.front().GeoId, selSeq.front().PosId); @@ -3042,11 +3095,15 @@ void CmdSketcherConstrainLock::applyConstraint(std::vector& selSeq, i // it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - sketchgui->getObject(), "setDriving(%d, %s)", ConStr.size() - 2, "False"); + Gui::cmdAppObjectArgs(sketchgui->getObject(), + "setDriving(%d, %s)", + ConStr.size() - 2, + "False"); - Gui::cmdAppObjectArgs( - sketchgui->getObject(), "setDriving(%d, %s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(sketchgui->getObject(), + "setDriving(%d, %s)", + ConStr.size() - 1, + "False"); } // finish the transaction and update @@ -3056,8 +3113,9 @@ void CmdSketcherConstrainLock::applyConstraint(std::vector& selSeq, i "User parameter:BaseApp/Preferences/Mod/Sketcher"); bool autoRecompute = hGrp->GetBool("AutoRecompute", false); - if (autoRecompute) + if (autoRecompute) { Gui::Command::updateActive(); + } break; } } @@ -3066,12 +3124,14 @@ void CmdSketcherConstrainLock::updateAction(int mode) { switch (mode) { case Reference: - if (getAction()) + if (getAction()) { getAction()->setIcon(Gui::BitmapFactory().iconFromTheme("Constraint_Lock_Driven")); + } break; case Driving: - if (getAction()) + if (getAction()) { getAction()->setIcon(Gui::BitmapFactory().iconFromTheme("Constraint_Lock")); + } break; } } @@ -3197,8 +3257,9 @@ void CmdSketcherConstrainBlock::activated(int iMsg) Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Block',%d))", (*itg)); }); - if (!safe) + if (!safe) { return; + } else { commitCommand(); tryAutoRecompute(Obj); @@ -3223,8 +3284,10 @@ void CmdSketcherConstrainBlock::applyConstraint(std::vector& selSeq, // check if the edge already has a Block constraint const std::vector& vals = Obj->Constraints.getValues(); - if (checkConstraint( - vals, Sketcher::Block, selSeq.front().GeoId, Sketcher::PointPos::none)) { + if (checkConstraint(vals, + Sketcher::Block, + selSeq.front().GeoId, + Sketcher::PointPos::none)) { Gui::TranslatedUserWarning( Obj, QObject::tr("Double constraint"), @@ -3241,8 +3304,9 @@ void CmdSketcherConstrainBlock::applyConstraint(std::vector& selSeq, selSeq.front().GeoId); }); - if (!safe) + if (!safe) { return; + } else { commitCommand(); tryAutoRecompute(Obj); @@ -3418,8 +3482,11 @@ protected: void activated(int iMsg) override; void applyConstraint(std::vector& selSeq, int seqIndex) override; // returns true if a substitution took place - static bool substituteConstraintCombinations(SketchObject* Obj, int GeoId1, PointPos PosId1, - int GeoId2, PointPos PosId2); + static bool substituteConstraintCombinations(SketchObject* Obj, + int GeoId1, + PointPos PosId1, + int GeoId2, + PointPos PosId2); }; CmdSketcherConstrainCoincident::CmdSketcherConstrainCoincident() @@ -3443,8 +3510,10 @@ CmdSketcherConstrainCoincident::CmdSketcherConstrainCoincident() {SelExternalEdge, SelEdge}}; } -bool CmdSketcherConstrainCoincident::substituteConstraintCombinations(SketchObject* Obj, int GeoId1, - PointPos PosId1, int GeoId2, +bool CmdSketcherConstrainCoincident::substituteConstraintCombinations(SketchObject* Obj, + int GeoId1, + PointPos PosId1, + int GeoId2, PointPos PosId2) { // checks for direct and indirect coincidence constraints @@ -3466,8 +3535,10 @@ bool CmdSketcherConstrainCoincident::substituteConstraintCombinations(SketchObje if (constraintExists) { // try to remove any pre-existing direct coincident constraints - Gui::cmdAppObjectArgs( - Obj, "delConstraintOnPoint(%d,%d)", GeoId1, static_cast(PosId1)); + Gui::cmdAppObjectArgs(Obj, + "delConstraintOnPoint(%d,%d)", + GeoId1, + static_cast(PosId1)); } Gui::cmdAppObjectArgs(Obj, "delConstraint(%d)", j); @@ -3556,12 +3627,14 @@ void CmdSketcherConstrainCoincident::activated(int iMsg) getIdsFromName(*it, Obj, GeoId, PosId); if (isEdge(GeoId, PosId)) { atLeastOneEdge = true; - if (!isGeoConcentricCompatible(Obj->getGeometry(GeoId))) + if (!isGeoConcentricCompatible(Obj->getGeometry(GeoId))) { allConicsEdges = false; + } } - else + else { allConicsEdges = false;// at least one point is selected, so concentric can't be // applied. + } if (atLeastOneEdge && !allConicsEdges) { Gui::TranslatedUserWarning( @@ -3577,16 +3650,18 @@ void CmdSketcherConstrainCoincident::activated(int iMsg) int GeoId1, GeoId2; Sketcher::PointPos PosId1, PosId2; getIdsFromName(SubNames[0], Obj, GeoId1, PosId1); - if (allConicsEdges) + if (allConicsEdges) { PosId1 = Sketcher::PointPos::mid; + } // undo command open bool constraintsAdded = false; openCommand(QT_TRANSLATE_NOOP("Command", "Add coincident constraint")); for (std::size_t i = 1; i < SubNames.size(); i++) { getIdsFromName(SubNames[i], Obj, GeoId2, PosId2); - if (allConicsEdges) + if (allConicsEdges) { PosId2 = Sketcher::PointPos::mid; + } // check if the edge already has a Block constraint if (areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2)) { @@ -3618,10 +3693,12 @@ void CmdSketcherConstrainCoincident::activated(int iMsg) } // finish or abort the transaction and update - if (constraintsAdded) + if (constraintsAdded) { commitCommand(); - else + } + else { abortCommand(); + } tryAutoRecompute(Obj); @@ -3775,8 +3852,9 @@ void CmdSketcherConstrainDistance::activated(int iMsg) int GeoId1, GeoId2 = GeoEnum::GeoUndef; Sketcher::PointPos PosId1, PosId2 = Sketcher::PointPos::none; getIdsFromName(SubNames[0], Obj, GeoId1, PosId1); - if (SubNames.size() == 2) + if (SubNames.size() == 2) { getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); + } bool arebothpointsorsegmentsfixed = areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2); @@ -3834,12 +3912,15 @@ void CmdSketcherConstrainDistance::activated(int iMsg) // it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } else if ((isVertex(GeoId1, PosId1) && isEdge(GeoId2, PosId2)) @@ -3873,12 +3954,47 @@ void CmdSketcherConstrainDistance::activated(int iMsg) == Reference) {// it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } + + return; + } + else if (geom->getTypeId() == Part::GeomCircle::getClassTypeId()) { + const Part::GeomCircle* circleSeg; + circleSeg = static_cast(geom); + Base::Vector3d ct = circleSeg->getCenter(); + Base::Vector3d d = ct - pnt; + double ActDist = std::abs(d.Length() - circleSeg->getRadius()); + + openCommand(QT_TRANSLATE_NOOP("Command", "Add point to circle Distance constraint")); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "addConstraint(Sketcher.Constraint('Distance',%d,%d,%d,%f))", + GeoId1, + static_cast(PosId1), + GeoId2, + ActDist); + + if (arebothpointsorsegmentsfixed + || constraintCreationMode + == Reference) {// it is a constraint on a external line, make it non-driving + const std::vector& ConStr = Obj->Constraints.getValues(); + + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); + finishDatumConstraint(this, Obj, false); + } + else { + finishDatumConstraint(this, Obj, true); + } return; } @@ -3925,12 +4041,15 @@ void CmdSketcherConstrainDistance::activated(int iMsg) == Reference) {// it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -3970,12 +4089,15 @@ void CmdSketcherConstrainDistance::activated(int iMsg) == Reference) {// it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%i,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%i,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -4007,12 +4129,15 @@ void CmdSketcherConstrainDistance::activated(int iMsg) || constraintCreationMode == Reference) { const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -4096,8 +4221,9 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector& selSe Gui::cmdAppObjectArgs(Obj, "setDriving(%d,%s)", ConStr.size() - 1, "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -4117,8 +4243,10 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector& selSe double ActLength = (lineSeg->getEndPoint() - lineSeg->getStartPoint()).Length(); openCommand(QT_TRANSLATE_NOOP("Command", "Add length constraint")); - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Distance',%d,%f))", GeoId1, ActLength); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Distance',%d,%f))", + GeoId1, + ActLength); if (arebothpointsorsegmentsfixed || GeoId1 <= Sketcher::GeoEnum::RefExt || constraintCreationMode == Reference) { @@ -4128,8 +4256,9 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector& selSe Gui::cmdAppObjectArgs(Obj, "setDriving(%d,%s)", ConStr.size() - 1, "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } } else if (geom->getTypeId() == Part::GeomCircle::getClassTypeId()) { // allow this selection but do nothing as it needs 2 circles or 1 circle and 1 line @@ -4180,8 +4309,9 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector& selSe Gui::cmdAppObjectArgs(Obj, "setDriving(%d,%s)", ConStr.size() - 1, "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } } return; @@ -4235,8 +4365,9 @@ void CmdSketcherConstrainDistance::applyConstraint(std::vector& selSe Gui::cmdAppObjectArgs(Obj, "setDriving(%d,%s)", ConStr.size() - 1, "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -4257,13 +4388,15 @@ void CmdSketcherConstrainDistance::updateAction(int mode) { switch (mode) { case Reference: - if (getAction()) + if (getAction()) { getAction()->setIcon( Gui::BitmapFactory().iconFromTheme("Constraint_Length_Driven")); + } break; case Driving: - if (getAction()) + if (getAction()) { getAction()->setIcon(Gui::BitmapFactory().iconFromTheme("Constraint_Length")); + } break; } } @@ -4285,8 +4418,8 @@ protected: void activated(int iMsg) override; void applyConstraint(std::vector& selSeq, int seqIndex) override; // returns true if a substitution took place - static bool substituteConstraintCombinations(SketchObject* Obj, int GeoId1, PointPos PosId1, - int GeoId2); + static bool + substituteConstraintCombinations(SketchObject* Obj, int GeoId1, PointPos PosId1, int GeoId2); }; CmdSketcherConstrainPointOnObject::CmdSketcherConstrainPointOnObject() @@ -4379,10 +4512,12 @@ void CmdSketcherConstrainPointOnObject::activated(int iMsg) for (std::size_t i = 0; i < SubNames.size(); i++) { SelIdPair id; getIdsFromName(SubNames[i], Obj, id.GeoId, id.PosId); - if (isEdge(id.GeoId, id.PosId)) + if (isEdge(id.GeoId, id.PosId)) { curves.push_back(id); - if (isVertex(id.GeoId, id.PosId)) + } + if (isVertex(id.GeoId, id.PosId)) { points.push_back(id); + } } if ((points.size() == 1 && !curves.empty()) || (!points.empty() && curves.size() == 1)) { @@ -4395,8 +4530,9 @@ void CmdSketcherConstrainPointOnObject::activated(int iMsg) showNoConstraintBetweenFixedGeometry(Obj); continue; } - if (points[iPnt].GeoId == curves[iCrv].GeoId) + if (points[iPnt].GeoId == curves[iCrv].GeoId) { continue;// constraining a point of an element onto the element is a bad idea... + } const Part::Geometry* geom = Obj->getGeometry(curves[iCrv].GeoId); @@ -4410,8 +4546,10 @@ void CmdSketcherConstrainPointOnObject::activated(int iMsg) continue; } - if (substituteConstraintCombinations( - Obj, points[iPnt].GeoId, points[iPnt].PosId, curves[iCrv].GeoId)) { + if (substituteConstraintCombinations(Obj, + points[iPnt].GeoId, + points[iPnt].PosId, + curves[iCrv].GeoId)) { cnt++; continue; } @@ -4488,8 +4626,9 @@ void CmdSketcherConstrainPointOnObject::applyConstraint(std::vector& showNoConstraintBetweenFixedGeometry(Obj); allOK = false; } - if (GeoIdVt == GeoIdCrv) + if (GeoIdVt == GeoIdCrv) { allOK = false;// constraining a point of an element onto the element is a bad idea... + } const Part::Geometry* geom = Obj->getGeometry(GeoIdCrv); @@ -4503,12 +4642,13 @@ void CmdSketcherConstrainPointOnObject::applyConstraint(std::vector& } if (allOK) { - if (!substituteConstraintCombinations(Obj, GeoIdVt, PosIdVt, GeoIdCrv)) + if (!substituteConstraintCombinations(Obj, GeoIdVt, PosIdVt, GeoIdCrv)) { Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d))", GeoIdVt, static_cast(PosIdVt), GeoIdCrv); + } commitCommand(); tryAutoRecompute(Obj); @@ -4559,8 +4699,10 @@ CmdSketcherConstrainDistanceX::CmdSketcherConstrainDistanceX() eType = ForEdit; // Can't do single vertex because its a prefix for 2 vertices - allowedSelSequences = { - {SelVertex, SelVertexOrRoot}, {SelRoot, SelVertex}, {SelEdge}, {SelExternalEdge}}; + allowedSelSequences = {{SelVertex, SelVertexOrRoot}, + {SelRoot, SelVertex}, + {SelEdge}, + {SelExternalEdge}}; } void CmdSketcherConstrainDistanceX::activated(int iMsg) @@ -4604,8 +4746,9 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) int GeoId1, GeoId2 = GeoEnum::GeoUndef; Sketcher::PointPos PosId1, PosId2 = Sketcher::PointPos::none; getIdsFromName(SubNames[0], Obj, GeoId1, PosId1); - if (SubNames.size() == 2) + if (SubNames.size() == 2) { getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); + } bool arebothpointsorsegmentsfixed = areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2); @@ -4614,9 +4757,10 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) std::swap(PosId1, PosId2); } - if (GeoId1 == Sketcher::GeoEnum::HAxis && PosId1 == Sketcher::PointPos::none) + if (GeoId1 == Sketcher::GeoEnum::HAxis && PosId1 == Sketcher::PointPos::none) { // reject horizontal axis from selection GeoId1 = GeoEnum::GeoUndef; + } else if (GeoId1 == Sketcher::GeoEnum::VAxis && PosId1 == Sketcher::PointPos::none) { GeoId1 = Sketcher::GeoEnum::HAxis; PosId1 = Sketcher::PointPos::start; @@ -4670,12 +4814,15 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) // it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -4707,12 +4854,15 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) // it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -4795,22 +4945,25 @@ void CmdSketcherConstrainDistanceX::applyConstraint(std::vector& selS Gui::cmdAppObjectArgs(Obj, "setDriving(%d,%s)", ConStr.size() - 1, "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } } void CmdSketcherConstrainDistanceX::updateAction(int mode) { switch (mode) { case Reference: - if (getAction()) + if (getAction()) { getAction()->setIcon( Gui::BitmapFactory().iconFromTheme("Constraint_HorizontalDistance_Driven")); + } break; case Driving: - if (getAction()) + if (getAction()) { getAction()->setIcon( Gui::BitmapFactory().iconFromTheme("Constraint_HorizontalDistance")); + } break; } } @@ -4849,8 +5002,10 @@ CmdSketcherConstrainDistanceY::CmdSketcherConstrainDistanceY() eType = ForEdit; // Can't do single vertex because its a prefix for 2 vertices - allowedSelSequences = { - {SelVertex, SelVertexOrRoot}, {SelRoot, SelVertex}, {SelEdge}, {SelExternalEdge}}; + allowedSelSequences = {{SelVertex, SelVertexOrRoot}, + {SelRoot, SelVertex}, + {SelEdge}, + {SelExternalEdge}}; } void CmdSketcherConstrainDistanceY::activated(int iMsg) @@ -4894,8 +5049,9 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) int GeoId1, GeoId2 = GeoEnum::GeoUndef; Sketcher::PointPos PosId1, PosId2 = Sketcher::PointPos::none; getIdsFromName(SubNames[0], Obj, GeoId1, PosId1); - if (SubNames.size() == 2) + if (SubNames.size() == 2) { getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); + } bool arebothpointsorsegmentsfixed = areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2); @@ -4905,10 +5061,12 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) } if (GeoId1 == Sketcher::GeoEnum::VAxis - && PosId1 == Sketcher::PointPos::none)// reject vertical axis from selection + && PosId1 == Sketcher::PointPos::none) {// reject vertical axis from selection GeoId1 = GeoEnum::GeoUndef; - else if (GeoId1 == Sketcher::GeoEnum::HAxis && PosId1 == Sketcher::PointPos::none) + } + else if (GeoId1 == Sketcher::GeoEnum::HAxis && PosId1 == Sketcher::PointPos::none) { PosId1 = Sketcher::PointPos::start; + } if (isEdge(GeoId1, PosId1) && GeoId2 == GeoEnum::GeoUndef) {// vertical length of a line if (GeoId1 < 0 && GeoId1 >= Sketcher::GeoEnum::VAxis) { @@ -4958,12 +5116,15 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) // it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -4993,12 +5154,15 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg) // it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -5082,22 +5246,25 @@ void CmdSketcherConstrainDistanceY::applyConstraint(std::vector& selS Gui::cmdAppObjectArgs(Obj, "setDriving(%d,%s)", ConStr.size() - 1, "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } } void CmdSketcherConstrainDistanceY::updateAction(int mode) { switch (mode) { case Reference: - if (getAction()) + if (getAction()) { getAction()->setIcon( Gui::BitmapFactory().iconFromTheme("Constraint_VerticalDistance_Driven")); + } break; case Driving: - if (getAction()) + if (getAction()) { getAction()->setIcon( Gui::BitmapFactory().iconFromTheme("Constraint_VerticalDistance")); + } break; } } @@ -5189,8 +5356,9 @@ void CmdSketcherConstrainParallel::activated(int iMsg) getIdsFromName(*it, Obj, GeoId, PosId); if (!isEdge(GeoId, PosId)) { - Gui::TranslatedUserWarning( - Obj, QObject::tr("Wrong selection"), QObject::tr("Select a valid line.")); + Gui::TranslatedUserWarning(Obj, + QObject::tr("Wrong selection"), + QObject::tr("Select a valid line.")); return; } else if (isPointOrSegmentFixed(Obj, GeoId)) { @@ -5198,8 +5366,9 @@ void CmdSketcherConstrainParallel::activated(int iMsg) showNoConstraintBetweenFixedGeometry(Obj); return; } - else + else { hasAlreadyExternal = true; + } } // Check that the curve is a line segment @@ -5348,8 +5517,9 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg) QObject::tr("Select some geometry from the sketch.", "perpendicular constraint"); strError.append(QString::fromLatin1("\n\n")); strError.append(strBasicHelp); - Gui::TranslatedUserWarning( - getActiveGuiDocument(), QObject::tr("Wrong selection"), std::move(strError)); + Gui::TranslatedUserWarning(getActiveGuiDocument(), + QObject::tr("Wrong selection"), + std::move(strError)); } return; } @@ -5359,8 +5529,9 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg) Sketcher::SketchObject* Obj = dynamic_cast(selection[0].getObject()); if (!Obj || (SubNames.size() != 2 && SubNames.size() != 3)) { - Gui::TranslatedUserWarning( - Obj, QObject::tr("Wrong selection"), QObject::tr("Wrong number of selected objects!")); + Gui::TranslatedUserWarning(Obj, + QObject::tr("Wrong selection"), + QObject::tr("Wrong number of selected objects!")); return; } @@ -5369,8 +5540,9 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg) getIdsFromName(SubNames[0], Obj, GeoId1, PosId1); getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - if (areBothPointsOrSegmentsFixed( - Obj, GeoId1, GeoId2)) {// checkBothExternal displays error message + if (areBothPointsOrSegmentsFixed(Obj, + GeoId1, + GeoId2)) {// checkBothExternal displays error message showNoConstraintBetweenFixedGeometry(Obj); return; } @@ -5442,8 +5614,9 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg) static_cast(PosId3)); }); - if (!safe) + if (!safe) { return; + } else { commitCommand(); tryAutoRecompute(Obj); @@ -5577,8 +5750,9 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg) return; } - if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId()) + if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { std::swap(GeoId1, GeoId2); + } if (isBsplinePole(Obj, GeoId1)) { Gui::TranslatedUserWarning( @@ -5677,8 +5851,10 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg) try { // Add a point - Gui::cmdAppObjectArgs( - Obj, "addGeometry(Part.Point(App.Vector(%f,%f,0)))", PoO.x, PoO.y); + Gui::cmdAppObjectArgs(Obj, + "addGeometry(Part.Point(App.Vector(%f,%f,0)))", + PoO.x, + PoO.y); int GeoIdPoint = Obj->getHighestCurveIndex(); // Point on first object (ellipse, arc of ellipse) @@ -5706,8 +5882,9 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg) static_cast(Sketcher::PointPos::start)); } catch (const Base::Exception& e) { - Gui::NotifyUserError( - Obj, QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), e.what()); + Gui::NotifyUserError(Obj, + QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), + e.what()); Gui::Command::abortCommand(); tryAutoRecompute(Obj); @@ -5790,8 +5967,9 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector& return; } - if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId()) + if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { std::swap(GeoId1, GeoId2); + } if (isBsplinePole(Obj, GeoId1)) { Gui::TranslatedUserWarning( @@ -5890,8 +6068,10 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector& try { // Add a point - Gui::cmdAppObjectArgs( - Obj, "addGeometry(Part.Point(App.Vector(%f,%f,0)))", PoO.x, PoO.y); + Gui::cmdAppObjectArgs(Obj, + "addGeometry(Part.Point(App.Vector(%f,%f,0)))", + PoO.x, + PoO.y); int GeoIdPoint = Obj->getHighestCurveIndex(); // Point on first object (ellipse, arc of ellipse) @@ -5921,8 +6101,9 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector& commitCommand(); } catch (const Base::Exception& e) { - Gui::NotifyUserError( - Obj, QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), e.what()); + Gui::NotifyUserError(Obj, + QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), + e.what()); Gui::Command::abortCommand(); } @@ -5934,8 +6115,10 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector& } openCommand(QT_TRANSLATE_NOOP("Command", "Add perpendicular constraint")); - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Perpendicular',%d,%d))", GeoId1, GeoId2); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Perpendicular',%d,%d))", + GeoId1, + GeoId2); commitCommand(); tryAutoRecompute(Obj); @@ -6032,8 +6215,9 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector& static_cast(PosId3)); }); - if (!safe) + if (!safe) { return; + } else { commitCommand(); tryAutoRecompute(Obj); @@ -6094,7 +6278,8 @@ CmdSketcherConstrainTangent::CmdSketcherConstrainTangent() {SelVertexOrRoot, SelVertex} /*Two Endpoints*/ /*No Place for One Endpoint and One Curve*/}; } -bool CmdSketcherConstrainTangent::substituteConstraintCombinations(SketchObject* Obj, int GeoId1, +bool CmdSketcherConstrainTangent::substituteConstraintCombinations(SketchObject* Obj, + int GeoId1, int GeoId2) { const std::vector& cvals = Obj->Constraints.getValues(); @@ -6133,13 +6318,15 @@ bool CmdSketcherConstrainTangent::substituteConstraintCombinations(SketchObject* && (((*it)->First == GeoId1 && (*it)->Second == GeoId2) || ((*it)->Second == GeoId1 && (*it)->First == GeoId2))) { - Gui::Command::openCommand(QT_TRANSLATE_NOOP( - "Command", "Swap PointOnObject+tangency with point to curve tangency")); + Gui::Command::openCommand( + QT_TRANSLATE_NOOP("Command", + "Swap PointOnObject+tangency with point to curve tangency")); doEndpointToEdgeTangency(Obj, (*it)->First, (*it)->FirstPos, (*it)->Second); - Gui::cmdAppObjectArgs( - Obj, "delConstraint(%d)", cid);// remove the preexisting point on object constraint. + Gui::cmdAppObjectArgs(Obj, + "delConstraint(%d)", + cid);// remove the preexisting point on object constraint. commitCommand(); @@ -6187,8 +6374,9 @@ void CmdSketcherConstrainTangent::activated(int iMsg) QObject::tr("Select some geometry from the sketch.", "tangent constraint"); strError.append(QString::fromLatin1("\n\n")); strError.append(strBasicHelp); - Gui::TranslatedUserWarning( - getActiveGuiDocument(), QObject::tr("Wrong selection"), std::move(strError)); + Gui::TranslatedUserWarning(getActiveGuiDocument(), + QObject::tr("Wrong selection"), + std::move(strError)); } return; } @@ -6198,8 +6386,9 @@ void CmdSketcherConstrainTangent::activated(int iMsg) Sketcher::SketchObject* Obj = static_cast(selection[0].getObject()); if (SubNames.size() != 2 && SubNames.size() != 3) { - Gui::TranslatedUserWarning( - Obj, QObject::tr("Wrong selection"), QObject::tr("Wrong number of selected objects!")); + Gui::TranslatedUserWarning(Obj, + QObject::tr("Wrong selection"), + QObject::tr("Wrong number of selected objects!")); return; } @@ -6209,8 +6398,9 @@ void CmdSketcherConstrainTangent::activated(int iMsg) getIdsFromName(SubNames[0], Obj, GeoId1, PosId1); getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - if (areBothPointsOrSegmentsFixed( - Obj, GeoId1, GeoId2)) {// checkBothExternal displays error message + if (areBothPointsOrSegmentsFixed(Obj, + GeoId1, + GeoId2)) {// checkBothExternal displays error message showNoConstraintBetweenFixedGeometry(Obj); return; } @@ -6282,8 +6472,9 @@ void CmdSketcherConstrainTangent::activated(int iMsg) static_cast(PosId3)); }); - if (!safe) + if (!safe) { return; + } else { commitCommand(); tryAutoRecompute(Obj); @@ -6435,15 +6626,17 @@ void CmdSketcherConstrainTangent::activated(int iMsg) // would arise and substitute them with more appropriate counterparts, examples: // - coincidence + tangency on edge // - point on object + tangency on edge - if (substituteConstraintCombinations(Obj, GeoId1, GeoId2)) + if (substituteConstraintCombinations(Obj, GeoId1, GeoId2)) { return; + } if (geom1 && geom2 && (geom1->getTypeId() == Part::GeomEllipse::getClassTypeId() || geom2->getTypeId() == Part::GeomEllipse::getClassTypeId())) { - if (geom1->getTypeId() != Part::GeomEllipse::getClassTypeId()) + if (geom1->getTypeId() != Part::GeomEllipse::getClassTypeId()) { std::swap(GeoId1, GeoId2); + } // GeoId1 is the ellipse geom1 = Obj->getGeometry(GeoId1); @@ -6456,8 +6649,11 @@ void CmdSketcherConstrainTangent::activated(int iMsg) Gui::Command::openCommand( QT_TRANSLATE_NOOP("Command", "Add tangent constraint point")); - makeTangentToEllipseviaNewPoint( - Obj, static_cast(geom1), geom2, GeoId1, GeoId2); + makeTangentToEllipseviaNewPoint(Obj, + static_cast(geom1), + geom2, + GeoId1, + GeoId2); getSelection().clearSelection(); return; } @@ -6490,8 +6686,9 @@ void CmdSketcherConstrainTangent::activated(int iMsg) && (geom1->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId())) { - if (geom1->getTypeId() != Part::GeomArcOfEllipse::getClassTypeId()) + if (geom1->getTypeId() != Part::GeomArcOfEllipse::getClassTypeId()) { std::swap(GeoId1, GeoId2); + } // GeoId1 is the arc of ellipse geom1 = Obj->getGeometry(GeoId1); @@ -6532,8 +6729,9 @@ void CmdSketcherConstrainTangent::activated(int iMsg) && (geom1->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId() || geom2->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId())) { - if (geom1->getTypeId() != Part::GeomArcOfHyperbola::getClassTypeId()) + if (geom1->getTypeId() != Part::GeomArcOfHyperbola::getClassTypeId()) { std::swap(GeoId1, GeoId2); + } // GeoId1 is the arc of hyperbola geom1 = Obj->getGeometry(GeoId1); @@ -6573,8 +6771,9 @@ void CmdSketcherConstrainTangent::activated(int iMsg) && (geom1->getTypeId() == Part::GeomArcOfParabola::getClassTypeId() || geom2->getTypeId() == Part::GeomArcOfParabola::getClassTypeId())) { - if (geom1->getTypeId() != Part::GeomArcOfParabola::getClassTypeId()) + if (geom1->getTypeId() != Part::GeomArcOfParabola::getClassTypeId()) { std::swap(GeoId1, GeoId2); + } // GeoId1 is the arc of hyperbola geom1 = Obj->getGeometry(GeoId1); @@ -6670,15 +6869,17 @@ void CmdSketcherConstrainTangent::applyConstraint(std::vector& selSeq // would arise and substitute them with more appropriate counterparts, examples: // - coincidence + tangency on edge // - point on object + tangency on edge - if (substituteConstraintCombinations(Obj, GeoId1, GeoId2)) + if (substituteConstraintCombinations(Obj, GeoId1, GeoId2)) { return; + } if (geom1 && geom2 && (geom1->getTypeId() == Part::GeomEllipse::getClassTypeId() || geom2->getTypeId() == Part::GeomEllipse::getClassTypeId())) { - if (geom1->getTypeId() != Part::GeomEllipse::getClassTypeId()) + if (geom1->getTypeId() != Part::GeomEllipse::getClassTypeId()) { std::swap(GeoId1, GeoId2); + } // GeoId1 is the ellipse geom1 = Obj->getGeometry(GeoId1); @@ -6691,8 +6892,11 @@ void CmdSketcherConstrainTangent::applyConstraint(std::vector& selSeq Gui::Command::openCommand( QT_TRANSLATE_NOOP("Command", "Add tangent constraint point")); - makeTangentToEllipseviaNewPoint( - Obj, static_cast(geom1), geom2, GeoId1, GeoId2); + makeTangentToEllipseviaNewPoint(Obj, + static_cast(geom1), + geom2, + GeoId1, + GeoId2); getSelection().clearSelection(); return; } @@ -6725,8 +6929,9 @@ void CmdSketcherConstrainTangent::applyConstraint(std::vector& selSeq && (geom1->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId() || geom2->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId())) { - if (geom1->getTypeId() != Part::GeomArcOfHyperbola::getClassTypeId()) + if (geom1->getTypeId() != Part::GeomArcOfHyperbola::getClassTypeId()) { std::swap(GeoId1, GeoId2); + } // GeoId1 is the arc of hyperbola geom1 = Obj->getGeometry(GeoId1); @@ -6766,8 +6971,9 @@ void CmdSketcherConstrainTangent::applyConstraint(std::vector& selSeq && (geom1->getTypeId() == Part::GeomArcOfParabola::getClassTypeId() || geom2->getTypeId() == Part::GeomArcOfParabola::getClassTypeId())) { - if (geom1->getTypeId() != Part::GeomArcOfParabola::getClassTypeId()) + if (geom1->getTypeId() != Part::GeomArcOfParabola::getClassTypeId()) { std::swap(GeoId1, GeoId2); + } // GeoId1 is the arc of hyperbola geom1 = Obj->getGeometry(GeoId1); @@ -6794,8 +7000,10 @@ void CmdSketcherConstrainTangent::applyConstraint(std::vector& selSeq } openCommand(QT_TRANSLATE_NOOP("Command", "Add tangent constraint")); - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Tangent',%d,%d))", GeoId1, GeoId2); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Tangent',%d,%d))", + GeoId1, + GeoId2); commitCommand(); tryAutoRecompute(Obj); @@ -6943,8 +7151,9 @@ void CmdSketcherConstrainTangent::applyConstraint(std::vector& selSeq static_cast(PosId3)); }); - if (!safe) + if (!safe) { return; + } else { commitCommand(); tryAutoRecompute(Obj); @@ -7050,8 +7259,9 @@ void CmdSketcherConstrainRadius::activated(int iMsg) GeoId = -std::atoi(it->substr(12, 4000).c_str()) - 2; issegmentfixed = true; } - else + else { continue; + } const Part::Geometry* geom = Obj->getGeometry(GeoId); @@ -7079,10 +7289,12 @@ void CmdSketcherConstrainRadius::activated(int iMsg) geoIdRadiusMap.emplace_back(GeoId, radius); } - if (isBsplinePole(geom)) + if (isBsplinePole(geom)) { poles = true; - else + } + else { nonpoles = true; + } } } @@ -7119,23 +7331,27 @@ void CmdSketcherConstrainRadius::activated(int iMsg) it != externalGeoIdRadiusMap.end(); ++it) { - if (nonpoles) + if (nonpoles) { Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Radius',%d,%f))", it->first, it->second); - else + } + else { Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Weight',%d,%f))", it->first, it->second); + } const std::vector& ConStr = Obj->Constraints.getValues(); constrSize = ConStr.size(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", constrSize - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + constrSize - 1, + "False"); } @@ -7151,8 +7367,9 @@ void CmdSketcherConstrainRadius::activated(int iMsg) int refGeoId = geoIdRadiusMap.front().first; double radius = geoIdRadiusMap.front().second; - if (!commandopened) + if (!commandopened) { openCommand(QT_TRANSLATE_NOOP("Command", "Add radius constraint")); + } // Add the equality constraints for (std::vector>::iterator it = geoIdRadiusMap.begin() + 1; @@ -7164,39 +7381,46 @@ void CmdSketcherConstrainRadius::activated(int iMsg) it->first); } - if (nonpoles) + if (nonpoles) { Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Radius',%d,%f))", refGeoId, radius); - else + } + else { Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Weight',%d,%f))", refGeoId, radius); + } } else { // Create the radius constraints now - if (!commandopened) + if (!commandopened) { openCommand(QT_TRANSLATE_NOOP("Command", "Add radius constraint")); + } for (std::vector>::iterator it = geoIdRadiusMap.begin(); it != geoIdRadiusMap.end(); ++it) { - if (nonpoles) + if (nonpoles) { Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Radius',%d,%f))", it->first, it->second); - else + } + else { Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Weight',%d,%f))", it->first, it->second); + } if (constraintCreationMode == Reference) { const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); } } } @@ -7207,8 +7431,9 @@ void CmdSketcherConstrainRadius::activated(int iMsg) getSelection().clearSelection(); } - if (commitNeeded) + if (commitNeeded) { commitCommand(); + } if (updateNeeded) { tryAutoRecomputeIfNotSolve(Obj);// we have to update the solver after this aborted addition. @@ -7253,12 +7478,18 @@ void CmdSketcherConstrainRadius::applyConstraint(std::vector& selSeq, bool ispole = isBsplinePole(geom); - if (ispole) - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Weight',%d,%f))", GeoId, radius); - else - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Radius',%d,%f))", GeoId, radius); + if (ispole) { + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Weight',%d,%f))", + GeoId, + radius); + } + else { + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Radius',%d,%f))", + GeoId, + radius); + } const std::vector& ConStr = Obj->Constraints.getValues(); @@ -7289,13 +7520,15 @@ void CmdSketcherConstrainRadius::updateAction(int mode) { switch (mode) { case Reference: - if (getAction()) + if (getAction()) { getAction()->setIcon( Gui::BitmapFactory().iconFromTheme("Constraint_Radius_Driven")); + } break; case Driving: - if (getAction()) + if (getAction()) { getAction()->setIcon(Gui::BitmapFactory().iconFromTheme("Constraint_Radius")); + } break; } } @@ -7391,8 +7624,9 @@ void CmdSketcherConstrainDiameter::activated(int iMsg) GeoId = -std::atoi(it->substr(12, 4000).c_str()) - 2; issegmentfixed = true; } - else + else { continue; + } const Part::Geometry* geom = Obj->getGeometry(GeoId); @@ -7451,8 +7685,10 @@ void CmdSketcherConstrainDiameter::activated(int iMsg) for (std::vector>::iterator it = externalGeoIdDiameterMap.begin(); it != externalGeoIdDiameterMap.end(); ++it) { - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Diameter',%d,%f))", it->first, it->second); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Diameter',%d,%f))", + it->first, + it->second); const std::vector& ConStr = Obj->Constraints.getValues(); @@ -7474,24 +7710,30 @@ void CmdSketcherConstrainDiameter::activated(int iMsg) int refGeoId = geoIdDiameterMap.front().first; double diameter = geoIdDiameterMap.front().second; - if (!commandopened) + if (!commandopened) { openCommand(QT_TRANSLATE_NOOP("Command", "Add diameter constraint")); + } // Add the equality constraints for (std::vector>::iterator it = geoIdDiameterMap.begin() + 1; it != geoIdDiameterMap.end(); ++it) { - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Equal',%d,%d))", refGeoId, it->first); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Equal',%d,%d))", + refGeoId, + it->first); } - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Diameter',%d,%f))", refGeoId, diameter); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Diameter',%d,%f))", + refGeoId, + diameter); } else { // Create the diameter constraints now - if (!commandopened) + if (!commandopened) { openCommand(QT_TRANSLATE_NOOP("Command", "Add diameter constraint")); + } for (std::vector>::iterator it = geoIdDiameterMap.begin(); it != geoIdDiameterMap.end(); ++it) { @@ -7515,8 +7757,9 @@ void CmdSketcherConstrainDiameter::activated(int iMsg) getSelection().clearSelection(); } - if (commitNeeded) + if (commitNeeded) { commitCommand(); + } if (updateNeeded) { tryAutoRecomputeIfNotSolve(Obj);// we have to update the solver after this aborted addition. @@ -7567,8 +7810,10 @@ void CmdSketcherConstrainDiameter::applyConstraint(std::vector& selSe // Create the diameter constraint now openCommand(QT_TRANSLATE_NOOP("Command", "Add diameter constraint")); - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Diameter',%d,%f))", GeoId, diameter); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Diameter',%d,%f))", + GeoId, + diameter); const std::vector& ConStr = Obj->Constraints.getValues(); @@ -7598,13 +7843,15 @@ void CmdSketcherConstrainDiameter::updateAction(int mode) { switch (mode) { case Reference: - if (getAction()) + if (getAction()) { getAction()->setIcon( Gui::BitmapFactory().iconFromTheme("Constraint_Diameter_Driven")); + } break; case Driving: - if (getAction()) + if (getAction()) { getAction()->setIcon(Gui::BitmapFactory().iconFromTheme("Constraint_Diameter")); + } break; } } @@ -7704,8 +7951,9 @@ void CmdSketcherConstrainRadiam::activated(int iMsg) GeoId = -std::atoi(it->substr(12, 4000).c_str()) - 2; issegmentfixed = true; } - else + else { continue; + } const Part::Geometry* geom = Obj->getGeometry(GeoId); double radius; @@ -7718,13 +7966,16 @@ void CmdSketcherConstrainRadiam::activated(int iMsg) else if (geom && geom->getTypeId() == Part::GeomCircle::getClassTypeId()) { const Part::GeomCircle* arcir = static_cast(geom); radius = arcir->getRadius(); - if (isBsplinePole(geom)) + if (isBsplinePole(geom)) { poles = true; - else + } + else { nonpoles = true; + } } - else + else { continue; + } if (issegmentfixed) { externalGeoIdRadiamMap.emplace_back(GeoId, radius); @@ -7807,20 +8058,25 @@ void CmdSketcherConstrainRadiam::activated(int iMsg) int refGeoId = geoIdRadiamMap.front().first; double radiam = geoIdRadiamMap.front().second; - if (!commandopened) + if (!commandopened) { openCommand(QT_TRANSLATE_NOOP("Command", "Add radiam constraint")); + } // Add the equality constraints for (std::vector>::iterator it = geoIdRadiamMap.begin() + 1; it != geoIdRadiamMap.end(); ++it) { - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Equal',%d,%d))", refGeoId, it->first); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Equal',%d,%d))", + refGeoId, + it->first); } if (poles) { - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Weight',%d,%f))", refGeoId, radiam); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Weight',%d,%f))", + refGeoId, + radiam); } else if (Obj->getGeometry(refGeoId)->getTypeId() == Part::GeomCircle::getClassTypeId()) { @@ -7830,14 +8086,17 @@ void CmdSketcherConstrainRadiam::activated(int iMsg) radiam * 2); } else { - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Radius',%d,%f))", refGeoId, radiam); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Radius',%d,%f))", + refGeoId, + radiam); } } else { // Create the radiam constraints now - if (!commandopened) + if (!commandopened) { openCommand(QT_TRANSLATE_NOOP("Command", "Add radiam constraint")); + } for (std::vector>::iterator it = geoIdRadiamMap.begin(); it != geoIdRadiamMap.end(); ++it) { @@ -7876,8 +8135,9 @@ void CmdSketcherConstrainRadiam::activated(int iMsg) getSelection().clearSelection(); } - if (commitNeeded) + if (commitNeeded) { commitCommand(); + } if (updateNeeded) { tryAutoRecomputeIfNotSolve(Obj);// we have to update the solver after this aborted addition. @@ -7911,8 +8171,9 @@ void CmdSketcherConstrainRadiam::applyConstraint(std::vector& selSeq, const Part::GeomCircle* circle = static_cast(geom); radiam = circle->getRadius(); isCircle = true; - if (isBsplinePole(geom)) + if (isBsplinePole(geom)) { isPole = true; + } } else { Gui::TranslatedUserWarning( @@ -7927,16 +8188,22 @@ void CmdSketcherConstrainRadiam::applyConstraint(std::vector& selSeq, openCommand(QT_TRANSLATE_NOOP("Command", "Add radiam constraint")); if (isPole) { - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Weight',%d,%f))", GeoId, radiam); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Weight',%d,%f))", + GeoId, + radiam); } else if (isCircle) { - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Diameter',%d,%f))", GeoId, radiam * 2); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Diameter',%d,%f))", + GeoId, + radiam * 2); } else { - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Radius',%d,%f))", GeoId, radiam); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Radius',%d,%f))", + GeoId, + radiam); } const std::vector& ConStr = Obj->Constraints.getValues(); @@ -7967,13 +8234,15 @@ void CmdSketcherConstrainRadiam::updateAction(int mode) { switch (mode) { case Reference: - if (getAction()) + if (getAction()) { getAction()->setIcon( Gui::BitmapFactory().iconFromTheme("Constraint_Radiam_Driven")); + } break; case Driving: - if (getAction()) + if (getAction()) { getAction()->setIcon(Gui::BitmapFactory().iconFromTheme("Constraint_Radiam")); + } break; } } @@ -8007,8 +8276,9 @@ void CmdSketcherCompConstrainRadDia::activated(int iMsg) else if (iMsg == 2) { rcCmdMgr.runCommandByName("Sketcher_ConstrainRadiam"); } - else + else { return; + } // Save new choice as default ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( @@ -8064,8 +8334,9 @@ Gui::Action* CmdSketcherCompConstrainRadDia::createAction() void CmdSketcherCompConstrainRadDia::updateAction(int mode) { Gui::ActionGroup* pcAction = qobject_cast(getAction()); - if (!pcAction) + if (!pcAction) { return; + } QList a = pcAction->actions(); int index = pcAction->property("defaultAction").toInt(); @@ -8089,8 +8360,9 @@ void CmdSketcherCompConstrainRadDia::languageChange() { Command::languageChange(); - if (!_pcAction) + if (!_pcAction) { return; + } Gui::ActionGroup* pcAction = qobject_cast(_pcAction); QList a = pcAction->actions(); @@ -8214,10 +8486,12 @@ void CmdSketcherConstrainAngle::activated(int iMsg) int GeoId1, GeoId2 = GeoEnum::GeoUndef, GeoId3 = GeoEnum::GeoUndef; Sketcher::PointPos PosId1, PosId2 = Sketcher::PointPos::none, PosId3 = Sketcher::PointPos::none; getIdsFromName(SubNames[0], Obj, GeoId1, PosId1); - if (SubNames.size() > 1) + if (SubNames.size() > 1) { getIdsFromName(SubNames[1], Obj, GeoId2, PosId2); - if (SubNames.size() > 2) + } + if (SubNames.size() > 2) { getIdsFromName(SubNames[2], Obj, GeoId3, PosId3); + } if (SubNames.size() == 3) {// standalone implementation of angle-via-point @@ -8305,12 +8579,15 @@ void CmdSketcherConstrainAngle::activated(int iMsg) == Reference) {// it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; }; @@ -8364,14 +8641,18 @@ void CmdSketcherConstrainAngle::activated(int iMsg) // get the end points of the line segments that are closest to the intersection // point Base::Vector3d s3d(s.x, s.y, p1[0].z); - if (Base::DistanceP2(s3d, p1[0]) < Base::DistanceP2(s3d, p1[1])) + if (Base::DistanceP2(s3d, p1[0]) < Base::DistanceP2(s3d, p1[1])) { PosId1 = Sketcher::PointPos::start; - else + } + else { PosId1 = Sketcher::PointPos::end; - if (Base::DistanceP2(s3d, p2[0]) < Base::DistanceP2(s3d, p2[1])) + } + if (Base::DistanceP2(s3d, p2[0]) < Base::DistanceP2(s3d, p2[1])) { PosId2 = Sketcher::PointPos::start; - else + } + else { PosId2 = Sketcher::PointPos::end; + } } else { // if all points are collinear @@ -8430,12 +8711,15 @@ void CmdSketcherConstrainAngle::activated(int iMsg) == Reference) {// it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -8467,12 +8751,15 @@ void CmdSketcherConstrainAngle::activated(int iMsg) // it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -8493,12 +8780,15 @@ void CmdSketcherConstrainAngle::activated(int iMsg) // it is a constraint on a external line, make it non-driving const std::vector& ConStr = Obj->Constraints.getValues(); - Gui::cmdAppObjectArgs( - selection[0].getObject(), "setDriving(%d,%s)", ConStr.size() - 1, "False"); + Gui::cmdAppObjectArgs(selection[0].getObject(), + "setDriving(%d,%s)", + ConStr.size() - 1, + "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -8561,14 +8851,18 @@ void CmdSketcherConstrainAngle::applyConstraint(std::vector& selSeq, // get the end points of the line segments that are closest to the intersection // point Base::Vector3d s3d(s.x, s.y, p1[0].z); - if (Base::DistanceP2(s3d, p1[0]) < Base::DistanceP2(s3d, p1[1])) + if (Base::DistanceP2(s3d, p1[0]) < Base::DistanceP2(s3d, p1[1])) { PosId1 = Sketcher::PointPos::start; - else + } + else { PosId1 = Sketcher::PointPos::end; - if (Base::DistanceP2(s3d, p2[0]) < Base::DistanceP2(s3d, p2[1])) + } + if (Base::DistanceP2(s3d, p2[0]) < Base::DistanceP2(s3d, p2[1])) { PosId2 = Sketcher::PointPos::start; - else + } + else { PosId2 = Sketcher::PointPos::end; + } } else { // if all points are collinear @@ -8630,8 +8924,9 @@ void CmdSketcherConstrainAngle::applyConstraint(std::vector& selSeq, Gui::cmdAppObjectArgs(Obj, "setDriving(%d,%s)", ConStr.size() - 1, "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; } @@ -8733,8 +9028,9 @@ void CmdSketcherConstrainAngle::applyConstraint(std::vector& selSeq, Gui::cmdAppObjectArgs(Obj, "setDriving(%d,%s)", ConStr.size() - 1, "False"); finishDatumConstraint(this, Obj, false); } - else + else { finishDatumConstraint(this, Obj, true); + } return; }; @@ -8744,14 +9040,16 @@ void CmdSketcherConstrainAngle::updateAction(int mode) { switch (mode) { case Reference: - if (getAction()) + if (getAction()) { getAction()->setIcon( Gui::BitmapFactory().iconFromTheme("Constraint_InternalAngle_Driven")); + } break; case Driving: - if (getAction()) + if (getAction()) { getAction()->setIcon( Gui::BitmapFactory().iconFromTheme("Constraint_InternalAngle")); + } break; } } @@ -8889,10 +9187,12 @@ void CmdSketcherConstrainEqual::activated(int iMsg) arcSel = true; } else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) { - if (isBsplinePole(geo)) + if (isBsplinePole(geo)) { weightSel = true; - else + } + else { circSel = true; + } } else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) { ellipsSel = true; @@ -9000,8 +9300,10 @@ void CmdSketcherConstrainEqual::applyConstraint(std::vector& selSeq, // undo command open openCommand(QT_TRANSLATE_NOOP("Command", "Add equality constraint")); - Gui::cmdAppObjectArgs( - Obj, "addConstraint(Sketcher.Constraint('Equal',%d,%d))", GeoId1, GeoId2); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Equal',%d,%d))", + GeoId1, + GeoId2); // finish the transaction and update commitCommand(); tryAutoRecompute(Obj); @@ -9481,8 +9783,9 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg) && isVertex(GeoId2, PosId2) && !isSimpleVertex(Obj, GeoId2, PosId2) && isEdge(GeoId3, PosId3))) { - Gui::TranslatedUserWarning( - Obj, QObject::tr("Wrong selection"), QObject::tr("Incompatible geometry is selected.")); + Gui::TranslatedUserWarning(Obj, + QObject::tr("Wrong selection"), + QObject::tr("Incompatible geometry is selected.")); return; }; @@ -9529,8 +9832,9 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg) ui_Datum.labelEdit->setSingleStep(0.05); // Unable to bind, because the constraint does not yet exist - if (dlg.exec() != QDialog::Accepted) + if (dlg.exec() != QDialog::Accepted) { return; + } ui_Datum.labelEdit->pushToHistory(); Base::Quantity newQuant = ui_Datum.labelEdit->value(); @@ -9540,20 +9844,22 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg) openCommand(QT_TRANSLATE_NOOP("Command", "Add Snell's law constraint")); bool safe = addConstraintSafely(Obj, [&]() { - if (!IsPointAlreadyOnCurve(GeoId2, GeoId1, PosId1, Obj)) + if (!IsPointAlreadyOnCurve(GeoId2, GeoId1, PosId1, Obj)) { Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Coincident',%d,%d,%d,%d))", GeoId1, static_cast(PosId1), GeoId2, static_cast(PosId2)); + } - if (!IsPointAlreadyOnCurve(GeoId3, GeoId1, PosId1, Obj)) + if (!IsPointAlreadyOnCurve(GeoId3, GeoId1, PosId1, Obj)) { Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d))", GeoId1, static_cast(PosId1), GeoId3); + } Gui::cmdAppObjectArgs( selection[0].getObject(), @@ -9574,8 +9880,9 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg) }*/ }); - if (!safe) + if (!safe) { return; + } else { commitCommand(); tryAutoRecompute(Obj); @@ -9662,8 +9969,9 @@ void CmdSketcherToggleDrivingConstraint::activated(int iMsg) for (std::vector::const_iterator it = SubNames.begin(); it != SubNames.end(); ++it) { // see if we have constraints, if we do it is not a mode change, but a toggle. - if (it->size() > 10 && it->substr(0, 10) == "Constraint") + if (it->size() > 10 && it->substr(0, 10) == "Constraint") { modeChange = false; + } } } @@ -9716,10 +10024,12 @@ void CmdSketcherToggleDrivingConstraint::activated(int iMsg) } } - if (successful > 0) + if (successful > 0) { commitCommand(); - else + } + else { abortCommand(); + } tryAutoRecompute(Obj); @@ -9804,10 +10114,12 @@ void CmdSketcherToggleActiveConstraint::activated(int iMsg) } } - if (successful > 0) + if (successful > 0) { commitCommand(); - else + } + else { abortCommand(); + } tryAutoRecompute(Obj); diff --git a/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp b/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp index 9a88f9c193..e4d3ec1017 100644 --- a/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp +++ b/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp @@ -72,9 +72,12 @@ using namespace Sketcher; //**************************** EditModeConstraintCoinManager class ****************************** EditModeConstraintCoinManager::EditModeConstraintCoinManager( - ViewProviderSketch& vp, DrawingParameters& drawingParams, - GeometryLayerParameters& geometryLayerParams, ConstraintParameters& constraintParams, - EditModeScenegraphNodes& editModeScenegraph, CoinMapping& coinMap) + ViewProviderSketch& vp, + DrawingParameters& drawingParams, + GeometryLayerParameters& geometryLayerParams, + ConstraintParameters& constraintParams, + EditModeScenegraphNodes& editModeScenegraph, + CoinMapping& coinMap) : viewProvider(vp) , drawingParameters(drawingParams) , geometryLayerParameters(geometryLayerParams) @@ -99,9 +102,10 @@ void EditModeConstraintCoinManager::updateVirtualSpace() SbBool* sws = editModeScenegraphNodes.constrGroup->enable.startEditing(); - for (size_t i = 0; i < constrlist.size(); i++) + for (size_t i = 0; i < constrlist.size(); i++) { sws[i] = !(constrlist[i]->isInVirtualSpace != isshownvirtualspace);// XOR of constraint mode and VP mode + } editModeScenegraphNodes.constrGroup->enable.finishEditing(); @@ -128,8 +132,9 @@ void EditModeConstraintCoinManager::processConstraints(const GeoListFacade& geol // reset point if the constraint type has changed Restart: // check if a new constraint arrived - if (constrlist.size() != vConstrType.size()) + if (constrlist.size() != vConstrType.size()) { rebuildConstraintNodes(geolistfacade); + } assert(int(constrlist.size()) == editModeScenegraphNodes.constrGroup->getNumChildren()); assert(int(vConstrType.size()) == editModeScenegraphNodes.constrGroup->getNumChildren()); @@ -316,18 +321,21 @@ Restart: angleplus = (startangle + endangle) / 2; midpos = aop->getFocus(); } - else + else { break; + } if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId() || geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() || geo->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId()) { Base::Vector3d majDir, minDir, rvec; - majDir = Base::Vector3d( - cos(angle), sin(angle), 0);// direction of major axis of ellipse - minDir = Base::Vector3d( - -majDir.y, majDir.x, 0);// direction of minor axis of ellipse + majDir = Base::Vector3d(cos(angle), + sin(angle), + 0);// direction of major axis of ellipse + minDir = Base::Vector3d(-majDir.y, + majDir.x, + 0);// direction of minor axis of ellipse rvec = (ra * cos(angleplus)) * majDir + (rb * sin(angleplus)) * minDir; midpos += rvec; @@ -413,13 +421,11 @@ Restart: // get the geometry const Part::Geometry* geo1 = geolistfacade.getGeometryFromGeoId(Constr->First); const Part::Geometry* geo2 = geolistfacade.getGeometryFromGeoId(Constr->Second); - Base::Vector3d midpos1, dir1, norm1; Base::Vector3d midpos2, dir2, norm2; bool twoIcons = false;// a very local flag. It's set to true to indicate that // the second dir+norm are valid and should be used - if (Constr->Third != GeoEnum::GeoUndef ||// perpty via point Constr->FirstPos != Sketcher::PointPos::none) {// endpoint-to-curve or @@ -430,16 +436,19 @@ Restart: do {// dummy loop to use break =) Maybe goto? ptGeoId = Constr->First; ptPosId = Constr->FirstPos; - if (ptPosId != Sketcher::PointPos::none) + if (ptPosId != Sketcher::PointPos::none) { break; + } ptGeoId = Constr->Second; ptPosId = Constr->SecondPos; - if (ptPosId != Sketcher::PointPos::none) + if (ptPosId != Sketcher::PointPos::none) { break; + } ptGeoId = Constr->Third; ptPosId = Constr->ThirdPos; - if (ptPosId != Sketcher::PointPos::none) + if (ptPosId != Sketcher::PointPos::none) { break; + } assert(0);// no point found! } while (false); @@ -483,8 +492,9 @@ Restart: dir1 = Base::Vector3d(-norm1.y, norm1.x, 0); midpos1 = circle->getCenter() + circle->getRadius() * norm1; } - else + else { break; + } if (geo2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment* lineSeg2 = @@ -511,8 +521,9 @@ Restart: dir2 = Base::Vector3d(-norm2.y, norm2.x, 0); midpos2 = circle->getCenter() + circle->getRadius() * norm2; } - else + else { break; + } twoIcons = true; } @@ -629,8 +640,9 @@ Restart: angle1plus = (startangle + endangle) / 2; midpos1 = aop->getFocus(); } - else + else { break; + } if (geo2->getTypeId() == Part::GeomCircle::getClassTypeId()) { const Part::GeomCircle* circle = @@ -696,8 +708,9 @@ Restart: angle2plus = (startangle + endangle) / 2; midpos2 = aop->getFocus(); } - else + else { break; + } if (geo1->getTypeId() == Part::GeomEllipse::getClassTypeId() || geo1->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() @@ -708,8 +721,9 @@ Restart: majDir = Base::Vector3d(cos(angle1), sin(angle1), 0);// direction of major axis of ellipse - minDir = Base::Vector3d( - -majDir.y, majDir.x, 0);// direction of minor axis of ellipse + minDir = Base::Vector3d(-majDir.y, + majDir.x, + 0);// direction of minor axis of ellipse rvec = (r1a * cos(angle1plus)) * majDir + (r1b * sin(angle1plus)) * minDir; midpos1 += rvec; @@ -736,8 +750,9 @@ Restart: majDir = Base::Vector3d(cos(angle2), sin(angle2), 0);// direction of major axis of ellipse - minDir = Base::Vector3d( - -majDir.y, majDir.x, 0);// direction of minor axis of ellipse + minDir = Base::Vector3d(-majDir.y, + majDir.x, + 0);// direction of minor axis of ellipse rvec = (r2a * cos(angle2plus)) * majDir + (r2b * sin(angle2plus)) * minDir; midpos2 += rvec; @@ -751,8 +766,9 @@ Restart: midpos2 += r2a * norm2; } } - else// Parallel can only apply to a GeomLineSegment + else {// Parallel can only apply to a GeomLineSegment break; + } } else { const Part::GeomLineSegment* lineSeg1 = @@ -809,15 +825,13 @@ Restart: case DistanceX: case DistanceY: { assert(Constr->First >= -extGeoCount && Constr->First < intGeoCount); - Base::Vector3d pnt1(0., 0., 0.), pnt2(0., 0., 0.); + const Part::Geometry* geo = geolistfacade.getGeometryFromGeoId(Constr->Second); if (Constr->SecondPos != Sketcher::PointPos::none) {// point to point distance pnt1 = geolistfacade.getPoint(Constr->First, Constr->FirstPos); pnt2 = geolistfacade.getPoint(Constr->Second, Constr->SecondPos); } else if (Constr->Second != GeoEnum::GeoUndef) { - const Part::Geometry* geo = - geolistfacade.getGeometryFromGeoId(Constr->Second); if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) { const Part::GeomLineSegment* lineSeg = static_cast(geo); @@ -860,9 +874,18 @@ Restart: auto circleSeg2 = static_cast(geo); GetCirclesMinimalDistance(circleSeg1, circleSeg2, pnt1, pnt2); } + else if (Constr->FirstPos + != Sketcher::PointPos::none) {// point to circle distance + auto circleSeg2 = static_cast(geo); + pnt1 = geolistfacade.getPoint(Constr->First, Constr->FirstPos); + Base::Vector3d v = pnt1 - circleSeg2->getCenter(); + v = v.Normalize(); + pnt2 = circleSeg2->getCenter() + circleSeg2->getRadius() * v; + } } - else + else { break; + } } else if (Constr->FirstPos != Sketcher::PointPos::none) { pnt2 = geolistfacade.getPoint(Constr->First, Constr->FirstPos); @@ -877,11 +900,13 @@ Restart: pnt1 = lineSeg->getStartPoint(); pnt2 = lineSeg->getEndPoint(); } - else + else { break; + } } - else + else { break; + } SoDatumLabel* asciiText = static_cast( sep->getChild(static_cast(ConstraintNodePosition::DatumLabelIndex))); @@ -890,12 +915,15 @@ Restart: asciiText->string = SbString(getPresentationString(Constr).toUtf8().constData()); - if (Constr->Type == Distance) + if (Constr->Type == Distance) { asciiText->datumtype = SoDatumLabel::DISTANCE; - else if (Constr->Type == DistanceX) + } + else if (Constr->Type == DistanceX) { asciiText->datumtype = SoDatumLabel::DISTANCEX; - else if (Constr->Type == DistanceY) + } + else if (Constr->Type == DistanceY) { asciiText->datumtype = SoDatumLabel::DISTANCEY; + } // Assign the Datum Points asciiText->pnts.setNum(2); @@ -933,16 +961,19 @@ Restart: do {// dummy loop to use break =) Maybe goto? ptGeoId = Constr->First; ptPosId = Constr->FirstPos; - if (ptPosId != Sketcher::PointPos::none) + if (ptPosId != Sketcher::PointPos::none) { break; + } ptGeoId = Constr->Second; ptPosId = Constr->SecondPos; - if (ptPosId != Sketcher::PointPos::none) + if (ptPosId != Sketcher::PointPos::none) { break; + } ptGeoId = Constr->Third; ptPosId = Constr->ThirdPos; - if (ptPosId != Sketcher::PointPos::none) + if (ptPosId != Sketcher::PointPos::none) { break; + } assert(0);// no point found! } while (false); @@ -957,7 +988,11 @@ Restart: dir.RotateZ(-M_PI / 2.0); relPos = seekConstraintPosition( - pos, norm, dir, 2.5, editModeScenegraphNodes.constrGroup->getChild(i)); + pos, + norm, + dir, + 2.5, + editModeScenegraphNodes.constrGroup->getChild(i)); auto translation = static_cast(sep->getChild( static_cast(ConstraintNodePosition::FirstTranslationIndex))); @@ -1167,8 +1202,9 @@ Restart: const Part::Geometry* geo2 = geolistfacade.getGeometryFromGeoId(Constr->Second); if (geo1->getTypeId() != Part::GeomLineSegment::getClassTypeId() - || geo2->getTypeId() != Part::GeomLineSegment::getClassTypeId()) + || geo2->getTypeId() != Part::GeomLineSegment::getClassTypeId()) { break; + } const Part::GeomLineSegment* lineSeg1 = static_cast(geo1); const Part::GeomLineSegment* lineSeg2 = @@ -1269,8 +1305,9 @@ Restart: break; } } - else + else { break; + } SoDatumLabel* asciiText = static_cast( sep->getChild(static_cast(ConstraintNodePosition::DatumLabelIndex))); @@ -1323,11 +1360,13 @@ Restart: pnt1 = center - radius * Base::Vector3d(cos(angle), sin(angle), 0.); pnt2 = center + radius * Base::Vector3d(cos(angle), sin(angle), 0.); } - else + else { break; + } } - else + else { break; + } SbVec3f p1(pnt1.x, pnt1.y, zConstrH); SbVec3f p2(pnt2.x, pnt2.y, zConstrH); @@ -1390,11 +1429,13 @@ Restart: pnt1 = circle->getCenter(); pnt2 = pnt1 + radius * Base::Vector3d(cos(angle), sin(angle), 0.); } - else + else { break; + } } - else + else { break; + } SbVec3f p1(pnt1.x, pnt1.y, zConstrH); SbVec3f p2(pnt2.x, pnt2.y, zConstrH); @@ -1403,12 +1444,14 @@ Restart: sep->getChild(static_cast(ConstraintNodePosition::DatumLabelIndex))); // Get display string with units hidden if so requested - if (Constr->Type == Weight) + if (Constr->Type == Weight) { asciiText->string = SbString(QString::number(Constr->getValue()).toStdString().c_str()); - else + } + else { asciiText->string = SbString(getPresentationString(Constr).toUtf8().constData()); + } asciiText->datumtype = SoDatumLabel::RADIUS; asciiText->param1 = Constr->LabelDistance; @@ -1430,8 +1473,9 @@ Restart: } } catch (Base::Exception& e) { - Base::Console().DeveloperError( - "EditModeConstraintCoinManager", "Exception during draw: %s\n", e.what()); + Base::Console().DeveloperError("EditModeConstraintCoinManager", + "Exception during draw: %s\n", + e.what()); e.ReportException(); } catch (...) { @@ -1483,19 +1527,22 @@ Base::Vector3d EditModeConstraintCoinManager::seekConstraintPosition(const Base: SoNode* tailFather2 = path->getNode(length - 3); // checking if a constraint is the same as the one selected - if (tailFather1 == constraint || tailFather2 == constraint) + if (tailFather1 == constraint || tailFather2 == constraint) { isConstraintAtPosition = false; + } } else { isConstraintAtPosition = false; } multiplier *= -1;// search in both sides - if (multiplier >= 0) + if (multiplier >= 0) { multiplier++;// Increment the multiplier + } } - if (multiplier == 10) + if (multiplier == 10) { relPos = norm * 0.5f;// no free position found + } return relPos * step; } @@ -1532,8 +1579,9 @@ void EditModeConstraintCoinManager::updateConstraintColor( // It may happen that color updates are triggered by programmatic selection changes before a // command final update. Then constraints may have been changed and the color will be // updated as part - if (type != vConstrType[i]) + if (type != vConstrType[i]) { break; + } bool hasDatumLabel = (type == Sketcher::Angle || type == Sketcher::Radius || type == Sketcher::Diameter || type == Sketcher::Weight @@ -1695,7 +1743,8 @@ void EditModeConstraintCoinManager::rebuildConstraintNodes(const GeoListFacade& } void EditModeConstraintCoinManager::rebuildConstraintNodes( - const GeoListFacade& geolistfacade, const std::vector constrlist, + const GeoListFacade& geolistfacade, + const std::vector constrlist, SbVec3f norm) { @@ -1868,8 +1917,9 @@ QString EditModeConstraintCoinManager::getPresentationString(const Constraint* c double factor; // unit scaling factor, currently not used Base::UnitSystem unitSys;// current unit system - if (!constraint->isActive) + if (!constraint->isActive) { return QString::fromLatin1(" "); + } // Get the current name parameter string of the constraint nameStr = QString::fromStdString(constraint->Name); @@ -1963,8 +2013,9 @@ std::set EditModeConstraintCoinManager::detectPreselectionConstr(const SoPi // Get the constraints' tail SoNode* tailFather2 = path->getNode(path->getLength() - 3); - if (tailFather2 != editModeScenegraphNodes.constrGroup) + if (tailFather2 != editModeScenegraphNodes.constrGroup) { return constrIndices; + } SoNode* tail = path->getTail(); @@ -2053,7 +2104,8 @@ std::set EditModeConstraintCoinManager::detectPreselectionConstr(const SoPi SbVec3f constrPos = absPos + scaleFactor * trans; SbVec2f iconCoords = ViewProviderSketchCoinAttorney::getScreenCoordinates( - viewProvider, SbVec2f(constrPos[0], constrPos[1])); + viewProvider, + SbVec2f(constrPos[0], constrPos[1])); // cursorPos is SbVec2s in screen coordinates coming from SoEvent in // mousemove @@ -2116,10 +2168,12 @@ SbVec3s EditModeConstraintCoinManager::getDisplayedSize(const SoImage* iconPtr) { SbVec3s iconSize = iconPtr->image.getValue().getSize(); - if (iconPtr->width.getValue() != -1) + if (iconPtr->width.getValue() != -1) { iconSize[0] = iconPtr->width.getValue(); - if (iconPtr->height.getValue() != -1) + } + if (iconPtr->height.getValue() != -1) { iconSize[1] = iconPtr->height.getValue(); + } return iconSize; } @@ -2148,11 +2202,13 @@ void EditModeConstraintCoinManager::drawConstraintIcons(const GeoListFacade& geo bool multipleIcons = false; QString icoType = iconTypeFromConstraint(constraint); - if (icoType.isEmpty()) + if (icoType.isEmpty()) { continue; + } - if (constraint->Type != vConstrType[constrId]) + if (constraint->Type != vConstrType[constrId]) { break; + } switch (constraint->Type) { @@ -2178,8 +2234,9 @@ void EditModeConstraintCoinManager::drawConstraintIcons(const GeoListFacade& geo case Perpendicular: // second icon is available only when there is no common point if (constraint->FirstPos == Sketcher::PointPos::none - && constraint->Third == GeoEnum::GeoUndef) + && constraint->Third == GeoEnum::GeoUndef) { multipleIcons = true; + } break; case Equal: multipleIcons = true; @@ -2207,10 +2264,12 @@ void EditModeConstraintCoinManager::drawConstraintIcons(const GeoListFacade& geo SoTranslation* translationPtr = static_cast( sep->getChild(static_cast(ConstraintNodePosition::FirstTranslationIndex))); - if (dynamic_cast(translationPtr)) + if (dynamic_cast(translationPtr)) { absPos = static_cast(translationPtr)->abPos.getValue(); - else + } + else { absPos = translationPtr->translation.getValue(); + } SoImage* coinIconPtr = dynamic_cast( sep->getChild(static_cast(ConstraintNodePosition::FirstIconIndex))); @@ -2243,10 +2302,12 @@ void EditModeConstraintCoinManager::drawConstraintIcons(const GeoListFacade& geo } if (multipleIcons) { - if (constraint->Name.empty()) + if (constraint->Name.empty()) { thisIcon.label = QString::number(constrId + 1); - else + } + else { thisIcon.label = QString::fromUtf8(constraint->Name.c_str()); + } iconQueue.push_back(thisIcon); // Note that the second translation is meant to be applied after the first. @@ -2256,11 +2317,13 @@ void EditModeConstraintCoinManager::drawConstraintIcons(const GeoListFacade& geo if (numChildren > static_cast(ConstraintNodePosition::SecondConstraintIdIndex)) { translationPtr = static_cast(sep->getChild( static_cast(ConstraintNodePosition::SecondTranslationIndex))); - if (dynamic_cast(translationPtr)) + if (dynamic_cast(translationPtr)) { thisIcon.position += static_cast(translationPtr)->abPos.getValue(); - else + } + else { thisIcon.position += translationPtr->translation.getValue(); + } thisIcon.destination = dynamic_cast( sep->getChild(static_cast(ConstraintNodePosition::SecondIconIndex))); @@ -2269,10 +2332,12 @@ void EditModeConstraintCoinManager::drawConstraintIcons(const GeoListFacade& geo } } else { - if (constraint->Name.empty()) + if (constraint->Name.empty()) { thisIcon.label = QString(); - else + } + else { thisIcon.label = QString::fromUtf8(constraint->Name.c_str()); + } } iconQueue.push_back(thisIcon); @@ -2322,19 +2387,23 @@ void EditModeConstraintCoinManager::combineConstraintIcons(IconQueue iconQueue) } if (addedToGroup) { - if (i == iconQueue.end()) + if (i == iconQueue.end()) { // We just got the last icon out of iconQueue break; - else + } + else { // Start looking through the iconQueue again, in case // we have an icon that's now close enough to thisGroup i = iconQueue.begin(); + } } - else + else { ++i; + } } - else// if !visible we skip it + else {// if !visible we skip it i++; + } } } @@ -2387,8 +2456,9 @@ void EditModeConstraintCoinManager::drawMergedConstraintIcons(IconQueue iconQueu maxColorPriority = constrColorPriority(i->constraintId); - if (idString.length()) + if (idString.length()) { idString.append(QString::fromLatin1(",")); + } idString.append(QString::number(i->constraintId)); i = iconQueue.erase(i); @@ -2468,8 +2538,9 @@ void EditModeConstraintCoinManager::drawMergedConstraintIcons(IconQueue iconQueu if (bb == boundingBoxesVec.begin()) { // The first bounding box is for the icon at left, so assign // all IDs for that type of constraint to the icon. - for (std::vector::iterator j = ids.begin(); j != ids.end(); ++j) + for (std::vector::iterator j = ids.begin(); j != ids.end(); ++j) { nextIds.insert(*j); + } } else { nextIds.insert(*(id++)); @@ -2489,11 +2560,13 @@ void EditModeConstraintCoinManager::drawMergedConstraintIcons(IconQueue iconQueu /// Note: labels, labelColors, and boundingBoxes are all /// assumed to be the same length. -QImage EditModeConstraintCoinManager::renderConstrIcon(const QString& type, const QColor& iconColor, +QImage EditModeConstraintCoinManager::renderConstrIcon(const QString& type, + const QColor& iconColor, const QStringList& labels, const QList& labelColors, double iconRotation, - std::vector* boundingBoxes, int* vPad) + std::vector* boundingBoxes, + int* vPad) { // Constants to help create constraint icons QString joinStr = QString::fromLatin1(", "); @@ -2520,8 +2593,9 @@ QImage EditModeConstraintCoinManager::renderConstrIcon(const QString& type, cons // See Qt docs on qRect::bottom() for explanation of the +1 int pxBelowBase = qfm.boundingRect(labels.join(joinStr)).bottom() + 1; - if (vPad) + if (vPad) { *vPad = pxBelowBase; + } QTransform rotation; rotation.rotate(iconRotation); @@ -2530,8 +2604,9 @@ QImage EditModeConstraintCoinManager::renderConstrIcon(const QString& type, cons QImage image = roticon.copy(0, 0, roticon.width() + labelWidth, roticon.height() + pxBelowBase); // Make a bounding box for the icon - if (boundingBoxes) + if (boundingBoxes) { boundingBoxes->push_back(QRect(0, 0, roticon.width(), roticon.height())); + } // Render the Icons QPainter qp(&image); @@ -2556,10 +2631,12 @@ QImage EditModeConstraintCoinManager::renderConstrIcon(const QString& type, cons qp.setPen(*colorItr); - if (labelItr + 1 == labels.end())// if this is the last label + if (labelItr + 1 == labels.end()) {// if this is the last label labelStr = *labelItr; - else + } + else { labelStr = *labelItr + joinStr; + } // Note: text can sometimes draw to the left of the starting // position, eg italic fonts. Check QFontMetrics @@ -2585,8 +2662,11 @@ void EditModeConstraintCoinManager::drawTypicalConstraintIcon(const constrIconQu { QColor color = constrColor(i.constraintId); - QImage image = renderConstrIcon( - i.type, color, QStringList(i.label), QList() << color, i.iconRotation); + QImage image = renderConstrIcon(i.type, + color, + QStringList(i.label), + QList() << color, + i.iconRotation); i.infoPtr->string.setValue(QString::number(i.constraintId).toLatin1().data()); sendConstraintIconToCoin(image, i.destination); @@ -2651,32 +2731,41 @@ void EditModeConstraintCoinManager::clearCoinImage(SoImage* soImagePtr) QColor EditModeConstraintCoinManager::constrColor(int constraintId) { auto toQColor = [](auto sbcolor) -> QColor { - return QColor( - (int)(sbcolor[0] * 255.0f), (int)(sbcolor[1] * 255.0f), (int)(sbcolor[2] * 255.0f)); + return QColor((int)(sbcolor[0] * 255.0f), + (int)(sbcolor[1] * 255.0f), + (int)(sbcolor[2] * 255.0f)); }; const auto constraints = ViewProviderSketchCoinAttorney::getConstraints(viewProvider); - if (ViewProviderSketchCoinAttorney::isConstraintPreselected(viewProvider, constraintId)) + if (ViewProviderSketchCoinAttorney::isConstraintPreselected(viewProvider, constraintId)) { return toQColor(drawingParameters.PreselectColor); - else if (ViewProviderSketchCoinAttorney::isConstraintSelected(viewProvider, constraintId)) + } + else if (ViewProviderSketchCoinAttorney::isConstraintSelected(viewProvider, constraintId)) { return toQColor(drawingParameters.SelectColor); - else if (!constraints[constraintId]->isActive) + } + else if (!constraints[constraintId]->isActive) { return toQColor(drawingParameters.DeactivatedConstrDimColor); - else if (!constraints[constraintId]->isDriving) + } + else if (!constraints[constraintId]->isDriving) { return toQColor(drawingParameters.NonDrivingConstrDimColor); - else + } + else { return toQColor(drawingParameters.ConstrIcoColor); + } } int EditModeConstraintCoinManager::constrColorPriority(int constraintId) { - if (ViewProviderSketchCoinAttorney::isConstraintPreselected(viewProvider, constraintId)) + if (ViewProviderSketchCoinAttorney::isConstraintPreselected(viewProvider, constraintId)) { return 3; - else if (ViewProviderSketchCoinAttorney::isConstraintSelected(viewProvider, constraintId)) + } + else if (ViewProviderSketchCoinAttorney::isConstraintSelected(viewProvider, constraintId)) { return 2; - else + } + else { return 1; + } } SoSeparator* EditModeConstraintCoinManager::getConstraintIdSeparator(int i) diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 442d530793..b8dcae8dff 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -1640,6 +1640,12 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d& toPo const Part::GeomCircle* circleSeg1 = static_cast(geo1); const Part::GeomCircle* circleSeg2 = static_cast(geo); GetCirclesMinimalDistance(circleSeg1, circleSeg2, p1, p2); + } else if (Constr->FirstPos != Sketcher::PointPos::none) { //point to circle distance + auto circleSeg2 = static_cast(geo); + p1 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); + Base::Vector3d v = p1 - circleSeg2->getCenter(); + v = v.Normalize(); + p2 = circleSeg2->getCenter() + circleSeg2->getRadius() * v; } } else