From fb0d83056082def0c81ff241fb4910605a0571e5 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Tue, 7 Oct 2014 15:26:34 +0200 Subject: [PATCH] Sketcher Ellipse and ArcOfEllipse: Major bug fixes - Change mode so that focus1 is not a point, but two doubles so that visual model and solver model match in number of points. - Solver fix to deal with reduced constraint partials accuracy (threshold for matrix rank calculation tweak) - Changes suggested by logari81 --- src/Mod/Sketcher/App/Sketch.cpp | 57 +++++--------------- src/Mod/Sketcher/App/Sketch.h | 2 - src/Mod/Sketcher/App/freegcs/Constraints.cpp | 38 ++++++------- src/Mod/Sketcher/App/freegcs/Constraints.h | 9 ++-- src/Mod/Sketcher/App/freegcs/GCS.cpp | 24 +++++++-- src/Mod/Sketcher/App/freegcs/Geo.h | 6 ++- src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 4 +- 7 files changed, 62 insertions(+), 78 deletions(-) diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp index f8c8013b8..3bc8f6710 100644 --- a/src/Mod/Sketcher/App/Sketch.cpp +++ b/src/Mod/Sketcher/App/Sketch.cpp @@ -382,7 +382,6 @@ int Sketch::addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool f aoe->getRange(startAngle, endAngle); GCS::Point p1, p2, p3; - GCS::Point f1; params.push_back(new double(startPnt.x)); params.push_back(new double(startPnt.y)); @@ -401,8 +400,8 @@ int Sketch::addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool f params.push_back(new double(focus1.x)); params.push_back(new double(focus1.y)); - f1.x = params[params.size()-2]; - f1.y = params[params.size()-1]; + double *f1X = params[params.size()-2]; + double *f1Y = params[params.size()-1]; def.startPointId = Points.size(); Points.push_back(p1); @@ -411,7 +410,7 @@ int Sketch::addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool f def.midPointId = Points.size(); Points.push_back(p3); - Points.push_back(f1); + //Points.push_back(f1); // add the radius parameters @@ -429,7 +428,8 @@ int Sketch::addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool f a.start = p1; a.end = p2; a.center = p3; - a.focus1 = f1; + a.focus1X = f1X; + a.focus1Y = f1Y; a.radmin = rmin; a.startAngle = a1; a.endAngle = a2; @@ -521,26 +521,20 @@ int Sketch::addEllipse(const Part::GeomEllipse &elip, bool fixed) def.midPointId = Points.size(); // this takes midPointId+1 Points.push_back(c); - - GCS::Point f1; params.push_back(new double(focus1.x)); params.push_back(new double(focus1.y)); - f1.x = params[params.size()-2]; - f1.y = params[params.size()-1]; + double *f1X = params[params.size()-2]; + double *f1Y = params[params.size()-1]; - //def.midPointId = Points.size(); - Points.push_back(f1); - - - // add the radius parameters params.push_back(new double(radmin)); double *rmin = params[params.size()-1]; // set the ellipse for later constraints GCS::Ellipse e; - e.focus1 = f1; + e.focus1X = f1X; + e.focus1Y = f1Y; e.center = c; e.radmin = rmin; @@ -2068,8 +2062,8 @@ bool Sketch::updateGeometry() GeomArcOfEllipse *aoe = dynamic_cast(it->geo); Base::Vector3d center = Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0); - Base::Vector3d f1 = Vector3d(*Points[it->midPointId+1].x, *Points[it->midPointId+1].y, 0.0); - double radmin = *ArcsOfEllipse[it->index].radmin; + Base::Vector3d f1 = Vector3d(*myArc.focus1X, *myArc.focus1Y, 0.0); + double radmin = *myArc.radmin; Base::Vector3d fd=f1-center; double radmaj = sqrt(fd*fd+radmin*radmin); @@ -2098,7 +2092,7 @@ bool Sketch::updateGeometry() GeomEllipse *ellipse = dynamic_cast(it->geo); Base::Vector3d center = Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0); - Base::Vector3d f1 = Vector3d(*Points[it->midPointId+1].x, *Points[it->midPointId+1].y, 0.0); + Base::Vector3d f1 = Vector3d(*Ellipses[it->index].focus1X, *Ellipses[it->index].focus1Y, 0.0); double radmin = *Ellipses[it->index].radmin; Base::Vector3d fd=f1-center; @@ -2481,33 +2475,6 @@ int Sketch::getPointId(int geoId, PointPos pos) const return -1; } -int Sketch::getVisiblePointId(int geoId, PointPos pos) const -{ - // do a range check first - if (geoId < 0 || geoId >= (int)Geoms.size()) - return -1; - - int invisiblepoints = 0; - int i; - - // calculate the number of points in the solver that are not visible in the UI - for(i=0;i #define _GCS_DEBUG 1 +#undef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX #ifdef _GCS_DEBUG #include @@ -844,7 +845,8 @@ int System::addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse &e, Point int System::addConstraintInternalAlignmentEllipseFocus1(Ellipse &e, Point &p1, int tagId) { - return addConstraintP2PCoincident(e.focus1,p1); + addConstraintEqual(e.focus1X, p1.x, tagId); + return addConstraintEqual(e.focus1Y, p1.y, tagId); } int System::addConstraintInternalAlignmentEllipseFocus2(Ellipse &e, Point &p1, int tagId) @@ -878,7 +880,8 @@ int System::addConstraintInternalAlignmentEllipseMinorDiameter(ArcOfEllipse &a, int System::addConstraintInternalAlignmentEllipseFocus1(ArcOfEllipse &a, Point &p1, int tagId) { - return addConstraintP2PCoincident(a.focus1,p1); + addConstraintEqual(a.focus1X, p1.x, tagId); + return addConstraintEqual(a.focus1Y, p1.y, tagId); } int System::addConstraintInternalAlignmentEllipseFocus2(ArcOfEllipse &a, Point &p1, int tagId) @@ -1694,7 +1697,7 @@ int System::diagnose() Eigen::MatrixXd Q = qrJT.matrixQ (); int paramsNum = qrJT.rows(); int constrNum = qrJT.cols(); - //qrJT.setThreshold(0); + qrJT.setThreshold(1e-10); int rank = qrJT.rank(); Eigen::MatrixXd R; @@ -1703,6 +1706,21 @@ int System::diagnose() else R = qrJT.matrixQR().topRows(constrNum) .triangularView(); + + + #ifdef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX + // Debug code starts + std::stringstream stream; + + stream << "["; + stream << R ; + stream << "]"; + + const std::string tmp = stream.str(); + + Base::Console().Warning(tmp.c_str()); + // Debug code ends + #endif if (constrNum > rank) { // conflicting or redundant constraints for (int i=1; i < rank; i++) { diff --git a/src/Mod/Sketcher/App/freegcs/Geo.h b/src/Mod/Sketcher/App/freegcs/Geo.h index b44daa73c..a17f4e73a 100644 --- a/src/Mod/Sketcher/App/freegcs/Geo.h +++ b/src/Mod/Sketcher/App/freegcs/Geo.h @@ -71,7 +71,8 @@ namespace GCS public: Ellipse(){ radmin = 0;} Point center; - Point focus1; //+x + double *focus1X; //+u + double *focus1Y; double *radmin; }; @@ -85,7 +86,8 @@ namespace GCS Point start; Point end; Point center; - Point focus1; //+x + double *focus1X; //+u + double *focus1Y; }; } //namespace GCS diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 589897de3..197f5e640 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -2145,9 +2145,9 @@ void ViewProviderSketch::updateColor(void) m->diffuseColor = SelectColor; } else if (type == Sketcher::Coincident) { int index; - index = edit->ActSketch.getVisiblePointId(constraint->First, constraint->FirstPos) + 1; + index = edit->ActSketch.getPointId(constraint->First, constraint->FirstPos) + 1; if (index >= 0 && index < PtNum) pcolor[index] = SelectColor; - index = edit->ActSketch.getVisiblePointId(constraint->Second, constraint->SecondPos) + 1; + index = edit->ActSketch.getPointId(constraint->Second, constraint->SecondPos) + 1; if (index >= 0 && index < PtNum) pcolor[index] = SelectColor; } } else if (edit->PreselectConstraintSet.count(i)) {