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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user