diff --git a/src/Base/Tools.h b/src/Base/Tools.h index 630739572..c73d014be 100644 --- a/src/Base/Tools.h +++ b/src/Base/Tools.h @@ -120,6 +120,13 @@ inline T toDegrees(T r) return static_cast((r/M_PI)*180.0); } +template +inline T fmod(T numerator, T denominator) +{ + T modulo = std::fmod(numerator, denominator); + return (modulo >= T(0)) ? modulo : modulo + denominator; +} + // ---------------------------------------------------------------------------- class BaseExport StopWatch diff --git a/src/Mod/Sketcher/App/PropertyConstraintList.cpp b/src/Mod/Sketcher/App/PropertyConstraintList.cpp index 8a3d71174..23cb85040 100644 --- a/src/Mod/Sketcher/App/PropertyConstraintList.cpp +++ b/src/Mod/Sketcher/App/PropertyConstraintList.cpp @@ -32,8 +32,6 @@ #include #include #include -#include - #include "PropertyConstraintList.h" #include "ConstraintPy.h" diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 59f84dc15..8e1fe4daa 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -27,11 +27,11 @@ # include # include # include -# include #endif #include #include +#include #include @@ -40,7 +40,6 @@ #include "SketchObject.h" #include "SketchObjectPy.h" #include "Sketch.h" -#include using namespace Sketcher; using namespace Base; @@ -390,6 +389,27 @@ int SketchObject::delConstraintOnPoint(int GeoId, PointPos PosId, bool onlyCoinc return -1; // no such constraint } +int SketchObject::transferConstraints(int fromGeoId, PointPos fromPosId, int toGeoId, PointPos toPosId) +{ + const std::vector &vals = this->Constraints.getValues(); + std::vector newVals(vals); + for (int i=0; i < int(newVals.size()); i++) { + if (vals[i]->First == fromGeoId && vals[i]->FirstPos == fromPosId) { + Constraint *constNew = newVals[i]->clone(); + constNew->First = toGeoId; + constNew->FirstPos = toPosId; + newVals[i] = constNew; + } else if (vals[i]->Second == fromGeoId && vals[i]->SecondPos == fromPosId) { + Constraint *constNew = newVals[i]->clone(); + constNew->Second = toGeoId; + constNew->SecondPos = toPosId; + newVals[i] = constNew; + } + } + this->Constraints.setValues(newVals); + return 0; +} + int SketchObject::fillet(int GeoId, PointPos PosId, double radius, bool trim) { const std::vector &geomlist = this->Geometry.getValues(); @@ -537,27 +557,7 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) if (x1 < x0 && x2 > x0) { int newGeoId = addGeometry(geo); // go through all constraints and replace the point (GeoId,end) with (newGeoId,end) - const std::vector &constraints = Constraints.getValues(); - - std::vector newVals(constraints); - for (int i=0; i < int(newVals.size()); i++) { - if (constraints[i]->First == GeoId && - constraints[i]->FirstPos == end) { - - Constraint *constNew = newVals[i]->clone(); - constNew->First = newGeoId; - newVals[i] = constNew; - - } else if (constraints[i]->Second == GeoId && - constraints[i]->SecondPos == end) { - - Constraint *constNew = newVals[i]->clone(); - constNew->Second = newGeoId; - newVals[i] = constNew; - } - } - - this->Constraints.setValues(newVals); + transferConstraints(GeoId, end, newGeoId, end); movePoint(GeoId, end, point1); movePoint(newGeoId, start, point2); @@ -627,142 +627,79 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) } else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) { const Part::GeomCircle *circle = dynamic_cast(geo); Base::Vector3d center = circle->getCenter(); - double theta0 = atan2(point.y - center.y,point.x - center.x); + double theta0 = Base::fmod(atan2(point.y - center.y,point.x - center.x), 2.f*M_PI); if (GeoId1 >= 0 && GeoId2 >= 0) { - double theta1 = atan2(point1.y - center.y, point1.x - center.x); - double theta2 = atan2(point2.y - center.y, point2.x - center.x); - - if (theta0 < theta1 && theta0 < theta2) { - if (theta1 > theta2) - theta1 -= 2*M_PI; - else - theta2 -= 2*M_PI; - } else if (theta0 > theta1 && theta0 > theta2) { - if (theta1 > theta2) - theta2 += 2*M_PI; - else - theta1 += 2*M_PI; - } - - if (theta1 > theta2) { + double theta1 = Base::fmod(atan2(point1.y - center.y, point1.x - center.x), 2.f*M_PI); + double theta2 = Base::fmod(atan2(point2.y - center.y, point2.x - center.x), 2.f*M_PI); + if (Base::fmod(theta1 - theta0, 2.f*M_PI) > Base::fmod(theta2 - theta0, 2.f*M_PI)) { std::swap(GeoId1,GeoId2); std::swap(point1,point2); std::swap(theta1,theta2); } + if (theta1 == theta0 || theta1 == theta2) + return -1; + else if (theta1 > theta2) + theta2 += 2.f*M_PI; // Trim Point between intersection points - if (theta1 < theta0 && theta2 > theta0) { - // Create a new arc to substitute Circle in geometry list and set parameters - Part::GeomArcOfCircle *geoNew = new Part::GeomArcOfCircle(); - geoNew->setCenter(center); - geoNew->setRadius(circle->getRadius()); - geoNew->setRange(theta2, theta1); + // Create a new arc to substitute Circle in geometry list and set parameters + Part::GeomArcOfCircle *geoNew = new Part::GeomArcOfCircle(); + geoNew->setCenter(center); + geoNew->setRadius(circle->getRadius()); + geoNew->setRange(theta1, theta2); - std::vector< Part::Geometry * > newVals(geomlist); - newVals[GeoId] = geoNew; - Geometry.setValues(newVals); - delete geoNew; - rebuildVertexIndex(); + std::vector< Part::Geometry * > newVals(geomlist); + newVals[GeoId] = geoNew; + Geometry.setValues(newVals); + delete geoNew; + rebuildVertexIndex(); - // constrain the trimming points on the corresponding geometries - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = Sketcher::PointOnObject; - newConstr->First = GeoId; - newConstr->FirstPos = end; - newConstr->Second = GeoId1; - addConstraint(newConstr); + // constrain the trimming points on the corresponding geometries + Sketcher::Constraint *newConstr = new Sketcher::Constraint(); + newConstr->Type = Sketcher::PointOnObject; + newConstr->First = GeoId; + newConstr->FirstPos = start; + newConstr->Second = GeoId1; + addConstraint(newConstr); - newConstr->First = GeoId; - newConstr->FirstPos = start; - newConstr->Second = GeoId2; - addConstraint(newConstr); + newConstr->First = GeoId; + newConstr->FirstPos = end; + newConstr->Second = GeoId2; + addConstraint(newConstr); - delete newConstr; + delete newConstr; - return 0; - } else - return -1; + return 0; } } else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { const Part::GeomArcOfCircle *aoc = dynamic_cast(geo); Base::Vector3d center = aoc->getCenter(); - double theta0 = atan2(point.y - center.y,point.x - center.x); - - // Boolean if arc first parameter is greater than last parameter - bool swap; - + double startAngle, endAngle; + aoc->getRange(startAngle, endAngle); + double dir = (startAngle < endAngle) ? 1 : -1; // this is always == 1 + double arcLength = (endAngle - startAngle)*dir; + double theta0 = Base::fmod(atan2(point.y - center.y, point.x - center.x) - startAngle, 2.f*M_PI); // x0 if (GeoId1 >= 0 && GeoId2 >= 0) { - double theta1 = atan2(point1.y - center.y, point1.x - center.x); - double theta2 = atan2(point2.y - center.y, point2.x - center.x); - - double u1 = (theta1 >= 0) ? theta1 : theta1 + 2*M_PI; - double v1 = (theta2 >= 0) ? theta2 : theta2 + 2*M_PI; - - if (theta0 < theta1 && theta0 < theta2) { - if (theta1 > theta2) - theta1 -= 2*M_PI; - else - theta2 -= 2*M_PI; - } else if (theta0 > theta1 && theta0 > theta2) { - if (theta1 > theta2) - theta2 += 2*M_PI; - else - theta1 += 2*M_PI; - } - - // Getting Arc Trim Parameters - Note: for some reason aoc->getRange is not reliable - Handle_Geom_TrimmedCurve curve = Handle_Geom_TrimmedCurve::DownCast(aoc->handle()); - double u = (double) curve->FirstParameter(),v = (double) curve->LastParameter(); - // aoc->getRange(u,v); - u = fmod(u, 2.f*M_PI); - v = fmod(v, 2.f*M_PI); - - swap = (u > v); + double theta1 = Base::fmod(atan2(point1.y - center.y, point1.x - center.x) - startAngle, 2.f*M_PI) * dir; // x1 + double theta2 = Base::fmod(atan2(point2.y - center.y, point2.x - center.x) - startAngle, 2.f*M_PI) * dir; // x2 if (theta1 > theta2) { std::swap(GeoId1,GeoId2); std::swap(point1,point2); std::swap(theta1,theta2); } - - if ((swap && (!(u1 <= (1.001*u) && u1 >= 0.999 * v) && !(v1 <= (1.001*u) && v1 >= 0.999*v)) ) || - (!swap && (u1 >= (1.001*u ) && u1 <= 0.999*v) && (v1 >= (1.001*u ) && v1 <= 0.999*v) ) ) { + if (theta1 >= 0.001*arcLength && theta2 <= 0.999*arcLength) { // Trim Point between intersection points if (theta1 < theta0 && theta2 > theta0) { - // Setting the range manually to improve stability before adding constraints - int newGeoId = addGeometry(geo); - Part::GeomArcOfCircle *aoc = dynamic_cast(geomlist[GeoId]); - Part::GeomArcOfCircle *aoc2 = dynamic_cast(geomlist[newGeoId]); // go through all constraints and replace the point (GeoId,end) with (newGeoId,end) - const std::vector &constraints = Constraints.getValues(); + transferConstraints(GeoId, end, newGeoId, end); - std::vector newVals(constraints); - for (int i=0; i < int(newVals.size()); i++) { - if (constraints[i]->First == GeoId && - constraints[i]->FirstPos == end) { - - Constraint *constNew = newVals[i]->clone(); - constNew->First = newGeoId; - newVals[i] = constNew; - } else if (constraints[i]->Second == GeoId && - constraints[i]->SecondPos == end) { - - Constraint *constNew = newVals[i]->clone(); - constNew->Second = newGeoId; - newVals[i] = constNew; - } - } - - this->Constraints.setValues(newVals); - - // Setting the range manually to improve stability before adding constraints - u = fmod((double) curve->FirstParameter(), 2.f*M_PI); - v = fmod((double) curve->LastParameter(), 2.f*M_PI); - - aoc->setRange(u, theta1); - aoc2->setRange(theta2, v); + Part::GeomArcOfCircle *aoc1 = dynamic_cast(geomlist[GeoId]); + Part::GeomArcOfCircle *aoc2 = dynamic_cast(geomlist[newGeoId]); + aoc1->setRange(startAngle, startAngle + theta1); + aoc2->setRange(startAngle + theta2, endAngle); // constrain the trimming points on the corresponding geometries Sketcher::Constraint *newConstr = new Sketcher::Constraint(); @@ -796,71 +733,45 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) return 0; } else return -1; - } - - bool u1Valid = true, v1Valid = true; - - // Check if start and end of arcs have point on object constraints - if ((swap && v1 < 1.001*u && v1 > 0.999*v) || - (!swap && !(v1 > 1.001*u && v1 < 0.999*v)) ) { // drop the second intersection point - v1Valid = false; - } - - if ((swap && u1 < 1.001*u && u1 > 0.999*v) || - (!swap && !(u1 > 1.001* u && u1 < 0.999*v)) ) { // drop the first intersection point + } else if (theta1 < 0.001*arcLength) { // drop the second intersection point std::swap(GeoId1,GeoId2); std::swap(point1,point2); - - u1Valid = false; + } else if (theta2 > 0.999*arcLength) { } - - // If Both Parameters have invalid ranges. Leave trim operation - if(!v1Valid && !u1Valid) + else return -1; } if (GeoId1 >= 0) { - Handle_Geom_TrimmedCurve curve = Handle_Geom_TrimmedCurve::DownCast(aoc->handle()); - double u = (double) curve->FirstParameter(),v = (double) curve->LastParameter(); - // aoc->getRange(u,v); - u = fmod(u, 2.f*M_PI); - v = fmod(v, 2.f*M_PI); - - double theta1 = atan2(point1.y - center.y, point1.x - center.x); - - if (theta0 < 0) - theta0 += 2*M_PI; - - if (theta1 < 0) - theta1 += 2*M_PI; - - if ((theta1 > theta0) || - (swap && theta1 < theta0 && theta1 < v)) { // trim en - delConstraintOnPoint(GeoId, start, false); - - movePoint(GeoId, start, point1); - // constrain the trimming point on the corresponding geometry - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = Sketcher::PointOnObject; - newConstr->First = GeoId; - newConstr->FirstPos = start; - newConstr->Second = GeoId1; - addConstraint(newConstr); - delete newConstr; - return 0; - } - else if ((theta1 < theta0) || - (swap && theta1 > theta0 && theta1 > v)) { // trim line end - delConstraintOnPoint(GeoId, end, false); - movePoint(GeoId, end, point1); - Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = Sketcher::PointOnObject; - newConstr->First = GeoId; - newConstr->FirstPos = end; - newConstr->Second = GeoId1; - addConstraint(newConstr); - delete newConstr; - return 0; + double theta1 = Base::fmod(atan2(point1.y - center.y, point1.x - center.x) - startAngle, 2.f*M_PI) * dir; // x1 + if (theta1 >= 0.001*arcLength && theta1 <= 0.999*arcLength) { + if (theta1 > theta0) { // trim arc start + delConstraintOnPoint(GeoId, start, false); + Part::GeomArcOfCircle *aoc1 = dynamic_cast(geomlist[GeoId]); + aoc1->setRange(startAngle + theta1, endAngle); + // constrain the trimming point on the corresponding geometry + Sketcher::Constraint *newConstr = new Sketcher::Constraint(); + newConstr->Type = Sketcher::PointOnObject; + newConstr->First = GeoId; + newConstr->FirstPos = start; + newConstr->Second = GeoId1; + addConstraint(newConstr); + delete newConstr; + return 0; + } + else { // trim arc end + delConstraintOnPoint(GeoId, end, false); + Part::GeomArcOfCircle *aoc1 = dynamic_cast(geomlist[GeoId]); + aoc1->setRange(startAngle, startAngle + theta1); + Sketcher::Constraint *newConstr = new Sketcher::Constraint(); + newConstr->Type = Sketcher::PointOnObject; + newConstr->First = GeoId; + newConstr->FirstPos = end; + newConstr->Second = GeoId1; + addConstraint(newConstr); + delete newConstr; + return 0; + } } } } diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index 4a683ef57..208f8e115 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -72,6 +72,8 @@ public: int delConstraint(int ConstrId); int delConstraintOnPoint(int GeoId, PointPos PosId, bool onlyCoincident=true); int delConstraintOnPoint(int VertexId, bool onlyCoincident=true); + /// transfers all contraints of a point to a new point + int transferConstraints(int fromGeoId, PointPos fromPosId, int toGeoId, PointPos toPosId); /// add an external geometry reference int addExternal(App::DocumentObject *Obj, const char* SubName); /// returns a list of projected external geoms diff --git a/src/Mod/Sketcher/App/freegcs/GCS.cpp b/src/Mod/Sketcher/App/freegcs/GCS.cpp index 29ccf68be..a2af83bfa 100644 --- a/src/Mod/Sketcher/App/freegcs/GCS.cpp +++ b/src/Mod/Sketcher/App/freegcs/GCS.cpp @@ -402,7 +402,7 @@ int System::addConstraintP2PSymmetric(Point &p1, Point &p2, Line &l, int tagId) void System::initSolution(VEC_pD ¶ms) { // - Stores the current parameters in the vector "reference" - // - Identifies the equality constraints with tagged with ids >= 0 + // - Identifies the equality constraints tagged with ids >= 0 // and prepares a corresponding system reduction // - Organizes the rest of constraints into two subsystems for // tag ids >=0 and < 0 respectively and applies the @@ -477,13 +477,13 @@ void System::resetToReference() *(it->first) = it->second; } -int System::solve(VEC_pD ¶ms, int isFine) +int System::solve(VEC_pD ¶ms, bool isFine) { initSolution(params); return solve(isFine); } -int System::solve(int isFine) +int System::solve(bool isFine) { if (subsystems.size() == 0) return 0; @@ -498,7 +498,7 @@ int System::solve(int isFine) } } -int System::solve(SubSystem *subsys, int isFine) +int System::solve(SubSystem *subsys, bool isFine) { int xsize = subsys->pSize(); if (xsize == 0) @@ -527,7 +527,7 @@ int System::solve(SubSystem *subsys, int isFine) subsys->getParams(x); h = x - h; // = x - xold - double convergence = (isFine > 0) ? XconvergenceFine : XconvergenceRough; + double convergence = isFine ? XconvergenceFine : XconvergenceRough; int maxIterNumber = MaxIterations * xsize; for (int iter=1; iter < maxIterNumber; iter++) { @@ -572,7 +572,7 @@ int System::solve(SubSystem *subsys, int isFine) // The following solver variant solves a system compound of two subsystems // treating the first of them as of higher priority than the second -int System::solve(SubSystem *subsysA, SubSystem *subsysB, int isFine) +int System::solve(SubSystem *subsysA, SubSystem *subsysB, bool isFine) { int xsizeA = subsysA->pSize(); int xsizeB = subsysB->pSize(); @@ -618,7 +618,7 @@ int System::solve(SubSystem *subsysA, SubSystem *subsysB, int isFine) subsysA->calcJacobi(plist,JA); subsysA->calcResidual(resA); - double convergence = (isFine > 0) ? XconvergenceFine : XconvergenceRough; + double convergence = isFine ? XconvergenceFine : XconvergenceRough; int maxIterNumber = MaxIterations * xsize; double mu = 0; @@ -829,6 +829,8 @@ double lineSearch(SubSystem *subsys, Eigen::VectorXd &xdir) { double f1,f2,f3,alpha1,alpha2,alpha3,alphaStar; + double alphaMax = subsys->maxStep(xdir); + Eigen::VectorXd x0, x; //Save initial values @@ -864,6 +866,8 @@ double lineSearch(SubSystem *subsys, Eigen::VectorXd &xdir) f2 = subsys->error(); } else if (f2 > f3) { + 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; @@ -881,6 +885,9 @@ double lineSearch(SubSystem *subsys, Eigen::VectorXd &xdir) if (alphaStar >= alpha3 || alphaStar <= alpha1) alphaStar = alpha2; + if (alphaStar > alphaMax) + alphaStar = alphaMax; + if (alphaStar != alphaStar) alphaStar = 0.; @@ -933,6 +940,9 @@ void free(std::vector &constrvec) case L2LAngle: delete static_cast(*constr); break; + case MidpointOnLine: + delete static_cast(*constr); + break; case None: default: delete *constr; diff --git a/src/Mod/Sketcher/App/freegcs/GCS.h b/src/Mod/Sketcher/App/freegcs/GCS.h index 4f91739de..e3a72b53d 100644 --- a/src/Mod/Sketcher/App/freegcs/GCS.h +++ b/src/Mod/Sketcher/App/freegcs/GCS.h @@ -115,10 +115,10 @@ namespace GCS void initSolution(VEC_pD ¶ms); - int solve(int isFine=1); - int solve(VEC_pD ¶ms, int isFine=1); - int solve(SubSystem *subsys, int isFine=1); - int solve(SubSystem *subsysA, SubSystem *subsysB, int isFine=1); + int solve(bool isFine=true); + int solve(VEC_pD ¶ms, bool isFine=true); + int solve(SubSystem *subsys, bool isFine=true); + int solve(SubSystem *subsysA, SubSystem *subsysB, bool isFine=true); void getSubSystems(std::vector &subsysvec); void applySolution(); diff --git a/src/Mod/Sketcher/App/freegcs/qp_eq.cpp b/src/Mod/Sketcher/App/freegcs/qp_eq.cpp index 991217fe4..d2c63ee75 100644 --- a/src/Mod/Sketcher/App/freegcs/qp_eq.cpp +++ b/src/Mod/Sketcher/App/freegcs/qp_eq.cpp @@ -27,7 +27,7 @@ using namespace Eigen; // minimizes ( 0.5 * x^T * H * x + g^T * x ) under the condition ( A*x + c = 0 ) // it returns the solution in x, the row-space of A in Y, and the null space of A in Z int qp_eq(MatrixXd &H, VectorXd &g, MatrixXd &A, VectorXd &c, - VectorXd &x, MatrixXd &Y, MatrixXd &Z) + VectorXd &x, MatrixXd &Y, MatrixXd &Z) { FullPivHouseholderQR qrAT(A.transpose()); MatrixXd Q = qrAT.matrixQ (); diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index 9acb9c7d0..7567c0b2a 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -218,13 +218,13 @@ void CmdSketcherConstrainHorizontal::activated(int iMsg) ids.push_back(index); } } - // undo command open + // undo command open openCommand("add horizontal constraint"); - for(std::vector::iterator it = ids.begin(); it!=ids.end();it++) { + for (std::vector::iterator it=ids.begin(); it != ids.end(); it++) { // issue the actual commands to create the constraint doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Horizontal',%d)) " - ,selection[0].getFeatName(),*it); + ,selection[0].getFeatName(),*it); } // finish the transaction and update commitCommand(); @@ -309,10 +309,10 @@ void CmdSketcherConstrainVertical::activated(int iMsg) // undo command open openCommand("add vertical constraint"); - for(std::vector::iterator it = ids.begin(); it!=ids.end();it++) { - // issue the actual command to create the constraint + for (std::vector::iterator it=ids.begin(); it != ids.end(); it++) { + // issue the actual command to create the constraint doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Vertical',%d))" - ,selection[0].getFeatName(),*it); + ,selection[0].getFeatName(),*it); } // finish the transaction and update commitCommand(); @@ -627,8 +627,6 @@ void CmdSketcherConstrainDistance::activated(int iMsg) } } - - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("Select exactly one line or one point and one line or two points from the sketch.")); return; @@ -798,7 +796,7 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('DistanceX',%d,%d,%d,%d,%f)) ", selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,ActLength); commitCommand(); - + // Get the latest created constraint const std::vector &ConStr = dynamic_cast(selection[0].getObject())->Constraints.getValues(); Sketcher::Constraint *constr = ConStr[ConStr.size() -1]; @@ -851,7 +849,6 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg) updateDatumDistance(getActiveGuiDocument(), constr); - //updateActive(); getSelection().clearSelection(); return; @@ -1079,7 +1076,7 @@ void CmdSketcherConstrainParallel::activated(int iMsg) Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Parallel',%d,%d)) ", selection[0].getFeatName(),ids[i],ids[i+1]); } - + // finish the transaction and update commitCommand(); updateActive(); @@ -1492,7 +1489,7 @@ void CmdSketcherConstrainAngle::activated(int iMsg) constr->LabelDistance = 2. * sf; vp->draw(); // Redraw } - + //updateActive(); getSelection().clearSelection(); return; @@ -1688,11 +1685,11 @@ void CmdSketcherConstrainSymmetric::activated(int iMsg) Gui::Command::doCommand( Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Symmetric',%d,%d,%d,%d,%d)) ", selection[0].getFeatName(),GeoId1,PosId1,GeoId2,PosId2,GeoId3); - + // finish the transaction and update commitCommand(); updateActive(); - + // clear the selection (convenience) getSelection().clearSelection(); return; diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index d0fa7d7e5..494b856ff 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -143,7 +143,7 @@ public: Base::Vector3d seekConstraintPosition(const Base::Vector3d &suggestedPos, const Base::Vector3d &dir, float step, const SoNode *constraint); - + float getScaleFactor(); int getPreselectPoint(void) const; int getPreselectCurve(void) const;