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
This commit is contained in:
Abdullah Tahiri 2014-10-07 15:26:34 +02:00 committed by wmayer
parent e423c308af
commit fb0d830560
7 changed files with 62 additions and 78 deletions

View File

@ -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<GeomArcOfEllipse*>(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<GeomEllipse*>(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<geoId;i++)
if(Geoms[i].type == Ellipse || Geoms[i].type == ArcOfEllipse)
invisiblepoints++;
switch (pos) {
case start:
return Geoms[geoId].startPointId-invisiblepoints;
case end:
return Geoms[geoId].endPointId-invisiblepoints;
case mid:
return Geoms[geoId].midPointId-invisiblepoints;
case none:
break;
}
return -1;
}
Base::Vector3d Sketch::getPoint(int geoId, PointPos pos)
{
geoId = checkGeoId(geoId);

View File

@ -82,8 +82,6 @@ public:
/// retrieves the index of a point
int getPointId(int geoId, PointPos pos) const;
int getVisiblePointId(int geoId, PointPos pos) const;
/// retrieves a point
Base::Vector3d getPoint(int geoId, PointPos pos);

View File

@ -919,8 +919,8 @@ ConstraintPointOnEllipse::ConstraintPointOnEllipse(Point &p, Ellipse &e)
pvec.push_back(p.y);
pvec.push_back(e.center.x);
pvec.push_back(e.center.y);
pvec.push_back(e.focus1.x);
pvec.push_back(e.focus1.y);
pvec.push_back(e.focus1X);
pvec.push_back(e.focus1Y);
pvec.push_back(e.radmin);
origpvec = pvec;
rescale();
@ -932,8 +932,8 @@ ConstraintPointOnEllipse::ConstraintPointOnEllipse(Point &p, ArcOfEllipse &a)
pvec.push_back(p.y);
pvec.push_back(a.center.x);
pvec.push_back(a.center.y);
pvec.push_back(a.focus1.x);
pvec.push_back(a.focus1.y);
pvec.push_back(a.focus1X);
pvec.push_back(a.focus1Y);
pvec.push_back(a.radmin);
origpvec = pvec;
rescale();
@ -941,7 +941,7 @@ ConstraintPointOnEllipse::ConstraintPointOnEllipse(Point &p, ArcOfEllipse &a)
ConstraintType ConstraintPointOnEllipse::getTypeId()
{
return P2OnEllipse;
return PointOnEllipse;
}
void ConstraintPointOnEllipse::rescale(double coef)
@ -1023,8 +1023,8 @@ ConstraintEllipseTangentLine::ConstraintEllipseTangentLine(Line &l, Ellipse &e)
pvec.push_back(l.p2.y);
pvec.push_back(e.center.x);
pvec.push_back(e.center.y);
pvec.push_back(e.focus1.x);
pvec.push_back(e.focus1.y);
pvec.push_back(e.focus1X);
pvec.push_back(e.focus1Y);
pvec.push_back(e.radmin);
origpvec = pvec;
rescale();
@ -1038,8 +1038,8 @@ ConstraintEllipseTangentLine::ConstraintEllipseTangentLine(Line &l, ArcOfEllipse
pvec.push_back(l.p2.y);
pvec.push_back(a.center.x);
pvec.push_back(a.center.y);
pvec.push_back(a.focus1.x);
pvec.push_back(a.focus1.y);
pvec.push_back(a.focus1X);
pvec.push_back(a.focus1Y);
pvec.push_back(a.radmin);
origpvec = pvec;
rescale();
@ -1347,8 +1347,8 @@ ConstraintInternalAlignmentPoint2Ellipse::ConstraintInternalAlignmentPoint2Ellip
pvec.push_back(p1.y);
pvec.push_back(e.center.x);
pvec.push_back(e.center.y);
pvec.push_back(e.focus1.x);
pvec.push_back(e.focus1.y);
pvec.push_back(e.focus1X);
pvec.push_back(e.focus1Y);
pvec.push_back(e.radmin);
origpvec = pvec;
rescale();
@ -1361,8 +1361,8 @@ ConstraintInternalAlignmentPoint2Ellipse::ConstraintInternalAlignmentPoint2Ellip
pvec.push_back(p1.y);
pvec.push_back(a.center.x);
pvec.push_back(a.center.y);
pvec.push_back(a.focus1.x);
pvec.push_back(a.focus1.y);
pvec.push_back(a.focus1X);
pvec.push_back(a.focus1Y);
pvec.push_back(a.radmin);
origpvec = pvec;
rescale();
@ -1796,13 +1796,13 @@ double ConstraintInternalAlignmentPoint2Ellipse::grad(double *param)
{
pvec.push_back(e1.center.x);
pvec.push_back(e1.center.y);
pvec.push_back(e1.focus1.x);
pvec.push_back(e1.focus1.y);
pvec.push_back(e1.focus1X);
pvec.push_back(e1.focus1Y);
pvec.push_back(e1.radmin);
pvec.push_back(e2.center.x);
pvec.push_back(e2.center.y);
pvec.push_back(e2.focus1.x);
pvec.push_back(e2.focus1.y);
pvec.push_back(e2.focus1X);
pvec.push_back(e2.focus1Y);
pvec.push_back(e2.radmin);
origpvec = pvec;
rescale();
@ -1909,8 +1909,8 @@ ConstraintEllipticalArcRangeToEndPoints::ConstraintEllipticalArcRangeToEndPoints
pvec.push_back(angle_t);
pvec.push_back(a.center.x);
pvec.push_back(a.center.y);
pvec.push_back(a.focus1.x);
pvec.push_back(a.focus1.y);
pvec.push_back(a.focus1X);
pvec.push_back(a.focus1Y);
pvec.push_back(a.radmin);
origpvec = pvec;
rescale();

View File

@ -47,12 +47,11 @@ namespace GCS
L2LAngle = 10,
MidpointOnLine = 11,
TangentCircumf = 12,
P2OnEllipse = 13,
PointOnEllipse = 13,
TangentEllipseLine = 14,
Point2EllipseDistance = 15,
InternalAlignmentPoint2Ellipse = 16,
EqualMajorAxesEllipse = 17,
EllipticalArcRangeToEndPoints = 18
InternalAlignmentPoint2Ellipse = 15,
EqualMajorAxesEllipse = 16,
EllipticalArcRangeToEndPoints = 17
};
enum InternalAlignmentType {

View File

@ -28,6 +28,7 @@
#include <Eigen/QR>
#define _GCS_DEBUG 1
#undef _GCS_DEBUG_SOLVER_JACOBIAN_QR_DECOMPOSITION_TRIANGULAR_MATRIX
#ifdef _GCS_DEBUG
#include <Base/Writer.h>
@ -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<Eigen::Upper>();
#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++) {

View File

@ -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

View File

@ -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)) {