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:
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 *> ¶ms = 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 *> ¶ms = 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 *> ¶ms = 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 ¢er = 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 ¢er = 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 ¢er = 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 ¢er = 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ¶ms);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user