Sketcher New Feature: Ellipse support

- Ellipse introduction button via (center,majaxis extreme, a point in edge), ellipse is always CCW so that Z axis goes in the positive direction of the sketch
- Backwards compatibility with files of previous versions of ellipse not defining a phi angle
- Art by Jim (all the icons you see and the XPMs shown on creation of an ellipse)
- Element Widget support for ellipses
- Box selection for ellipses
- Point on Ellipse constraint based on the gardener's method based on Ulrich's function proposal (radcan simplified, i.e. with simplify_radical sage function)
- Tangent: Ellipse to Line based on DeepSOIC's geometric formulation (radcan simplified)

Sketcher New Feature: Internal Alignment Constraint
- The element to which internal alignment is applied has to be selected last.
- All other elements are added in the order of priority, taking into account existing elements
- Art by Jim (beautiful icons).

Sketcher New Feature: Tool to show/hide/restore the internal geometry of an element
- New functionality for show/hide internal geometry:
  toggles between hiding all unused internal geometry elements and showing all internal geometry.
  The restore function is implicit to the showing all internal geometry

Sketcher New Feature: Arc of Ellipse support
- Part::Geometry + Python implementation
- ArcOfEllipse creation method
- Art by Jim (all the icons you see and the XPMs shown on creation of arc of ellipse elements)
- Sketcher Element widget for ArcOfEllipse.

Bug fix: Select elements associated to constraints works now for foci internal alignment constraints
This commit is contained in:
Abdullah Tahiri
2014-11-11 19:29:45 +01:00
committed by wmayer
parent 193ad19ddb
commit 4946eddc6b
33 changed files with 5024 additions and 147 deletions

View File

@@ -43,6 +43,7 @@ const int Constraint::GeoUndef = -2000;
Constraint::Constraint()
: Type(None),
AlignmentType(Undef),
Name(""),
Value(0.0),
First(GeoUndef),
@@ -58,6 +59,7 @@ Constraint::Constraint()
Constraint::Constraint(const Constraint& from)
: Type(from.Type),
AlignmentType(from.AlignmentType),
Name(from.Name),
Value(from.Value),
First(from.First),
@@ -92,18 +94,22 @@ unsigned int Constraint::getMemSize (void) const
void Constraint::Save (Writer &writer) const
{
writer.Stream() << writer.ind() << "<Constrain "
<< "Name=\"" << Name << "\" "
<< "Type=\"" << (int)Type << "\" "
<< "Value=\"" << Value << "\" "
<< "First=\"" << First << "\" "
<< "FirstPos=\"" << (int) FirstPos << "\" "
<< "Second=\"" << Second << "\" "
<< "SecondPos=\"" << (int) SecondPos << "\" "
<< "Third=\"" << Third << "\" "
<< "ThirdPos=\"" << (int) ThirdPos << "\" "
<< "LabelDistance=\"" << LabelDistance << "\" "
<< "LabelPosition=\"" << LabelPosition << "\" />"
writer.Stream() << writer.ind() << "<Constrain "
<< "Name=\"" << Name << "\" "
<< "Type=\"" << (int)Type << "\" ";
if(this->Type==InternalAlignment)
writer.Stream()
<< "InternalAlignmentType=\"" << (int)AlignmentType << "\" ";
writer.Stream()
<< "Value=\"" << Value << "\" "
<< "First=\"" << First << "\" "
<< "FirstPos=\"" << (int) FirstPos << "\" "
<< "Second=\"" << Second << "\" "
<< "SecondPos=\"" << (int) SecondPos << "\" "
<< "Third=\"" << Third << "\" "
<< "ThirdPos=\"" << (int) ThirdPos << "\" "
<< "LabelDistance=\"" << LabelDistance << "\" "
<< "LabelPosition=\"" << LabelPosition << "\" />"
<< std::endl;
}
@@ -118,6 +124,11 @@ void Constraint::Restore(XMLReader &reader)
Second = reader.getAttributeAsInteger("Second");
SecondPos = (PointPos) reader.getAttributeAsInteger("SecondPos");
if(this->Type==InternalAlignment)
AlignmentType = (InternalAlignmentType) reader.getAttributeAsInteger("InternalAlignmentType");
else
AlignmentType = Undef;
// read the third geo group if present
if (reader.hasAttribute("Third")) {
Third = reader.getAttributeAsInteger("Third");

View File

@@ -31,21 +31,30 @@ namespace Sketcher
{
enum ConstraintType {
None,
Coincident,
Horizontal,
Vertical,
Parallel,
Tangent,
Distance,
DistanceX,
DistanceY,
Angle,
Perpendicular,
Radius,
Equal,
PointOnObject,
Symmetric
None = 0,
Coincident = 1,
Horizontal = 2,
Vertical = 3,
Parallel = 4,
Tangent = 5,
Distance = 6,
DistanceX = 7,
DistanceY = 8,
Angle = 9,
Perpendicular = 10,
Radius = 11,
Equal = 12,
PointOnObject = 13,
Symmetric = 14,
InternalAlignment = 15
};
enum InternalAlignmentType {
Undef = 0,
EllipseMajorDiameter = 1,
EllipseMinorDiameter = 2,
EllipseFocus1 = 3,
EllipseFocus2 = 4
};
/// define if you want to use the end or start point
@@ -74,6 +83,7 @@ public:
public:
ConstraintType Type;
InternalAlignmentType AlignmentType;
std::string Name;
double Value;
int First;

View File

@@ -93,6 +93,20 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
this->getConstraintPtr()->Type = Equal;
valid = true;
}
else if (strstr(ConstraintType,"InternalAlignment") != NULL) {
this->getConstraintPtr()->Type = InternalAlignment;
valid = true;
if(strstr(ConstraintType,"EllipseMajorDiameter") != NULL)
this->getConstraintPtr()->AlignmentType=EllipseMajorDiameter;
else if(strstr(ConstraintType,"EllipseMinorDiameter") != NULL)
this->getConstraintPtr()->AlignmentType=EllipseMinorDiameter;
else {
this->getConstraintPtr()->AlignmentType=Undef;
valid = false;
}
}
if (valid) {
this->getConstraintPtr()->First = FirstIndex;
this->getConstraintPtr()->Second = SecondIndex;
@@ -155,6 +169,20 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
this->getConstraintPtr()->Type = PointOnObject;
valid = true;
}
else if (strstr(ConstraintType,"InternalAlignment") != NULL) {
this->getConstraintPtr()->Type = InternalAlignment;
valid = true;
if(strstr(ConstraintType,"EllipseFocus1") != NULL)
this->getConstraintPtr()->AlignmentType=EllipseFocus1;
else if(strstr(ConstraintType,"EllipseFocus2") != NULL)
this->getConstraintPtr()->AlignmentType=EllipseFocus2;
else {
this->getConstraintPtr()->AlignmentType=Undef;
valid = false;
}
}
if (valid) {
this->getConstraintPtr()->First = FirstIndex;
this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) FirstPos;
@@ -340,17 +368,27 @@ std::string ConstraintPy::representation(void) const
std::stringstream result;
result << "<Constraint " ;
switch(this->getConstraintPtr()->Type) {
case None : result << "'None'>";break;
case DistanceX : result << "'DistanceX'>";break;
case DistanceY : result << "'DistanceY'>";break;
case Coincident : result << "'Coincident'>";break;
case Horizontal : result << "'Horizontal' (" << getConstraintPtr()->First << ")>";break;
case Vertical : result << "'Vertical' (" << getConstraintPtr()->First << ")>";break;
case Parallel : result << "'Parallel'>";break;
case Tangent : result << "'Tangent'>";break;
case Distance : result << "'Distance'>";break;
case Angle : result << "'Angle'>";break;
default : result << "'?'>";break;
case None : result << "'None'>";break;
case DistanceX : result << "'DistanceX'>";break;
case DistanceY : result << "'DistanceY'>";break;
case Coincident : result << "'Coincident'>";break;
case Horizontal : result << "'Horizontal' (" << getConstraintPtr()->First << ")>";break;
case Vertical : result << "'Vertical' (" << getConstraintPtr()->First << ")>";break;
case Parallel : result << "'Parallel'>";break;
case Tangent : result << "'Tangent'>";break;
case Distance : result << "'Distance'>";break;
case Angle : result << "'Angle'>";break;
case InternalAlignment :
switch(this->getConstraintPtr()->AlignmentType) {
case Undef : result << "'InternalAlignment:Undef'>";break;
case EllipseMajorDiameter : result << "'InternalAlignment:EllipseMajorDiameter'>";break;
case EllipseMinorDiameter : result << "'InternalAlignment:EllipseMinorDiameter'>";break;
case EllipseFocus1 : result << "'InternalAlignment:EllipseFocus1'>";break;
case EllipseFocus2 : result << "'InternalAlignment:EllipseFocus2'>";break;
default : result << "'InternalAlignment:?'>";break;
}
break;
default : result << "'?'>";break;
}
return result.str();
}

View File

@@ -40,6 +40,7 @@
#include <Mod/Part/App/Geometry.h>
#include <Mod/Part/App/GeometryCurvePy.h>
#include <Mod/Part/App/ArcOfCirclePy.h>
#include <Mod/Part/App/ArcOfEllipsePy.h>
#include <Mod/Part/App/CirclePy.h>
#include <Mod/Part/App/EllipsePy.h>
#include <Mod/Part/App/LinePy.h>
@@ -78,6 +79,8 @@ void Sketch::clear(void)
Lines.clear();
Arcs.clear();
Circles.clear();
Ellipses.clear();
ArcsOfEllipse.clear();
// deleting the doubles allocated with new
for (std::vector<double*>::iterator it = Parameters.begin(); it != Parameters.end(); ++it)
@@ -142,6 +145,8 @@ const char* nameByType(Sketch::GeoType type)
return "circle";
case Sketch::Ellipse:
return "ellipse";
case Sketch::ArcOfEllipse:
return "arcofellipse";
case Sketch::None:
default:
return "unknown";
@@ -164,10 +169,18 @@ int Sketch::addGeometry(const Part::Geometry *geo, bool fixed)
const GeomCircle *circle = dynamic_cast<const GeomCircle*>(geo);
// create the definition struct for that geom
return addCircle(*circle, fixed);
} else if (geo->getTypeId() == GeomEllipse::getClassTypeId()) { // add a ellipse
const GeomEllipse *ellipse = dynamic_cast<const GeomEllipse*>(geo);
// create the definition struct for that geom
return addEllipse(*ellipse, fixed);
} else if (geo->getTypeId() == GeomArcOfCircle::getClassTypeId()) { // add an arc
const GeomArcOfCircle *aoc = dynamic_cast<const GeomArcOfCircle*>(geo);
// create the definition struct for that geom
return addArc(*aoc, fixed);
} else if (geo->getTypeId() == GeomArcOfEllipse::getClassTypeId()) { // add an arc
const GeomArcOfEllipse *aoe = dynamic_cast<const GeomArcOfEllipse*>(geo);
// create the definition struct for that geom
return addArcOfEllipse(*aoe, fixed);
} else {
Base::Exception("Sketch::addGeometry(): Unknown or unsupported type added to a sketch");
return 0;
@@ -341,6 +354,99 @@ int Sketch::addArc(const Part::GeomArcOfCircle &circleSegment, bool fixed)
return Geoms.size()-1;
}
int Sketch::addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool fixed)
{
std::vector<double *> &params = fixed ? FixParameters : Parameters;
// create our own copy
GeomArcOfEllipse *aoe = static_cast<GeomArcOfEllipse*>(ellipseSegment.clone());
// create the definition struct for that geom
GeoDef def;
def.geo = aoe;
def.type = ArcOfEllipse;
Base::Vector3d center = aoe->getCenter();
Base::Vector3d startPnt = aoe->getStartPoint();
Base::Vector3d endPnt = aoe->getEndPoint();
double radmaj = aoe->getMajorRadius();
double radmin = aoe->getMinorRadius();
double phi = aoe->getAngleXU();
double dist_C_F = sqrt(radmaj*radmaj-radmin*radmin);
// solver parameters
Base::Vector3d focus1 = center+dist_C_F*Vector3d(cos(phi), sin(phi),0); //+x
double startAngle, endAngle;
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));
p1.x = params[params.size()-2];
p1.y = params[params.size()-1];
params.push_back(new double(endPnt.x));
params.push_back(new double(endPnt.y));
p2.x = params[params.size()-2];
p2.y = params[params.size()-1];
params.push_back(new double(center.x));
params.push_back(new double(center.y));
p3.x = params[params.size()-2];
p3.y = params[params.size()-1];
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];
def.startPointId = Points.size();
Points.push_back(p1);
def.endPointId = Points.size();
Points.push_back(p2);
def.midPointId = Points.size();
Points.push_back(p3);
Points.push_back(f1);
// add the radius parameters
params.push_back(new double(radmin));
double *rmin = params[params.size()-1];
params.push_back(new double(startAngle));
double *a1 = params[params.size()-1];
params.push_back(new double(endAngle));
double *a2 = params[params.size()-1];
// set the arc for later constraints
GCS::ArcOfEllipse a;
a.start = p1;
a.end = p2;
a.center = p3;
a.focus1 = f1;
a.radmin = rmin;
a.startAngle = a1;
a.endAngle = a2;
def.index = ArcsOfEllipse.size();
ArcsOfEllipse.push_back(a);
// store complete set
Geoms.push_back(def);
// arcs require an ArcRules constraint for the end points
if (!fixed)
GCSsys.addConstraintArcOfEllipseRules(a); // TODO: ArcOfEllipse implementation.
// return the position of the newly added geometry
return Geoms.size()-1;
}
int Sketch::addCircle(const Part::GeomCircle &cir, bool fixed)
{
std::vector<double *> &params = fixed ? FixParameters : Parameters;
@@ -384,8 +490,66 @@ int Sketch::addCircle(const Part::GeomCircle &cir, bool fixed)
return Geoms.size()-1;
}
int Sketch::addEllipse(const Part::GeomEllipse &ellipse, bool fixed)
int Sketch::addEllipse(const Part::GeomEllipse &elip, bool fixed)
{
// TODO: Ellipse
std::vector<double *> &params = fixed ? FixParameters : Parameters;
// create our own copy
GeomEllipse *elips = static_cast<GeomEllipse*>(elip.clone());
// create the definition struct for that geom
GeoDef def;
def.geo = elips;
def.type = Ellipse;
Base::Vector3d center = elips->getCenter();
double radmaj = elips->getMajorRadius();
double radmin = elips->getMinorRadius();
double phi = elips->getAngleXU();
double dist_C_F = sqrt(radmaj*radmaj-radmin*radmin);
// solver parameters
Base::Vector3d focus1 = center+dist_C_F*Vector3d(cos(phi), sin(phi),0); //+x
//double *radmin;
GCS::Point c;
params.push_back(new double(center.x));
params.push_back(new double(center.y));
c.x = params[params.size()-2];
c.y = params[params.size()-1];
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];
//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.center = c;
e.radmin = rmin;
def.index = Ellipses.size();
Ellipses.push_back(e);
// store complete set
Geoms.push_back(def);
// return the position of the newly added geometry
return Geoms.size()-1;
}
@@ -422,7 +586,11 @@ Py::Tuple Sketch::getPyGeometry(void) const
} else if (it->type == Ellipse) {
GeomEllipse *ellipse = dynamic_cast<GeomEllipse*>(it->geo->clone());
tuple[i] = Py::asObject(new EllipsePy(ellipse));
} else {
} else if (it->type == ArcOfEllipse) {
GeomArcOfEllipse *ellipse = dynamic_cast<GeomArcOfEllipse*>(it->geo->clone());
tuple[i] = Py::asObject(new ArcOfEllipsePy(ellipse));
}
else {
// not implemented type in the sketch!
}
}
@@ -549,6 +717,22 @@ int Sketch::addConstraint(const Constraint *constraint)
rtn = addSymmetricConstraint(constraint->First,constraint->FirstPos,
constraint->Second,constraint->SecondPos,constraint->Third);
break;
case InternalAlignment:
switch(constraint->AlignmentType) {
case EllipseMajorDiameter:
rtn = addInternalAlignmentEllipseMajorDiameter(constraint->First,constraint->Second);
break;
case EllipseMinorDiameter:
rtn = addInternalAlignmentEllipseMinorDiameter(constraint->First,constraint->Second);
break;
case EllipseFocus1:
rtn = addInternalAlignmentEllipseFocus1(constraint->First,constraint->Second);
break;
case EllipseFocus2:
rtn = addInternalAlignmentEllipseFocus2(constraint->First,constraint->Second);
break;
}
break;
case None:
break;
}
@@ -861,6 +1045,15 @@ int Sketch::addPerpendicularConstraint(int geoId1, PointPos pos1, int geoId2)
GCSsys.addConstraintPointOnLine(p2, l1, tag);
return ConstraintsCounter;
}
else if (Geoms[geoId2].type == Ellipse) {
// TODO: Ellipse
GCS::Ellipse &c2 = Ellipses[Geoms[geoId2].index];
GCS::Point &p2 = Points[Geoms[geoId2].midPointId];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintPointOnEllipse(p1, c2, tag);
GCSsys.addConstraintPointOnLine(p2, l1, tag);
return ConstraintsCounter;
}
}
else if (Geoms[geoId1].type == Arc) {
GCS::Arc &a1 = Arcs[Geoms[geoId1].index];
@@ -871,7 +1064,8 @@ int Sketch::addPerpendicularConstraint(int geoId1, PointPos pos1, int geoId2)
GCSsys.addConstraintPointOnLine(a1.center, l2, tag);
return ConstraintsCounter;
}
else if (Geoms[geoId2].type == Arc || Geoms[geoId2].type == Circle) {
else if (Geoms[geoId2].type == Arc || Geoms[geoId2].type == Circle || Geoms[geoId2].type == Ellipse) {
// TODO: ellipse real implementation
int tag = ++ConstraintsCounter;
GCS::Point &center = Points[Geoms[geoId2].midPointId];
double *radius;
@@ -879,10 +1073,15 @@ int Sketch::addPerpendicularConstraint(int geoId1, PointPos pos1, int geoId2)
GCS::Arc &a2 = Arcs[Geoms[geoId2].index];
radius = a2.rad;
}
else {
else if (Geoms[geoId2].type == Circle) {
GCS::Circle &c2 = Circles[Geoms[geoId2].index];
radius = c2.rad;
}
else {
// TODO: Ellipse
GCS::Ellipse &c2 = Ellipses[Geoms[geoId2].index];
radius = c2.radmin;
}
if (pos1 == start)
GCSsys.addConstraintPerpendicularCircle2Arc(center, radius, a1, tag);
else if (pos1 == end)
@@ -1026,6 +1225,18 @@ int Sketch::addTangentConstraint(int geoId1, int geoId2)
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangent(l, c, tag);
return ConstraintsCounter;
} else if (Geoms[geoId2].type == Ellipse) {
// TODO: real implementation
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangent(l, e, tag);
return ConstraintsCounter;
} else if (Geoms[geoId2].type == ArcOfEllipse) {
// TODO: real implementation
GCS::ArcOfEllipse &a = ArcsOfEllipse[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangent(l, a, tag);
return ConstraintsCounter;
}
} else if (Geoms[geoId1].type == Circle) {
GCS::Circle &c = Circles[Geoms[geoId1].index];
@@ -1034,12 +1245,33 @@ int Sketch::addTangentConstraint(int geoId1, int geoId2)
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangent(c, c2, tag);
return ConstraintsCounter;
} else if (Geoms[geoId2].type == Arc) {
} else if (Geoms[geoId2].type == Ellipse) {
// TODO: real implementation
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangent(e, c, tag);
return ConstraintsCounter;
}
else if (Geoms[geoId2].type == Arc) {
GCS::Arc &a = Arcs[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangent(c, a, tag);
return ConstraintsCounter;
}
} else if (Geoms[geoId1].type == Ellipse) {
GCS::Ellipse &e = Ellipses[Geoms[geoId1].index];
// TODO: Ellipse
if (Geoms[geoId2].type == Circle) {
GCS::Circle &c = Circles[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangent(e, c, tag);
return ConstraintsCounter;
} else if (Geoms[geoId2].type == Arc) {
GCS::Arc &a = Arcs[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangent(e, a, tag);
return ConstraintsCounter;
}
} else if (Geoms[geoId1].type == Arc) {
GCS::Arc &a = Arcs[Geoms[geoId1].index];
if (Geoms[geoId2].type == Circle) {
@@ -1047,6 +1279,12 @@ int Sketch::addTangentConstraint(int geoId1, int geoId2)
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangent(c, a, tag);
return ConstraintsCounter;
} else if (Geoms[geoId2].type == Ellipse) {
// TODO: Ellipse
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangent(e, a, tag);
return ConstraintsCounter;
} else if (Geoms[geoId2].type == Arc) {
GCS::Arc &a2 = Arcs[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
@@ -1096,6 +1334,14 @@ int Sketch::addTangentConstraint(int geoId1, PointPos pos1, int geoId2)
GCSsys.addConstraintTangent(l1, c2, tag);
return ConstraintsCounter;
}
else if (Geoms[geoId2].type == Ellipse) {
// TODO: Ellipse
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintPointOnEllipse(p1, e, tag);
GCSsys.addConstraintTangent(l1, e, tag);
return ConstraintsCounter;
}
}
else if (Geoms[geoId1].type == Arc) {
GCS::Arc &a1 = Arcs[Geoms[geoId1].index];
@@ -1125,6 +1371,19 @@ int Sketch::addTangentConstraint(int geoId1, PointPos pos1, int geoId2)
GCSsys.addConstraintTangentArc2Circle(a1, c2, tag);
return ConstraintsCounter;
}
} else if (Geoms[geoId2].type == Ellipse) {
// TODO: Ellipse
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
if (pos1 == start) {
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangentEllipse2Arc(e, a1, tag);
return ConstraintsCounter;
}
else if (pos1 == end) {
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangentArc2Ellipse(a1, e, tag);
return ConstraintsCounter;
}
}
}
return -1;
@@ -1198,6 +1457,35 @@ int Sketch::addTangentConstraint(int geoId1, PointPos pos1, int geoId2, PointPos
else
return -1;
}
if (Geoms[geoId2].type == ArcOfEllipse) {
GCS::ArcOfEllipse &a2 = ArcsOfEllipse[Geoms[geoId2].index];
if (pos2 == start) {
if (pos1 == start) {
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangentLine2ArcOfEllipse(l1.p2, l1.p1, l1, a2, tag);
return ConstraintsCounter;
}
else if (pos1 == end) {
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangentLine2ArcOfEllipse(l1.p1, l1.p2, l1, a2, tag);
return ConstraintsCounter;
}
}
else if (pos2 == end) {
if (pos1 == start) {
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangentArcOfEllipse2Line(a2, l1, l1.p1, l1.p2, tag);
return ConstraintsCounter;
}
else if (pos1 == end) {
int tag = ++ConstraintsCounter;
GCSsys.addConstraintTangentArcOfEllipse2Line(a2, l1, l1.p2, l1.p1, tag);
return ConstraintsCounter;
}
}
else
return -1;
}
}
else if (Geoms[geoId1].type == Arc) {
GCS::Arc &a1 = Arcs[Geoms[geoId1].index];
@@ -1309,7 +1597,7 @@ int Sketch::addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, PointPo
return -1;
}
int Sketch::addRadiusConstraint(int geoId, double value)
int Sketch::addRadiusConstraint(int geoId, double value, int radiusnumber)
{
geoId = checkGeoId(geoId);
@@ -1448,6 +1736,18 @@ int Sketch::addEqualConstraint(int geoId1, int geoId2)
else
std::swap(geoId1, geoId2);
}
// TODO: Ellipse
if (Geoms[geoId2].type == Ellipse) {
if (Geoms[geoId1].type == Ellipse) {
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
GCS::Ellipse &e2 = Ellipses[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintEqualRadii(e1, e2, tag);
return ConstraintsCounter;
}
else
std::swap(geoId1, geoId2);
}
if (Geoms[geoId1].type == Circle) {
GCS::Circle &c1 = Circles[Geoms[geoId1].index];
@@ -1502,6 +1802,18 @@ int Sketch::addPointOnObjectConstraint(int geoId1, PointPos pos1, int geoId2)
GCSsys.addConstraintPointOnCircle(p1, c, tag);
return ConstraintsCounter;
}
else if (Geoms[geoId2].type == Ellipse) {
GCS::Ellipse &e = Ellipses[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintPointOnEllipse(p1, e, tag);
return ConstraintsCounter;
}
else if (Geoms[geoId2].type == ArcOfEllipse) {
GCS::ArcOfEllipse &a = ArcsOfEllipse[Geoms[geoId2].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintPointOnArcOfEllipse(p1, a, tag);
return ConstraintsCounter;
}
}
return -1;
}
@@ -1555,6 +1867,167 @@ int Sketch::addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointP
return -1;
}
int Sketch::addInternalAlignmentEllipseMajorDiameter(int geoId1, int geoId2)
{
std::swap(geoId1, geoId2);
geoId1 = checkGeoId(geoId1);
geoId2 = checkGeoId(geoId2);
if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse)
return -1;
if (Geoms[geoId2].type != Line)
return -1;
int pointId1 = getPointId(geoId2, start);
int pointId2 = getPointId(geoId2, end);
if (pointId1 >= 0 && pointId1 < int(Points.size()) &&
pointId2 >= 0 && pointId2 < int(Points.size())) {
GCS::Point &p1 = Points[pointId1];
GCS::Point &p2 = Points[pointId2];
if(Geoms[geoId1].type == Ellipse) {
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
// constraints
// 1. start point with ellipse -a
// 2. end point with ellipse +a
int tag = ++ConstraintsCounter;
GCSsys.addConstraintInternalAlignmentEllipseMajorDiameter(e1, p1, p2, tag);
return ConstraintsCounter;
}
else {
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintInternalAlignmentEllipseMajorDiameter(a1, p1, p2, tag);
return ConstraintsCounter;
}
}
return -1;
}
int Sketch::addInternalAlignmentEllipseMinorDiameter(int geoId1, int geoId2)
{
std::swap(geoId1, geoId2);
geoId1 = checkGeoId(geoId1);
geoId2 = checkGeoId(geoId2);
if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse)
return -1;
if (Geoms[geoId2].type != Line)
return -1;
int pointId1 = getPointId(geoId2, start);
int pointId2 = getPointId(geoId2, end);
if (pointId1 >= 0 && pointId1 < int(Points.size()) &&
pointId2 >= 0 && pointId2 < int(Points.size())) {
GCS::Point &p1 = Points[pointId1];
GCS::Point &p2 = Points[pointId2];
if(Geoms[geoId1].type == Ellipse) {
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
// constraints
// 1. start point with ellipse -a
// 2. end point with ellipse +a
int tag = ++ConstraintsCounter;
GCSsys.addConstraintInternalAlignmentEllipseMinorDiameter(e1, p1, p2, tag);
return ConstraintsCounter;
}
else {
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintInternalAlignmentEllipseMinorDiameter(a1, p1, p2, tag);
return ConstraintsCounter;
}
}
return -1;
}
int Sketch::addInternalAlignmentEllipseFocus1(int geoId1, int geoId2)
{
std::swap(geoId1, geoId2);
geoId1 = checkGeoId(geoId1);
geoId2 = checkGeoId(geoId2);
if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse)
return -1;
if (Geoms[geoId2].type != Point)
return -1;
int pointId1 = getPointId(geoId2, start);
if (pointId1 >= 0 && pointId1 < int(Points.size())) {
GCS::Point &p1 = Points[pointId1];
if(Geoms[geoId1].type == Ellipse) {
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
// constraints
// 1. start point with ellipse -a
// 2. end point with ellipse +a
int tag = ++ConstraintsCounter;
GCSsys.addConstraintInternalAlignmentEllipseFocus1(e1, p1, tag);
return ConstraintsCounter;
}
else {
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintInternalAlignmentEllipseFocus1(a1, p1, tag);
return ConstraintsCounter;
}
}
return -1;
}
int Sketch::addInternalAlignmentEllipseFocus2(int geoId1, int geoId2)
{
std::swap(geoId1, geoId2);
geoId1 = checkGeoId(geoId1);
geoId2 = checkGeoId(geoId2);
if (Geoms[geoId1].type != Ellipse && Geoms[geoId1].type != ArcOfEllipse)
return -1;
if (Geoms[geoId2].type != Point)
return -1;
int pointId1 = getPointId(geoId2, start);
if (pointId1 >= 0 && pointId1 < int(Points.size())) {
GCS::Point &p1 = Points[pointId1];
if(Geoms[geoId1].type == Ellipse) {
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
// constraints
// 1. start point with ellipse -a
// 2. end point with ellipse +a
int tag = ++ConstraintsCounter;
GCSsys.addConstraintInternalAlignmentEllipseFocus2(e1, p1, tag);
return ConstraintsCounter;
}
else {
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
int tag = ++ConstraintsCounter;
GCSsys.addConstraintInternalAlignmentEllipseFocus2(a1, p1, tag);
return ConstraintsCounter;
}
}
return -1;
}
bool Sketch::updateGeometry()
{
int i=0;
@@ -1589,6 +2062,25 @@ bool Sketch::updateGeometry()
);
aoc->setRadius(*myArc.rad);
aoc->setRange(*myArc.startAngle, *myArc.endAngle);
} else if (it->type == ArcOfEllipse) {
GCS::ArcOfEllipse &myArc = ArcsOfEllipse[it->index];
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 fd=f1-center;
double radmaj = sqrt(fd*fd+radmin*radmin);
double phi = atan2(fd.y,fd.x);
aoe->setCenter(center);
aoe->setMajorRadius(radmaj);
aoe->setMinorRadius(radmin);
aoe->setAngleXU(phi);
aoe->setRange(*myArc.startAngle, *myArc.endAngle);
} else if (it->type == Circle) {
GeomCircle *circ = dynamic_cast<GeomCircle*>(it->geo);
circ->setCenter(Vector3d(*Points[it->midPointId].x,
@@ -1596,6 +2088,23 @@ bool Sketch::updateGeometry()
0.0)
);
circ->setRadius(*Circles[it->index].rad);
} else if (it->type == Ellipse) {
// TODO: Ellipse
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);
double radmin = *Ellipses[it->index].radmin;
Base::Vector3d fd=f1-center;
double radmaj = sqrt(fd*fd+radmin*radmin);
double phi = atan2(fd.y,fd.x);
ellipse->setCenter(center);
ellipse->setMajorRadius(radmaj);
ellipse->setMinorRadius(radmin);
ellipse->setAngleXU(phi);
}
} catch (Base::Exception e) {
Base::Console().Error("Updating geometry: Error build geometry(%d): %s\n",
@@ -1771,6 +2280,72 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
GCSsys.rescaleConstraint(i-1, 0.01);
GCSsys.rescaleConstraint(i, 0.01);
}
} else if (Geoms[geoId].type == Ellipse) {
// TODO: Ellipse
GCS::Point &center = Points[Geoms[geoId].midPointId];
GCS::Point p0,p1;
if (pos == mid) {
MoveParameters.resize(2); // cx,cy
p0.x = &MoveParameters[0];
p0.y = &MoveParameters[1];
*p0.x = *center.x;
*p0.y = *center.y;
GCSsys.addConstraintP2PCoincident(p0,center,-1);
} else if (pos == none) {
// TODO: Ellipse
MoveParameters.resize(4); // x,y,cx,cy
GCS::Ellipse &e = Ellipses[Geoms[geoId].index];
p0.x = &MoveParameters[0];
p0.y = &MoveParameters[1];
*p0.x = *center.x;
*p0.y = *center.y + *e.radmin;
GCSsys.addConstraintPointOnEllipse(p0,e,-1);
p1.x = &MoveParameters[2];
p1.y = &MoveParameters[3];
*p1.x = *center.x;
*p1.y = *center.y;
int i=GCSsys.addConstraintP2PCoincident(p1,center,-1);
GCSsys.rescaleConstraint(i-1, 0.01);
GCSsys.rescaleConstraint(i, 0.01);
}
} else if (Geoms[geoId].type == ArcOfEllipse) {
// TODO: ArcOfEllipse
GCS::Point &center = Points[Geoms[geoId].midPointId];
GCS::Point p0,p1;
if (pos == mid) {
MoveParameters.resize(2); // cx,cy
p0.x = &MoveParameters[0];
p0.y = &MoveParameters[1];
*p0.x = *center.x;
*p0.y = *center.y;
GCSsys.addConstraintP2PCoincident(p0,center,-1);
} else if (pos == start || pos == end || pos == none) {
// TODO: Ellipse
MoveParameters.resize(4); // x,y,cx,cy
if (pos == start || pos == end) {
GCS::Point &p = (pos == start) ? Points[Geoms[geoId].startPointId]
: Points[Geoms[geoId].endPointId];;
p0.x = &MoveParameters[0];
p0.y = &MoveParameters[1];
*p0.x = *p.x;
*p0.y = *p.y;
GCSsys.addConstraintP2PCoincident(p0,p,-1);
} else if (pos == none) {
GCS::ArcOfEllipse &a = ArcsOfEllipse[Geoms[geoId].index];
p0.x = &MoveParameters[0];
p0.y = &MoveParameters[1];
*p0.x = *center.x;
*p0.y = *center.y + *a.radmin;
GCSsys.addConstraintPointOnArcOfEllipse(p0,a,-1);
}
p1.x = &MoveParameters[2];
p1.y = &MoveParameters[3];
*p1.x = *center.x;
*p1.y = *center.y;
int i=GCSsys.addConstraintP2PCoincident(p1,center,-1);
GCSsys.rescaleConstraint(i-1, 0.01);
GCSsys.rescaleConstraint(i, 0.01);
}
} else if (Geoms[geoId].type == Arc) {
GCS::Point &center = Points[Geoms[geoId].midPointId];
GCS::Point p0,p1;
@@ -1858,6 +2433,16 @@ int Sketch::movePoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool rela
MoveParameters[0] = toPoint.x;
MoveParameters[1] = toPoint.y;
}
} else if (Geoms[geoId].type == Ellipse) {
if (pos == mid || pos == none) {
MoveParameters[0] = toPoint.x;
MoveParameters[1] = toPoint.y;
}
} else if (Geoms[geoId].type == ArcOfEllipse) {
if (pos == start || pos == end || pos == mid || pos == none) {
MoveParameters[0] = toPoint.x;
MoveParameters[1] = toPoint.y;
}
}
return solve();
@@ -1886,6 +2471,33 @@ 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

@@ -28,8 +28,8 @@
#include <Mod/Part/App/Geometry.h>
#include <Mod/Part/App/TopoShape.h>
#include "Constraint.h"
#include "freegcs/GCS.h"
#include "freegcs/GCS.h"
#include <Base/Persistence.h>
@@ -82,6 +82,8 @@ 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);
@@ -119,8 +121,10 @@ public:
int addArc(const Part::GeomArcOfCircle &circleSegment, bool fixed=false);
/// add a circle
int addCircle(const Part::GeomCircle &circle, bool fixed=false);
/// add a ellipse
/// add an ellipse
int addEllipse(const Part::GeomEllipse &ellipse, bool fixed=false);
/// add an arc of ellipse
int addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool fixed=false);
//@}
@@ -163,11 +167,14 @@ public:
int addTangentConstraint(int geoId1, PointPos pos1, int geoId2);
int addTangentConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2);
/// add a radius constraint on a circle or an arc
int addRadiusConstraint(int geoId, double value);
int addRadiusConstraint(int geoId, double value, int radiusnumber=0);
/// add an angle constraint on a line or between two lines
int addAngleConstraint(int geoId, double value);
int addAngleConstraint(int geoId1, int geoId2, double value);
int addAngleConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, double value);
/// add ellipse XDir axis angle constraint with respect to XAxis or a lines
int addEllipseAngleXUConstraint(int geoId, double value);
int addEllipseAngleXUConstraint(int geoId1, int geoId2, double value);
/// add an equal length or radius constraints between two lines or between circles and arcs
int addEqualConstraint(int geoId1, int geoId2);
/// add a point on line constraint
@@ -177,14 +184,24 @@ public:
/// add a symmetric constraint between three points, the last point is in the middle of the first two
int addSymmetricConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2, int geoId3, PointPos pos3);
//@}
/// Internal Alignment constraints
//@{
/// add InternalAlignmentEllipseMajorDiameter to a line and an ellipse
int addInternalAlignmentEllipseMajorDiameter(int geoId1, int geoId2);
int addInternalAlignmentEllipseMinorDiameter(int geoId1, int geoId2);
int addInternalAlignmentEllipseFocus1(int geoId1, int geoId2);
int addInternalAlignmentEllipseFocus2(int geoId1, int geoId2);
//@}
enum GeoType {
None = 0,
Point = 1, // 1 Point(start), 2 Parameters(x,y)
Line = 2, // 2 Points(start,end), 4 Parameters(x1,y1,x2,y2)
Arc = 3, // 3 Points(start,end,mid), (4)+5 Parameters((x1,y1,x2,y2),x,y,r,a1,a2)
Circle = 4, // 1 Point(mid), 3 Parameters(x,y,r)
Ellipse = 5
Ellipse = 5, // 1 Point(mid), 5 Parameters(x,y,r1,r2,phi) phi=angle xaxis of elipse with respect of sketch xaxis// TODO: Ellipse
ArcOfEllipse = 6
};
float SolveTime;
@@ -217,6 +234,8 @@ protected:
std::vector<GCS::Line> Lines;
std::vector<GCS::Arc> Arcs;
std::vector<GCS::Circle> Circles;
std::vector<GCS::Ellipse> Ellipses;
std::vector<GCS::ArcOfEllipse> ArcsOfEllipse;
bool isInitMove;
bool isFine;

View File

@@ -257,6 +257,10 @@ Base::Vector3d SketchObject::getPoint(int GeoId, PointPos PosId) const
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle*>(geo);
if (PosId == mid)
return circle->getCenter();
} else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
const Part::GeomEllipse *ellipse = dynamic_cast<const Part::GeomEllipse*>(geo);
if (PosId == mid)
return ellipse->getCenter();
} else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle *aoc = dynamic_cast<const Part::GeomArcOfCircle*>(geo);
if (PosId == start)
@@ -265,6 +269,14 @@ Base::Vector3d SketchObject::getPoint(int GeoId, PointPos PosId) const
return aoc->getEndPoint();
else if (PosId == mid)
return aoc->getCenter();
} else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
const Part::GeomArcOfEllipse *aoc = dynamic_cast<const Part::GeomArcOfEllipse*>(geo);
if (PosId == start)
return aoc->getStartPoint();
else if (PosId == end)
return aoc->getEndPoint();
else if (PosId == mid)
return aoc->getCenter();
}
return Base::Vector3d();
@@ -944,7 +956,9 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point)
return 0;
}
} else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
// TODO: Ellipse Trim support
return 0;
} else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle *aoc = dynamic_cast<const Part::GeomArcOfCircle*>(geo);
Base::Vector3d center = aoc->getCenter();
@@ -1490,6 +1504,9 @@ void SketchObject::rebuildVertexIndex(void)
} else if ((*it)->getTypeId() == Part::GeomCircle::getClassTypeId()) {
VertexId2GeoId.push_back(i);
VertexId2PosId.push_back(mid);
} else if ((*it)->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
VertexId2GeoId.push_back(i);
VertexId2PosId.push_back(mid);
} else if ((*it)->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
VertexId2GeoId.push_back(i);
VertexId2PosId.push_back(start);
@@ -1497,6 +1514,13 @@ void SketchObject::rebuildVertexIndex(void)
VertexId2PosId.push_back(end);
VertexId2GeoId.push_back(i);
VertexId2PosId.push_back(mid);
} else if ((*it)->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
VertexId2GeoId.push_back(i);
VertexId2PosId.push_back(start);
VertexId2GeoId.push_back(i);
VertexId2PosId.push_back(end);
VertexId2GeoId.push_back(i);
VertexId2PosId.push_back(mid);
}
}
}

View File

@@ -90,7 +90,9 @@ PyObject* SketchObjectPy::addGeometry(PyObject *args)
}
else if (geo->getTypeId() == Part::GeomPoint::getClassTypeId() ||
geo->getTypeId() == Part::GeomCircle::getClassTypeId() ||
geo->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
ret = this->getSketchObjectPtr()->addGeometry(geo);
}
@@ -131,7 +133,9 @@ PyObject* SketchObjectPy::addGeometry(PyObject *args)
}
else if (geo->getTypeId() == Part::GeomPoint::getClassTypeId() ||
geo->getTypeId() == Part::GeomCircle::getClassTypeId() ||
geo->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
geoList.push_back(geo);
}

File diff suppressed because it is too large Load Diff

View File

@@ -46,7 +46,26 @@ namespace GCS
Perpendicular = 9,
L2LAngle = 10,
MidpointOnLine = 11,
TangentCircumf = 12
TangentCircumf = 12,
P2OnEllipse = 13,
TangentEllipseLine = 14,
Point2EllipseDistance = 15,
InternalAlignmentPoint2Ellipse = 16,
EqualMajorAxesEllipse = 17,
EllipticalArcRangeToEndPoints = 18
};
enum InternalAlignmentType {
EllipsePositiveMajorX = 0,
EllipsePositiveMajorY = 1,
EllipseNegativeMajorX = 2,
EllipseNegativeMajorY = 3,
EllipsePositiveMinorX = 4,
EllipsePositiveMinorY = 5,
EllipseNegativeMinorX = 6,
EllipseNegativeMinorY = 7,
EllipseFocus2X = 8,
EllipseFocus2Y = 9
};
class Constraint
@@ -159,6 +178,7 @@ namespace GCS
virtual double error();
virtual double grad(double *);
virtual double maxStep(MAP_pD_D &dir, double lim=1.);
double abs(double darea);
};
// PointOnLine
@@ -304,6 +324,110 @@ namespace GCS
virtual double error();
virtual double grad(double *);
};
// PointOnEllipse
class ConstraintPointOnEllipse : public Constraint
{
private:
inline double* p1x() { return pvec[0]; }
inline double* p1y() { return pvec[1]; }
inline double* cx() { return pvec[2]; }
inline double* cy() { return pvec[3]; }
inline double* f1x() { return pvec[4]; }
inline double* f1y() { return pvec[5]; }
inline double* rmin() { return pvec[6]; }
public:
ConstraintPointOnEllipse(Point &p, Ellipse &e);
ConstraintPointOnEllipse(Point &p, ArcOfEllipse &a);
virtual ConstraintType getTypeId();
virtual void rescale(double coef=1.);
virtual double error();
virtual double grad(double *);
};
class ConstraintEllipseTangentLine : public Constraint
{
private:
inline double* p1x() { return pvec[0]; }
inline double* p1y() { return pvec[1]; }
inline double* p2x() { return pvec[2]; }
inline double* p2y() { return pvec[3]; }
inline double* cx() { return pvec[4]; }
inline double* cy() { return pvec[5]; }
inline double* f1x() { return pvec[6]; }
inline double* f1y() { return pvec[7]; }
inline double* rmin() { return pvec[8]; }
public:
ConstraintEllipseTangentLine(Line &l, Ellipse &e);
ConstraintEllipseTangentLine(Line &l, ArcOfEllipse &a);
virtual ConstraintType getTypeId();
virtual void rescale(double coef=1.);
virtual double error();
virtual double grad(double *);
};
class ConstraintInternalAlignmentPoint2Ellipse : public Constraint
{
private:
inline double* p1x() { return pvec[0]; }
inline double* p1y() { return pvec[1]; }
inline double* cx() { return pvec[2]; }
inline double* cy() { return pvec[3]; }
inline double* f1x() { return pvec[4]; }
inline double* f1y() { return pvec[5]; }
inline double* rmin() { return pvec[6]; }
public:
ConstraintInternalAlignmentPoint2Ellipse(Ellipse &e, Point &p1, InternalAlignmentType alignmentType);
ConstraintInternalAlignmentPoint2Ellipse(ArcOfEllipse &e, Point &p1, InternalAlignmentType alignmentType);
virtual ConstraintType getTypeId();
virtual void rescale(double coef=1.);
virtual double error();
virtual double grad(double *);
private:
InternalAlignmentType AlignmentType;
};
class ConstraintEqualMajorAxesEllipse : public Constraint
{
private:
inline double* e1cx() { return pvec[0]; }
inline double* e1cy() { return pvec[1]; }
inline double* e1f1x() { return pvec[2]; }
inline double* e1f1y() { return pvec[3]; }
inline double* e1rmin() { return pvec[4]; }
inline double* e2cx() { return pvec[5]; }
inline double* e2cy() { return pvec[6]; }
inline double* e2f1x() { return pvec[7]; }
inline double* e2f1y() { return pvec[8]; }
inline double* e2rmin() { return pvec[9]; }
public:
ConstraintEqualMajorAxesEllipse(Ellipse &e1, Ellipse &e2);
virtual ConstraintType getTypeId();
virtual void rescale(double coef=1.);
virtual double error();
virtual double grad(double *);
};
// EllipticalArcRangeToEndPoints
class ConstraintEllipticalArcRangeToEndPoints : public Constraint
{
private:
inline double* p1x() { return pvec[0]; }
inline double* p1y() { return pvec[1]; }
inline double* angle() { return pvec[2]; }
inline double* cx() { return pvec[3]; }
inline double* cy() { return pvec[4]; }
inline double* f1x() { return pvec[5]; }
inline double* f1y() { return pvec[6]; }
inline double* rmin() { return pvec[7]; }
public:
ConstraintEllipticalArcRangeToEndPoints(Point &p, ArcOfEllipse &a, double *angle_t);
virtual ConstraintType getTypeId();
virtual void rescale(double coef=1.);
virtual double error();
virtual double grad(double *);
virtual double maxStep(MAP_pD_D &dir, double lim=1.);
};
} //namespace GCS

View File

@@ -27,6 +27,16 @@
#include "qp_eq.h"
#include <Eigen/QR>
#define _GCS_DEBUG 1
#ifdef _GCS_DEBUG
#include <Base/Writer.h>
#include <Base/Reader.h>
#include <Base/Exception.h>
#include <Base/TimeInfo.h>
#include <Base/Console.h>
#endif // _GCS_DEBUG
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
@@ -481,6 +491,42 @@ int System::addConstraintPointOnCircle(Point &p, Circle &c, int tagId)
return addConstraintP2PDistance(p, c.center, c.rad, tagId);
}
int System::addConstraintPointOnEllipse(Point &p, Ellipse &e, int tagId)
{
// TODO: Implement real constraint => Done
Constraint *constr = new ConstraintPointOnEllipse(p, e);
constr->setTag(tagId);
return addConstraint(constr);
}
int System::addConstraintEllipticalArcRangeToEndPoints(Point &p, ArcOfEllipse &a, double *angle, int tagId)
{
Constraint *constr = new ConstraintEllipticalArcRangeToEndPoints(p,a,angle);
constr->setTag(tagId);
return addConstraint(constr);
}
int System::addConstraintArcOfEllipseRules(ArcOfEllipse &a, int tagId)
{
/* addConstraintP2PAngle(a.center, a.start, a.startAngle, tagId);
return addConstraintP2PAngle(a.center, a.end, a.endAngle, tagId);*/
addConstraintEllipticalArcRangeToEndPoints(a.start,a,a.startAngle, tagId);
addConstraintEllipticalArcRangeToEndPoints(a.end,a,a.endAngle, tagId);
addConstraintPointOnArcOfEllipse(a.start, a, tagId);
return addConstraintPointOnArcOfEllipse(a.end, a, tagId);
}
int System::addConstraintPointOnArcOfEllipse(Point &p, ArcOfEllipse &a, int tagId)
{
Constraint *constr = new ConstraintPointOnEllipse(p, a);
constr->setTag(tagId);
return addConstraint(constr);
}
int System::addConstraintPointOnArc(Point &p, Arc &a, int tagId)
{
return addConstraintP2PDistance(p, a.center, a.rad, tagId);
@@ -552,6 +598,39 @@ int System::addConstraintTangent(Line &l, Circle &c, int tagId)
return addConstraintP2LDistance(c.center, l, c.rad, tagId);
}
int System::addConstraintTangent(Line &l, Ellipse &e, int tagId)
{
// TODO: real ellipse implementation => Done
Constraint *constr = new ConstraintEllipseTangentLine(l, e);
constr->setTag(tagId);
return addConstraint(constr);
}
int System::addConstraintTangent(Line &l, ArcOfEllipse &a, int tagId)
{
// TODO: real ellipse implementation => Done
Constraint *constr = new ConstraintEllipseTangentLine(l, a);
constr->setTag(tagId);
return addConstraint(constr);
}
int System::addConstraintTangent(Ellipse &e, Circle &c, int tagId)
{
// TODO: elipse
/*double dx = *(c.center.x) - *(e.center.x);
double dy = *(c.center.y) - *(e.center.y);
double d = sqrt(dx*dx + dy*dy);*/
/*Constraint *constr = new ConstraintPoint2EllipseDistance(c.center,e,c.rad);
constr->setTag(tagId);
return addConstraint(constr); */
//return addConstraintTangentCircumf(e.center, c.center, e.radmaj, c.rad,
// (d < *e.radmaj || d < *c.rad), tagId);
return 0;
}
int System::addConstraintTangent(Line &l, Arc &a, int tagId)
{
return addConstraintP2LDistance(a.center, l, a.rad, tagId);
@@ -584,6 +663,19 @@ int System::addConstraintTangent(Circle &c, Arc &a, int tagId)
(d < *c.rad || d < *a.rad), tagId);
}
int System::addConstraintTangent(Ellipse &e, Arc &a, int tagId)
{
// TODO: elipse
/*double dx = *(a.center.x) - *(e.center.x);
double dy = *(a.center.y) - *(e.center.y);
double d = sqrt(dx*dx + dy*dy);Constraint *constr = new ConstraintEllipseTangentLine(l, e);
constr->setTag(tagId);
return addConstraint(constr);
return addConstraintTangentCircumf(e.center, a.center, e.radmaj, a.rad,
(d < *e.radmaj || d < *a.rad), tagId);*/
return 0;
}
int System::addConstraintTangentLine2Arc(Point &p1, Point &p2, Arc &a, int tagId)
{
addConstraintP2PCoincident(p2, a.start, tagId);
@@ -598,6 +690,18 @@ int System::addConstraintTangentArc2Line(Arc &a, Point &p1, Point &p2, int tagId
return addConstraintP2PAngle(p1, p2, a.endAngle, incrAngle, tagId);
}
int System::addConstraintTangentLine2ArcOfEllipse(Point &p1, Point &p2, Line &l, ArcOfEllipse &a, int tagId)
{
addConstraintP2PCoincident(p2, a.start, tagId);
return addConstraintTangent(l, a, tagId);
}
int System::addConstraintTangentArcOfEllipse2Line(ArcOfEllipse &a, Line &l, Point &p1, Point &p2, int tagId)
{
addConstraintP2PCoincident(p1, a.end, tagId);
return addConstraintTangent(l, a, tagId);
}
int System::addConstraintTangentCircle2Arc(Circle &c, Arc &a, int tagId)
{
addConstraintPointOnCircle(a.start, c, tagId);
@@ -609,6 +713,19 @@ int System::addConstraintTangentCircle2Arc(Circle &c, Arc &a, int tagId)
return addConstraintP2PAngle(c.center, a.start, a.startAngle, M_PI, tagId);
}
int System::addConstraintTangentEllipse2Arc(Ellipse &e, Arc &a, int tagId)
{
// TODO: Ellipse
/*addConstraintPointOnEllipse(a.start, e, tagId);
double dx = *(a.start.x) - *(e.center.x);
double dy = *(a.start.y) - *(e.center.y);
if (dx * cos(*(a.startAngle)) + dy * sin(*(a.startAngle)) > 0)
return addConstraintP2PAngle(e.center, a.start, a.startAngle, 0, tagId);
else
return addConstraintP2PAngle(e.center, a.start, a.startAngle, M_PI, tagId);*/
return 0;
}
int System::addConstraintTangentArc2Circle(Arc &a, Circle &c, int tagId)
{
addConstraintPointOnCircle(a.end, c, tagId);
@@ -620,6 +737,19 @@ int System::addConstraintTangentArc2Circle(Arc &a, Circle &c, int tagId)
return addConstraintP2PAngle(c.center, a.end, a.endAngle, M_PI, tagId);
}
int System::addConstraintTangentArc2Ellipse(Arc &a, Ellipse &e, int tagId)
{
// TODO: Ellipse
/*addConstraintPointOnEllipse(a.end, e, tagId);
double dx = *(a.end.x) - *(e.center.x);
double dy = *(a.end.y) - *(e.center.y);
if (dx * cos(*(a.endAngle)) + dy * sin(*(a.endAngle)) > 0)
return addConstraintP2PAngle(e.center, a.end, a.endAngle, 0, tagId);
else
return addConstraintP2PAngle(e.center, a.end, a.endAngle, M_PI, tagId);*/
return 0;
}
int System::addConstraintTangentArc2Arc(Arc &a1, bool reverse1, Arc &a2, bool reverse2,
int tagId)
{
@@ -656,6 +786,17 @@ int System::addConstraintEqualRadius(Circle &c1, Circle &c2, int tagId)
return addConstraintEqual(c1.rad, c2.rad, tagId);
}
int System::addConstraintEqualRadii(Ellipse &e1, Ellipse &e2, int tagId)
{
// TODO: Ellipse
//addConstraintEqual(e1.radmaj, e2.radmaj, tagId);
addConstraintEqual(e1.radmin, e2.radmin, tagId);
Constraint *constr = new ConstraintEqualMajorAxesEllipse(e1,e2);
constr->setTag(tagId);
return addConstraint(constr);
}
int System::addConstraintEqualRadius(Circle &c1, Arc &a2, int tagId)
{
return addConstraintEqual(c1.rad, a2.rad, tagId);
@@ -678,6 +819,74 @@ int System::addConstraintP2PSymmetric(Point &p1, Point &p2, Point &p, int tagId)
return addConstraintPointOnLine(p, p1, p2, tagId);
}
int System::addConstraintInternalAlignmentPoint2Ellipse(Ellipse &e, Point &p1, InternalAlignmentType alignmentType, int tagId)
{
Constraint *constr = new ConstraintInternalAlignmentPoint2Ellipse(e, p1, alignmentType);
constr->setTag(tagId);
return addConstraint(constr);
}
int System::addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId)
{
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMajorX,tagId);
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMajorY,tagId);
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMajorX,tagId);
return addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMajorY,tagId);
}
int System::addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId)
{
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMinorX,tagId);
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMinorY,tagId);
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMinorX,tagId);
return addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMinorY,tagId);
}
int System::addConstraintInternalAlignmentEllipseFocus1(Ellipse &e, Point &p1, int tagId)
{
return addConstraintP2PCoincident(e.focus1,p1);
}
int System::addConstraintInternalAlignmentEllipseFocus2(Ellipse &e, Point &p1, int tagId)
{
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseFocus2X,tagId);
return addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseFocus2Y,tagId);
}
int System::addConstraintInternalAlignmentPoint2Ellipse(ArcOfEllipse &a, Point &p1, InternalAlignmentType alignmentType, int tagId)
{
Constraint *constr = new ConstraintInternalAlignmentPoint2Ellipse(a, p1, alignmentType);
constr->setTag(tagId);
return addConstraint(constr);
}
int System::addConstraintInternalAlignmentEllipseMajorDiameter(ArcOfEllipse &a, Point &p1, Point &p2, int tagId)
{
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipsePositiveMajorX,tagId);
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipsePositiveMajorY,tagId);
addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipseNegativeMajorX,tagId);
return addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipseNegativeMajorY,tagId);
}
int System::addConstraintInternalAlignmentEllipseMinorDiameter(ArcOfEllipse &a, Point &p1, Point &p2, int tagId)
{
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipsePositiveMinorX,tagId);
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipsePositiveMinorY,tagId);
addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipseNegativeMinorX,tagId);
return addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipseNegativeMinorY,tagId);
}
int System::addConstraintInternalAlignmentEllipseFocus1(ArcOfEllipse &a, Point &p1, int tagId)
{
return addConstraintP2PCoincident(a.focus1,p1);
}
int System::addConstraintInternalAlignmentEllipseFocus2(ArcOfEllipse &a, Point &p1, int tagId)
{
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipseFocus2X,tagId);
return addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipseFocus2Y,tagId);
}
void System::rescaleConstraint(int id, double coeff)
{
if (id >= clist.size() || id < 0)
@@ -1465,12 +1674,27 @@ int System::diagnose()
J(count-1,j) = (*constr)->grad(plist[j]);
}
}
#ifdef _GCS_DEBUG
// Debug code starts
std::stringstream stream;
stream << "[";
stream << J ;
stream << "]";
const std::string tmp = stream.str();
Base::Console().Warning(tmp.c_str());
// Debug code ends
#endif
if (J.rows() > 0) {
Eigen::FullPivHouseholderQR<Eigen::MatrixXd> qrJT(J.topRows(count).transpose());
Eigen::MatrixXd Q = qrJT.matrixQ ();
int paramsNum = qrJT.rows();
int constrNum = qrJT.cols();
//qrJT.setThreshold(0);
int rank = qrJT.rank();
Eigen::MatrixXd R;

View File

@@ -125,6 +125,10 @@ namespace GCS
int addConstraintCoordinateY(Point &p, double *y, int tagId=0);
int addConstraintArcRules(Arc &a, int tagId=0);
int addConstraintPointOnCircle(Point &p, Circle &c, int tagId=0);
int addConstraintPointOnEllipse(Point &p, Ellipse &e, int tagId=0);
int addConstraintEllipticalArcRangeToEndPoints(Point &p, ArcOfEllipse &a, double *angle, int tagId=0);
int addConstraintArcOfEllipseRules(ArcOfEllipse &a, int tagId=0);
int addConstraintPointOnArcOfEllipse(Point &p, ArcOfEllipse &a, int tagId=0);
int addConstraintPointOnArc(Point &p, Arc &a, int tagId=0);
int addConstraintPerpendicularLine2Arc(Point &p1, Point &p2, Arc &a,
int tagId=0);
@@ -137,24 +141,47 @@ namespace GCS
int addConstraintPerpendicularArc2Arc(Arc &a1, bool reverse1,
Arc &a2, bool reverse2, int tagId=0);
int addConstraintTangent(Line &l, Circle &c, int tagId=0);
int addConstraintTangent(Line &l, Ellipse &e, int tagId=0);
int addConstraintTangent(Line &l, ArcOfEllipse &a, int tagId=0);
int addConstraintTangent(Ellipse &e, Circle &c, int tagId=0);
int addConstraintTangent(Line &l, Arc &a, int tagId=0);
int addConstraintTangent(Circle &c1, Circle &c2, int tagId=0);
int addConstraintTangent(Arc &a1, Arc &a2, int tagId=0);
int addConstraintTangent(Circle &c, Arc &a, int tagId=0);
int addConstraintTangent(Ellipse &e, Arc &a, int tagId=0);
int addConstraintTangentLine2ArcOfEllipse(Point &p1, Point &p2, Line &l, ArcOfEllipse &a, int tagId=0);
int addConstraintTangentArcOfEllipse2Line(ArcOfEllipse &a, Line &l, Point &p1, Point &p2, int tagId=0);
int addConstraintTangentLine2Arc(Point &p1, Point &p2, Arc &a, int tagId=0);
int addConstraintTangentArc2Line(Arc &a, Point &p1, Point &p2, int tagId=0);
int addConstraintTangentCircle2Arc(Circle &c, Arc &a, int tagId=0);
int addConstraintTangentEllipse2Arc(Ellipse &e, Arc &a, int tagId=0);
int addConstraintTangentArc2Circle(Arc &a, Circle &c, int tagId=0);
int addConstraintTangentArc2Ellipse(Arc &a, Ellipse &e, int tagId=0);
int addConstraintTangentArc2Arc(Arc &a1, bool reverse1, Arc &a2, bool reverse2,
int tagId=0);
int addConstraintCircleRadius(Circle &c, double *radius, int tagId=0);
int addConstraintEllipseAngleXU(Ellipse &e, double *angle, int tagId=0);
int addConstraintArcRadius(Arc &a, double *radius, int tagId=0);
int addConstraintEqualLength(Line &l1, Line &l2, double *length, int tagId=0);
int addConstraintEqualRadius(Circle &c1, Circle &c2, int tagId=0);
int addConstraintEqualRadii(Ellipse &e1, Ellipse &e2, int tagId=0);
int addConstraintEqualRadius(Circle &c1, Arc &a2, int tagId=0);
int addConstraintEqualRadius(Arc &a1, Arc &a2, int tagId=0);
int addConstraintP2PSymmetric(Point &p1, Point &p2, Line &l, int tagId=0);
int addConstraintP2PSymmetric(Point &p1, Point &p2, Point &p, int tagId=0);
// internal alignment constraints
int addConstraintInternalAlignmentPoint2Ellipse(Ellipse &e, Point &p1, InternalAlignmentType alignmentType, int tagId=0);
int addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId=0);
int addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId=0);
int addConstraintInternalAlignmentEllipseFocus1(Ellipse &e, Point &p1, int tagId=0);
int addConstraintInternalAlignmentEllipseFocus2(Ellipse &e, Point &p1, int tagId=0);
int addConstraintInternalAlignmentPoint2Ellipse(ArcOfEllipse &a, Point &p1, InternalAlignmentType alignmentType, int tagId=0);
int addConstraintInternalAlignmentEllipseMajorDiameter(ArcOfEllipse &a, Point &p1, Point &p2, int tagId=0);
int addConstraintInternalAlignmentEllipseMinorDiameter(ArcOfEllipse &a, Point &p1, Point &p2, int tagId=0);
int addConstraintInternalAlignmentEllipseFocus1(ArcOfEllipse &a, Point &p1, int tagId=0);
int addConstraintInternalAlignmentEllipseFocus2(ArcOfEllipse &a, Point &p1, int tagId=0);
void rescaleConstraint(int id, double coeff);
void declareUnknowns(VEC_pD &params);

View File

@@ -65,6 +65,28 @@ namespace GCS
Point center;
double *rad;
};
class Ellipse
{
public:
Ellipse(){ radmin = 0;}
Point center;
Point focus1; //+x
double *radmin;
};
class ArcOfEllipse
{
public:
ArcOfEllipse(){startAngle=0;endAngle=0;radmin = 0;}
double *startAngle;
double *endAngle;
double *radmin;
Point start;
Point end;
Point center;
Point focus1; //+x
};
} //namespace GCS