Sketcher Ellipse and ArcOfEllipse: Extra features and bug fixes
- Minor changes to alignment constraint selection to avoid to create objects just for simple calculations - Equality constraint of Ellipse, ArcOfEllipse and combinations of those elements - Bugfix for internalalignment creation of major and minor of ellipse and extension to arcofellipse - Trim support for ellipses - Solver threshold for rank calculation set at 1e-13. - Trim support for arc of ellipse - Ellipses and ArcOfEllipses as external geometry - Validate Sketch now supports arcs of ellipse - Tangents of Ellipse or ArcOfEllipse to any of ArcOfcircle, circle and Ellipse (using construction elements) - Perpendicularity constraint - Bug fix: Show/hide internal geometry not working for external geometry - Visualization of Internal alignment constraints when selecting in the constraint widget - Equality for ellipses and arc of ellipses
This commit is contained in:
parent
21354e9a8b
commit
a067a7c25a
|
@ -1761,6 +1761,26 @@ int Sketch::addEqualConstraint(int geoId1, int geoId2)
|
|||
GCSsys.addConstraintEqualRadius(a1, a2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
|
||||
if (Geoms[geoId2].type == ArcOfEllipse) {
|
||||
if (Geoms[geoId1].type == ArcOfEllipse) {
|
||||
GCS::ArcOfEllipse &a1 = ArcsOfEllipse[Geoms[geoId1].index];
|
||||
GCS::ArcOfEllipse &a2 = ArcsOfEllipse[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintEqualRadii(a1, a2, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
|
||||
if (Geoms[geoId1].type == Ellipse) {
|
||||
GCS::Ellipse &e1 = Ellipses[Geoms[geoId1].index];
|
||||
if (Geoms[geoId2].type == ArcOfEllipse) {
|
||||
GCS::ArcOfEllipse &a2 = ArcsOfEllipse[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintEqualRadii(a2, e1, tag);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
}
|
||||
|
||||
Base::Console().Warning("Equality constraints between %s and %s are not supported.\n",
|
||||
nameByType(Geoms[geoId1].type), nameByType(Geoms[geoId2].type));
|
||||
|
|
|
@ -30,11 +30,13 @@
|
|||
# include <gp_Pln.hxx>
|
||||
# include <gp_Ax3.hxx>
|
||||
# include <gp_Circ.hxx>
|
||||
# include <gp_Elips.hxx>
|
||||
# include <BRepAdaptor_Surface.hxx>
|
||||
# include <BRepAdaptor_Curve.hxx>
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <Geom_Plane.hxx>
|
||||
# include <Geom_Circle.hxx>
|
||||
# include <Geom_Ellipse.hxx>
|
||||
# include <Geom_TrimmedCurve.hxx>
|
||||
# include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
# include <BRepOffsetAPI_NormalProjection.hxx>
|
||||
|
@ -957,8 +959,95 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point)
|
|||
return 0;
|
||||
}
|
||||
} else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
// TODO: Ellipse Trim support
|
||||
const Part::GeomEllipse *ellipse = dynamic_cast<const Part::GeomEllipse*>(geo);
|
||||
Base::Vector3d center = ellipse->getCenter();
|
||||
double theta0 = Base::fmod(
|
||||
atan2(-ellipse->getMajorRadius()*((point.x-center.x)*sin(ellipse->getAngleXU())-(point.y-center.y)*cos(ellipse->getAngleXU())),
|
||||
ellipse->getMinorRadius()*((point.x-center.x)*cos(ellipse->getAngleXU())+(point.y-center.y)*sin(ellipse->getAngleXU()))
|
||||
), 2.f*M_PI);
|
||||
if (GeoId1 >= 0 && GeoId2 >= 0) {
|
||||
double theta1 = Base::fmod(
|
||||
atan2(-ellipse->getMajorRadius()*((point1.x-center.x)*sin(ellipse->getAngleXU())-(point1.y-center.y)*cos(ellipse->getAngleXU())),
|
||||
ellipse->getMinorRadius()*((point1.x-center.x)*cos(ellipse->getAngleXU())+(point1.y-center.y)*sin(ellipse->getAngleXU()))
|
||||
), 2.f*M_PI);
|
||||
double theta2 = Base::fmod(
|
||||
atan2(-ellipse->getMajorRadius()*((point2.x-center.x)*sin(ellipse->getAngleXU())-(point2.y-center.y)*cos(ellipse->getAngleXU())),
|
||||
ellipse->getMinorRadius()*((point2.x-center.x)*cos(ellipse->getAngleXU())+(point2.y-center.y)*sin(ellipse->getAngleXU()))
|
||||
), 2.f*M_PI);
|
||||
if (Base::fmod(theta1 - theta0, 2.f*M_PI) > Base::fmod(theta2 - theta0, 2.f*M_PI)) {
|
||||
std::swap(GeoId1,GeoId2);
|
||||
std::swap(point1,point2);
|
||||
std::swap(theta1,theta2);
|
||||
}
|
||||
if (theta1 == theta0 || theta1 == theta2)
|
||||
return -1;
|
||||
else if (theta1 > theta2)
|
||||
theta2 += 2.f*M_PI;
|
||||
|
||||
// Trim Point between intersection points
|
||||
|
||||
// Create a new arc to substitute Circle in geometry list and set parameters
|
||||
Part::GeomArcOfEllipse *geoNew = new Part::GeomArcOfEllipse();
|
||||
geoNew->setCenter(center);
|
||||
geoNew->setMajorRadius(ellipse->getMajorRadius());
|
||||
geoNew->setMinorRadius(ellipse->getMinorRadius());
|
||||
geoNew->setAngleXU(ellipse->getAngleXU());
|
||||
geoNew->setRange(theta1, theta2);
|
||||
|
||||
std::vector< Part::Geometry * > newVals(geomlist);
|
||||
newVals[GeoId] = geoNew;
|
||||
Geometry.setValues(newVals);
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
delete geoNew;
|
||||
rebuildVertexIndex();
|
||||
|
||||
PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none;
|
||||
ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject;
|
||||
for (std::vector<Constraint *>::const_iterator it=constraints.begin();
|
||||
it != constraints.end(); ++it) {
|
||||
Constraint *constr = *(it);
|
||||
if (secondPos1 == Sketcher::none && (constr->First == GeoId1 && constr->Second == GeoId)) {
|
||||
constrType1= Sketcher::Coincident;
|
||||
secondPos1 = constr->FirstPos;
|
||||
} else if(secondPos2 == Sketcher::none && (constr->First == GeoId2 && constr->Second == GeoId)) {
|
||||
constrType2 = Sketcher::Coincident;
|
||||
secondPos2 = constr->FirstPos;
|
||||
}
|
||||
}
|
||||
|
||||
// constrain the trimming points on the corresponding geometries
|
||||
Sketcher::Constraint *newConstr = new Sketcher::Constraint();
|
||||
newConstr->Type = constrType1;
|
||||
newConstr->First = GeoId;
|
||||
newConstr->FirstPos = start;
|
||||
newConstr->Second = GeoId1;
|
||||
|
||||
if (constrType1 == Sketcher::Coincident) {
|
||||
newConstr->SecondPos = secondPos1;
|
||||
delConstraintOnPoint(GeoId1, secondPos1, false);
|
||||
}
|
||||
|
||||
addConstraint(newConstr);
|
||||
|
||||
// Reset secondpos in case it was set previously
|
||||
newConstr->SecondPos = Sketcher::none;
|
||||
|
||||
// Add Second Constraint
|
||||
newConstr->First = GeoId;
|
||||
newConstr->FirstPos = end;
|
||||
newConstr->Second = GeoId2;
|
||||
|
||||
if (constrType2 == Sketcher::Coincident) {
|
||||
newConstr->SecondPos = secondPos2;
|
||||
delConstraintOnPoint(GeoId2, secondPos2, false);
|
||||
}
|
||||
|
||||
addConstraint(newConstr);
|
||||
|
||||
delete newConstr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
} else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
const Part::GeomArcOfCircle *aoc = dynamic_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
Base::Vector3d center = aoc->getCenter();
|
||||
|
@ -1106,6 +1195,176 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point)
|
|||
newConstr->FirstPos = end;
|
||||
newConstr->Second = GeoId1;
|
||||
|
||||
if (constrType == Sketcher::Coincident)
|
||||
newConstr->SecondPos = secondPos;
|
||||
|
||||
addConstraint(newConstr);
|
||||
delete newConstr;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
const Part::GeomArcOfEllipse *aoe = dynamic_cast<const Part::GeomArcOfEllipse*>(geo);
|
||||
Base::Vector3d center = aoe->getCenter();
|
||||
double startAngle, endAngle;
|
||||
aoe->getRange(startAngle, endAngle);
|
||||
double dir = (startAngle < endAngle) ? 1 : -1; // this is always == 1
|
||||
double arcLength = (endAngle - startAngle)*dir;
|
||||
double theta0 = Base::fmod(
|
||||
atan2(-aoe->getMajorRadius()*((point.x-center.x)*sin(aoe->getAngleXU())-(point.y-center.y)*cos(aoe->getAngleXU())),
|
||||
aoe->getMinorRadius()*((point.x-center.x)*cos(aoe->getAngleXU())+(point.y-center.y)*sin(aoe->getAngleXU()))
|
||||
)- startAngle, 2.f*M_PI); // x0
|
||||
if (GeoId1 >= 0 && GeoId2 >= 0) {
|
||||
double theta1 = Base::fmod(
|
||||
atan2(-aoe->getMajorRadius()*((point1.x-center.x)*sin(aoe->getAngleXU())-(point1.y-center.y)*cos(aoe->getAngleXU())),
|
||||
aoe->getMinorRadius()*((point1.x-center.x)*cos(aoe->getAngleXU())+(point1.y-center.y)*sin(aoe->getAngleXU()))
|
||||
)- startAngle, 2.f*M_PI) * dir; // x1
|
||||
double theta2 = Base::fmod(
|
||||
atan2(-aoe->getMajorRadius()*((point2.x-center.x)*sin(aoe->getAngleXU())-(point2.y-center.y)*cos(aoe->getAngleXU())),
|
||||
aoe->getMinorRadius()*((point2.x-center.x)*cos(aoe->getAngleXU())+(point2.y-center.y)*sin(aoe->getAngleXU()))
|
||||
)- startAngle, 2.f*M_PI) * dir; // x2
|
||||
|
||||
if (theta1 > theta2) {
|
||||
std::swap(GeoId1,GeoId2);
|
||||
std::swap(point1,point2);
|
||||
std::swap(theta1,theta2);
|
||||
}
|
||||
if (theta1 >= 0.001*arcLength && theta2 <= 0.999*arcLength) {
|
||||
// Trim Point between intersection points
|
||||
if (theta1 < theta0 && theta2 > theta0) {
|
||||
int newGeoId = addGeometry(geo);
|
||||
// go through all constraints and replace the point (GeoId,end) with (newGeoId,end)
|
||||
transferConstraints(GeoId, end, newGeoId, end);
|
||||
|
||||
Part::GeomArcOfEllipse *aoe1 = dynamic_cast<Part::GeomArcOfEllipse*>(geomlist[GeoId]);
|
||||
Part::GeomArcOfEllipse *aoe2 = dynamic_cast<Part::GeomArcOfEllipse*>(geomlist[newGeoId]);
|
||||
aoe1->setRange(startAngle, startAngle + theta1);
|
||||
aoe2->setRange(startAngle + theta2, endAngle);
|
||||
|
||||
// constrain the trimming points on the corresponding geometries
|
||||
Sketcher::Constraint *newConstr = new Sketcher::Constraint();
|
||||
|
||||
// Build Constraints associated with new pair of arcs
|
||||
newConstr->Type = Sketcher::Equal;
|
||||
newConstr->First = GeoId;
|
||||
newConstr->Second = newGeoId;
|
||||
addConstraint(newConstr);
|
||||
|
||||
PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none;
|
||||
ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject;
|
||||
|
||||
for (std::vector<Constraint *>::const_iterator it=constraints.begin();
|
||||
it != constraints.end(); ++it) {
|
||||
Constraint *constr = *(it);
|
||||
if (secondPos1 == Sketcher::none &&
|
||||
(constr->First == GeoId1 && constr->Second == GeoId)) {
|
||||
constrType1= Sketcher::Coincident;
|
||||
secondPos1 = constr->FirstPos;
|
||||
} else if (secondPos2 == Sketcher::none &&
|
||||
(constr->First == GeoId2 && constr->Second == GeoId)) {
|
||||
constrType2 = Sketcher::Coincident;
|
||||
secondPos2 = constr->FirstPos;
|
||||
}
|
||||
}
|
||||
|
||||
newConstr->Type = constrType1;
|
||||
newConstr->First = GeoId;
|
||||
newConstr->FirstPos = end;
|
||||
newConstr->Second = GeoId1;
|
||||
|
||||
if (constrType1 == Sketcher::Coincident) {
|
||||
newConstr->SecondPos = secondPos1;
|
||||
delConstraintOnPoint(GeoId1, secondPos1, false);
|
||||
}
|
||||
|
||||
addConstraint(newConstr);
|
||||
|
||||
// Reset secondpos in case it was set previously
|
||||
newConstr->SecondPos = Sketcher::none;
|
||||
|
||||
newConstr->Type = constrType2;
|
||||
newConstr->First = newGeoId;
|
||||
newConstr->FirstPos = start;
|
||||
newConstr->Second = GeoId2;
|
||||
|
||||
if (constrType2 == Sketcher::Coincident) {
|
||||
newConstr->SecondPos = secondPos2;
|
||||
delConstraintOnPoint(GeoId2, secondPos2, false);
|
||||
}
|
||||
|
||||
addConstraint(newConstr);
|
||||
|
||||
newConstr->Type = Sketcher::Coincident;
|
||||
newConstr->First = GeoId;
|
||||
newConstr->FirstPos = Sketcher::mid;
|
||||
newConstr->Second = newGeoId;
|
||||
newConstr->SecondPos = Sketcher::mid;
|
||||
addConstraint(newConstr);
|
||||
|
||||
delete newConstr;
|
||||
|
||||
return 0;
|
||||
} else
|
||||
return -1;
|
||||
} else if (theta1 < 0.001*arcLength) { // drop the second intersection point
|
||||
std::swap(GeoId1,GeoId2);
|
||||
std::swap(point1,point2);
|
||||
} else if (theta2 > 0.999*arcLength) {
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (GeoId1 >= 0) {
|
||||
|
||||
ConstraintType constrType = Sketcher::PointOnObject;
|
||||
PointPos secondPos = Sketcher::none;
|
||||
for (std::vector<Constraint *>::const_iterator it=constraints.begin();
|
||||
it != constraints.end(); ++it) {
|
||||
Constraint *constr = *(it);
|
||||
if ((constr->First == GeoId1 && constr->Second == GeoId)) {
|
||||
constrType = Sketcher::Coincident;
|
||||
secondPos = constr->FirstPos;
|
||||
delConstraintOnPoint(GeoId1, constr->FirstPos, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double theta1 = Base::fmod(
|
||||
atan2(-aoe->getMajorRadius()*((point1.x-center.x)*sin(aoe->getAngleXU())-(point1.y-center.y)*cos(aoe->getAngleXU())),
|
||||
aoe->getMinorRadius()*((point1.x-center.x)*cos(aoe->getAngleXU())+(point1.y-center.y)*sin(aoe->getAngleXU()))
|
||||
)- startAngle, 2.f*M_PI) * dir; // x1
|
||||
|
||||
if (theta1 >= 0.001*arcLength && theta1 <= 0.999*arcLength) {
|
||||
if (theta1 > theta0) { // trim arc start
|
||||
delConstraintOnPoint(GeoId, start, false);
|
||||
Part::GeomArcOfEllipse *aoe1 = dynamic_cast<Part::GeomArcOfEllipse*>(geomlist[GeoId]);
|
||||
aoe1->setRange(startAngle + theta1, endAngle);
|
||||
// constrain the trimming point on the corresponding geometry
|
||||
Sketcher::Constraint *newConstr = new Sketcher::Constraint();
|
||||
newConstr->Type = constrType;
|
||||
newConstr->First = GeoId;
|
||||
newConstr->FirstPos = start;
|
||||
newConstr->Second = GeoId1;
|
||||
|
||||
if (constrType == Sketcher::Coincident)
|
||||
newConstr->SecondPos = secondPos;
|
||||
|
||||
addConstraint(newConstr);
|
||||
delete newConstr;
|
||||
return 0;
|
||||
}
|
||||
else { // trim arc end
|
||||
delConstraintOnPoint(GeoId, end, false);
|
||||
Part::GeomArcOfEllipse *aoe1 = dynamic_cast<Part::GeomArcOfEllipse*>(geomlist[GeoId]);
|
||||
aoe1->setRange(startAngle, startAngle + theta1);
|
||||
Sketcher::Constraint *newConstr = new Sketcher::Constraint();
|
||||
newConstr->Type = constrType;
|
||||
newConstr->First = GeoId;
|
||||
newConstr->FirstPos = end;
|
||||
newConstr->Second = GeoId1;
|
||||
|
||||
if (constrType == Sketcher::Coincident)
|
||||
newConstr->SecondPos = secondPos;
|
||||
|
||||
|
@ -1438,6 +1697,35 @@ void SketchObject::rebuildExternalGeometry(void)
|
|||
ExternalGeo.push_back(arc);
|
||||
}
|
||||
}
|
||||
else if (projCurve.GetType() == GeomAbs_Ellipse) {
|
||||
gp_Elips e = projCurve.Ellipse();
|
||||
gp_Pnt p = e.Location();
|
||||
gp_Pnt P1 = projCurve.Value(projCurve.FirstParameter());
|
||||
gp_Pnt P2 = projCurve.Value(projCurve.LastParameter());
|
||||
|
||||
gp_Dir normal = e.Axis().Direction();
|
||||
gp_Dir xdir = e.XAxis().Direction();
|
||||
gp_Ax2 xdirref(p, normal);
|
||||
|
||||
if (P1.SquareDistance(P2) < Precision::Confusion()) {
|
||||
Part::GeomEllipse* ellipse = new Part::GeomEllipse();
|
||||
ellipse->setMajorRadius(e.MajorRadius());
|
||||
ellipse->setMinorRadius(e.MinorRadius());
|
||||
ellipse->setCenter(Base::Vector3d(p.X(),p.Y(),p.Z()));
|
||||
ellipse->setAngleXU(-xdir.AngleWithRef(xdirref.XDirection(),normal));
|
||||
ellipse->Construction = true;
|
||||
ExternalGeo.push_back(ellipse);
|
||||
}
|
||||
else {
|
||||
Part::GeomArcOfEllipse* aoe = new Part::GeomArcOfEllipse();
|
||||
Handle_Geom_Curve curve = new Geom_Ellipse(e);
|
||||
Handle_Geom_TrimmedCurve tCurve = new Geom_TrimmedCurve(curve, projCurve.FirstParameter(),
|
||||
projCurve.LastParameter());
|
||||
aoe->setHandle(tCurve);
|
||||
aoe->Construction = true;
|
||||
ExternalGeo.push_back(aoe);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw Base::Exception("Not yet supported geometry for external geometry");
|
||||
}
|
||||
|
|
|
@ -1792,7 +1792,7 @@ double ConstraintInternalAlignmentPoint2Ellipse::grad(double *param)
|
|||
}
|
||||
|
||||
// ConstraintEqualMajorAxesEllipse
|
||||
ConstraintEqualMajorAxesEllipse:: ConstraintEqualMajorAxesEllipse(Ellipse &e1, Ellipse &e2)
|
||||
ConstraintEqualMajorAxesEllipse:: ConstraintEqualMajorAxesEllipse(Ellipse &e1, Ellipse &e2)
|
||||
{
|
||||
pvec.push_back(e1.center.x);
|
||||
pvec.push_back(e1.center.y);
|
||||
|
@ -1808,6 +1808,38 @@ double ConstraintInternalAlignmentPoint2Ellipse::grad(double *param)
|
|||
rescale();
|
||||
}
|
||||
|
||||
ConstraintEqualMajorAxesEllipse:: ConstraintEqualMajorAxesEllipse(ArcOfEllipse &a1, Ellipse &e2)
|
||||
{
|
||||
pvec.push_back(a1.center.x);
|
||||
pvec.push_back(a1.center.y);
|
||||
pvec.push_back(a1.focus1X);
|
||||
pvec.push_back(a1.focus1Y);
|
||||
pvec.push_back(a1.radmin);
|
||||
pvec.push_back(e2.center.x);
|
||||
pvec.push_back(e2.center.y);
|
||||
pvec.push_back(e2.focus1X);
|
||||
pvec.push_back(e2.focus1Y);
|
||||
pvec.push_back(e2.radmin);
|
||||
origpvec = pvec;
|
||||
rescale();
|
||||
}
|
||||
|
||||
ConstraintEqualMajorAxesEllipse:: ConstraintEqualMajorAxesEllipse(ArcOfEllipse &a1, ArcOfEllipse &a2)
|
||||
{
|
||||
pvec.push_back(a1.center.x);
|
||||
pvec.push_back(a1.center.y);
|
||||
pvec.push_back(a1.focus1X);
|
||||
pvec.push_back(a1.focus1Y);
|
||||
pvec.push_back(a1.radmin);
|
||||
pvec.push_back(a2.center.x);
|
||||
pvec.push_back(a2.center.y);
|
||||
pvec.push_back(a2.focus1X);
|
||||
pvec.push_back(a2.focus1Y);
|
||||
pvec.push_back(a2.radmin);
|
||||
origpvec = pvec;
|
||||
rescale();
|
||||
}
|
||||
|
||||
ConstraintType ConstraintEqualMajorAxesEllipse::getTypeId()
|
||||
{
|
||||
return EqualMajorAxesEllipse;
|
||||
|
|
|
@ -400,6 +400,8 @@ namespace GCS
|
|||
inline double* e2rmin() { return pvec[9]; }
|
||||
public:
|
||||
ConstraintEqualMajorAxesEllipse(Ellipse &e1, Ellipse &e2);
|
||||
ConstraintEqualMajorAxesEllipse(ArcOfEllipse &a1, Ellipse &e2);
|
||||
ConstraintEqualMajorAxesEllipse(ArcOfEllipse &a1, ArcOfEllipse &a2);
|
||||
virtual ConstraintType getTypeId();
|
||||
virtual void rescale(double coef=1.);
|
||||
virtual double error();
|
||||
|
|
|
@ -798,6 +798,24 @@ int System::addConstraintEqualRadii(Ellipse &e1, Ellipse &e2, int tagId)
|
|||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintEqualRadii(ArcOfEllipse &a1, ArcOfEllipse &a2, int tagId)
|
||||
{
|
||||
addConstraintEqual(a1.radmin, a2.radmin, tagId);
|
||||
|
||||
Constraint *constr = new ConstraintEqualMajorAxesEllipse(a1,a2);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintEqualRadii(ArcOfEllipse &a1, Ellipse &e2, int tagId)
|
||||
{
|
||||
addConstraintEqual(a1.radmin, e2.radmin, tagId);
|
||||
|
||||
Constraint *constr = new ConstraintEqualMajorAxesEllipse(a1,e2);
|
||||
constr->setTag(tagId);
|
||||
return addConstraint(constr);
|
||||
}
|
||||
|
||||
int System::addConstraintEqualRadius(Circle &c1, Arc &a2, int tagId)
|
||||
{
|
||||
return addConstraintEqual(c1.rad, a2.rad, tagId);
|
||||
|
@ -828,71 +846,81 @@ int System::addConstraintInternalAlignmentPoint2Ellipse(Ellipse &e, Point &p1, I
|
|||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseMajorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId)
|
||||
{
|
||||
//chechk which of the points is closer to satisfying positivemajor
|
||||
double err1=0.0, err2=0.0;
|
||||
{
|
||||
ConstraintInternalAlignmentPoint2Ellipse constr (e,p1,EllipsePositiveMajorX);
|
||||
err1+=abs(constr.error());
|
||||
};
|
||||
{
|
||||
ConstraintInternalAlignmentPoint2Ellipse constr (e,p1,EllipsePositiveMajorY);
|
||||
err1+=abs(constr.error());
|
||||
};
|
||||
{
|
||||
ConstraintInternalAlignmentPoint2Ellipse constr (e,p2,EllipsePositiveMajorX);
|
||||
err2+=abs(constr.error());
|
||||
};
|
||||
{
|
||||
ConstraintInternalAlignmentPoint2Ellipse constr (e,p2,EllipsePositiveMajorY);
|
||||
err2+=abs(constr.error());
|
||||
};
|
||||
if(err1<=err2){
|
||||
{
|
||||
double X_1=*p1.x;
|
||||
double Y_1=*p1.y;
|
||||
double X_2=*p2.x;
|
||||
double Y_2=*p2.y;
|
||||
double X_c=*e.center.x;
|
||||
double Y_c=*e.center.y;
|
||||
double X_F1=*e.focus1X;
|
||||
double Y_F1=*e.focus1Y;
|
||||
double b=*e.radmin;
|
||||
|
||||
// P1=vector([X_1,Y_1])
|
||||
// P2=vector([X_2,Y_2])
|
||||
// dF1= (F1-C)/sqrt((F1-C)*(F1-C))
|
||||
// print "these are the extreme points of the major axis"
|
||||
// PA = C + a * dF1
|
||||
// PN = C - a * dF1
|
||||
// print "this is a simple function to know which point is closer to the positive edge of the ellipse"
|
||||
// DMC=(P1-PA)*(P1-PA)-(P2-PA)*(P2-PA)
|
||||
double closertopositivemajor=pow(X_1 - X_c - (X_F1 - X_c)*sqrt(pow(b, 2) + pow(X_F1 - X_c,
|
||||
2) + pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)),
|
||||
2) - pow(X_2 - X_c - (X_F1 - X_c)*sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) +
|
||||
pow(Y_1 - Y_c - (Y_F1 - Y_c)*sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) -
|
||||
pow(Y_2 - Y_c - (Y_F1 - Y_c)*sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2);
|
||||
|
||||
if(closertopositivemajor>0){
|
||||
//p2 is closer to positivemajor. Assign constraints back-to-front.
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipsePositiveMajorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipsePositiveMajorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseNegativeMajorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseNegativeMajorY,tagId);
|
||||
}
|
||||
else{
|
||||
//p1 is closer to positivemajor
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMajorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMajorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMajorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMajorY,tagId);
|
||||
} else {
|
||||
//p2 is closer to positivemajor. Assign constraints back-to-front.
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipsePositiveMajorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipsePositiveMajorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseNegativeMajorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseNegativeMajorY,tagId);
|
||||
}
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseMinorDiameter(Ellipse &e, Point &p1, Point &p2, int tagId)
|
||||
{
|
||||
//chechk which of the points is closer to satisfying positivemajor
|
||||
double err1=0.0, err2=0.0;
|
||||
{
|
||||
ConstraintInternalAlignmentPoint2Ellipse constr (e,p1,EllipsePositiveMinorX);
|
||||
err1+=abs(constr.error());
|
||||
};
|
||||
{
|
||||
ConstraintInternalAlignmentPoint2Ellipse constr (e,p1,EllipsePositiveMinorY);
|
||||
err1+=abs(constr.error());
|
||||
};
|
||||
{
|
||||
ConstraintInternalAlignmentPoint2Ellipse constr (e,p2,EllipsePositiveMinorX);
|
||||
err2+=abs(constr.error());
|
||||
};
|
||||
{
|
||||
ConstraintInternalAlignmentPoint2Ellipse constr (e,p2,EllipsePositiveMinorY);
|
||||
err2+=abs(constr.error());
|
||||
};
|
||||
if(err1<=err2){
|
||||
double X_1=*p1.x;
|
||||
double Y_1=*p1.y;
|
||||
double X_2=*p2.x;
|
||||
double Y_2=*p2.y;
|
||||
double X_c=*e.center.x;
|
||||
double Y_c=*e.center.y;
|
||||
double X_F1=*e.focus1X;
|
||||
double Y_F1=*e.focus1Y;
|
||||
double b=*e.radmin;
|
||||
|
||||
// Same idea as for major above, but for minor
|
||||
// DMC=(P1-PA)*(P1-PA)-(P2-PA)*(P2-PA)
|
||||
double closertopositiveminor= pow(X_1 - X_c + b*(Y_F1 - Y_c)/sqrt(pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2)), 2) - pow(X_2 - X_c + b*(Y_F1 - Y_c)/sqrt(pow(X_F1 -
|
||||
X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) + pow(-Y_1 + Y_c + b*(X_F1 -
|
||||
X_c)/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) - pow(-Y_2 + Y_c
|
||||
+ b*(X_F1 - X_c)/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2);
|
||||
|
||||
if(closertopositiveminor>0){
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipsePositiveMinorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipsePositiveMinorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseNegativeMinorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseNegativeMinorY,tagId);
|
||||
} else {
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMinorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipsePositiveMinorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMinorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipseNegativeMinorY,tagId);
|
||||
} else {
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipsePositiveMinorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p2,EllipsePositiveMinorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseNegativeMinorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(e,p1,EllipseNegativeMinorY,tagId);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
int System::addConstraintInternalAlignmentEllipseFocus1(Ellipse &e, Point &p1, int tagId)
|
||||
|
@ -916,18 +944,80 @@ int System::addConstraintInternalAlignmentPoint2Ellipse(ArcOfEllipse &a, Point &
|
|||
|
||||
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);
|
||||
double X_1=*p1.x;
|
||||
double Y_1=*p1.y;
|
||||
double X_2=*p2.x;
|
||||
double Y_2=*p2.y;
|
||||
double X_c=*a.center.x;
|
||||
double Y_c=*a.center.y;
|
||||
double X_F1=*a.focus1X;
|
||||
double Y_F1=*a.focus1Y;
|
||||
double b=*a.radmin;
|
||||
|
||||
// P1=vector([X_1,Y_1])
|
||||
// P2=vector([X_2,Y_2])
|
||||
// dF1= (F1-C)/sqrt((F1-C)*(F1-C))
|
||||
// print "these are the extreme points of the major axis"
|
||||
// PA = C + a * dF1
|
||||
// PN = C - a * dF1
|
||||
// print "this is a simple function to know which point is closer to the positive edge of the ellipse"
|
||||
// DMC=(P1-PA)*(P1-PA)-(P2-PA)*(P2-PA)
|
||||
double closertopositivemajor=pow(X_1 - X_c - (X_F1 - X_c)*sqrt(pow(b, 2) + pow(X_F1 - X_c,
|
||||
2) + pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)),
|
||||
2) - pow(X_2 - X_c - (X_F1 - X_c)*sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) +
|
||||
pow(Y_1 - Y_c - (Y_F1 - Y_c)*sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) -
|
||||
pow(Y_2 - Y_c - (Y_F1 - Y_c)*sqrt(pow(b, 2) + pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2))/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2);
|
||||
|
||||
if(closertopositivemajor>0){
|
||||
//p2 is closer to positivemajor. Assign constraints back-to-front.
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipsePositiveMajorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipsePositiveMajorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipseNegativeMajorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipseNegativeMajorY,tagId);
|
||||
}
|
||||
else{
|
||||
//p1 is closer to positivemajor
|
||||
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);
|
||||
double X_1=*p1.x;
|
||||
double Y_1=*p1.y;
|
||||
double X_2=*p2.x;
|
||||
double Y_2=*p2.y;
|
||||
double X_c=*a.center.x;
|
||||
double Y_c=*a.center.y;
|
||||
double X_F1=*a.focus1X;
|
||||
double Y_F1=*a.focus1Y;
|
||||
double b=*a.radmin;
|
||||
|
||||
// Same idea as for major above, but for minor
|
||||
// DMC=(P1-PA)*(P1-PA)-(P2-PA)*(P2-PA)
|
||||
double closertopositiveminor= pow(X_1 - X_c + b*(Y_F1 - Y_c)/sqrt(pow(X_F1 - X_c, 2) +
|
||||
pow(Y_F1 - Y_c, 2)), 2) - pow(X_2 - X_c + b*(Y_F1 - Y_c)/sqrt(pow(X_F1 -
|
||||
X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) + pow(-Y_1 + Y_c + b*(X_F1 -
|
||||
X_c)/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2) - pow(-Y_2 + Y_c
|
||||
+ b*(X_F1 - X_c)/sqrt(pow(X_F1 - X_c, 2) + pow(Y_F1 - Y_c, 2)), 2);
|
||||
|
||||
if(closertopositiveminor>0){
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipsePositiveMinorX,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p2,EllipsePositiveMinorY,tagId);
|
||||
addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipseNegativeMinorX,tagId);
|
||||
return addConstraintInternalAlignmentPoint2Ellipse(a,p1,EllipseNegativeMinorY,tagId);
|
||||
} else {
|
||||
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)
|
||||
|
@ -1749,7 +1839,7 @@ int System::diagnose()
|
|||
Eigen::MatrixXd Q = qrJT.matrixQ ();
|
||||
int paramsNum = qrJT.rows();
|
||||
int constrNum = qrJT.cols();
|
||||
qrJT.setThreshold(1e-10);
|
||||
qrJT.setThreshold(1e-13);
|
||||
int rank = qrJT.rank();
|
||||
|
||||
Eigen::MatrixXd R;
|
||||
|
|
|
@ -165,6 +165,8 @@ namespace GCS
|
|||
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 addConstraintEqualRadii(ArcOfEllipse &a1, ArcOfEllipse &a2, int tagId=0);
|
||||
int addConstraintEqualRadii(ArcOfEllipse &a1, 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);
|
||||
|
|
|
@ -1314,6 +1314,97 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg)
|
|||
QObject::tr("One of the selected edges should be a line."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId())
|
||||
std::swap(GeoId1,GeoId2);
|
||||
|
||||
// GeoId2 is the line
|
||||
geo1 = Obj->getGeometry(GeoId1);
|
||||
geo2 = Obj->getGeometry(GeoId2);
|
||||
|
||||
if( geo1->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
|
||||
geo1->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ) {
|
||||
|
||||
Base::Vector3d center;
|
||||
double majord;
|
||||
double minord;
|
||||
double phi;
|
||||
|
||||
if( geo1->getTypeId() == Part::GeomEllipse::getClassTypeId() ){
|
||||
const Part::GeomEllipse *ellipse = static_cast<const Part::GeomEllipse *>(geo1);
|
||||
|
||||
center=ellipse->getCenter();
|
||||
majord=ellipse->getMajorRadius();
|
||||
minord=ellipse->getMinorRadius();
|
||||
phi=ellipse->getAngleXU();
|
||||
} else
|
||||
if( geo1->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ){
|
||||
const Part::GeomArcOfEllipse *aoe = static_cast<const Part::GeomArcOfEllipse *>(geo1);
|
||||
|
||||
center=aoe->getCenter();
|
||||
majord=aoe->getMajorRadius();
|
||||
minord=aoe->getMinorRadius();
|
||||
phi=aoe->getAngleXU();
|
||||
}
|
||||
|
||||
const Part::GeomLineSegment *line = static_cast<const Part::GeomLineSegment *>(geo2);
|
||||
|
||||
Base::Vector3d point1=line->getStartPoint();
|
||||
Base::Vector3d point2=line->getEndPoint();
|
||||
|
||||
Base::Vector3d direction=point1-center;
|
||||
double tapprox=atan2(direction.y,direction.x)-phi; // we approximate the eccentric anomally by the polar
|
||||
|
||||
Base::Vector3d PoE = Base::Vector3d(center.x+majord*cos(tapprox)*cos(phi)-minord*sin(tapprox)*sin(phi),
|
||||
center.y+majord*cos(tapprox)*sin(phi)+minord*sin(tapprox)*cos(phi), 0);
|
||||
|
||||
Base::Vector3d perp = Base::Vector3d(direction.y,-direction.x);
|
||||
|
||||
Base::Vector3d endpoint = PoE+perp;
|
||||
|
||||
int currentgeoid= Obj->getHighestCurveIndex();
|
||||
|
||||
openCommand("add perpendicular constraint");
|
||||
|
||||
try {
|
||||
|
||||
// Add a construction line
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
|
||||
selection[0].getFeatName(),
|
||||
PoE.x,PoE.y,endpoint.x,endpoint.y);
|
||||
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",Obj->getNameInDocument(),currentgeoid+1);
|
||||
|
||||
// Point on first object (ellipse, arc of ellipse)
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,Sketcher::start,GeoId1);
|
||||
// construction line tangent to ellipse/arcofellipse
|
||||
Gui::Command::doCommand(
|
||||
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,GeoId1);
|
||||
// Point on second object
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,Sketcher::start,GeoId2);
|
||||
|
||||
// line perpendicular to construction line
|
||||
Gui::Command::doCommand(
|
||||
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Perpendicular',%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,GeoId2);
|
||||
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::updateActive();
|
||||
return;
|
||||
}
|
||||
|
||||
commitCommand();
|
||||
updateActive();
|
||||
getSelection().clearSelection();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
openCommand("add perpendicular constraint");
|
||||
Gui::Command::doCommand(
|
||||
|
@ -1423,6 +1514,188 @@ void CmdSketcherConstrainTangent::activated(int iMsg)
|
|||
}
|
||||
else if (isEdge(GeoId1,PosId1) && isEdge(GeoId2,PosId2)) { // simple tangency between GeoId1 and GeoId2
|
||||
|
||||
const Part::Geometry *geom1 = Obj->getGeometry(GeoId1);
|
||||
const Part::Geometry *geom2 = Obj->getGeometry(GeoId2);
|
||||
|
||||
if( geom1 && geom2 &&
|
||||
( geom1->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
|
||||
geom2->getTypeId() == Part::GeomEllipse::getClassTypeId() )){
|
||||
|
||||
if(geom1->getTypeId() != Part::GeomEllipse::getClassTypeId())
|
||||
std::swap(GeoId1,GeoId2);
|
||||
|
||||
// GeoId1 is the ellipse
|
||||
geom1 = Obj->getGeometry(GeoId1);
|
||||
geom2 = Obj->getGeometry(GeoId2);
|
||||
|
||||
if( geom2->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
|
||||
geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
|
||||
geom2->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ) {
|
||||
|
||||
const Part::GeomEllipse *ellipse = static_cast<const Part::GeomEllipse *>(geom1);
|
||||
|
||||
Base::Vector3d center=ellipse->getCenter();
|
||||
double majord=ellipse->getMajorRadius();
|
||||
double minord=ellipse->getMinorRadius();
|
||||
double phi=ellipse->getAngleXU();
|
||||
|
||||
Base::Vector3d center2;
|
||||
|
||||
if( geom2->getTypeId() == Part::GeomEllipse::getClassTypeId() )
|
||||
center2= (static_cast<const Part::GeomEllipse *>(geom2))->getCenter();
|
||||
else if( geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId())
|
||||
center2= (static_cast<const Part::GeomArcOfEllipse *>(geom2))->getCenter();
|
||||
else if( geom2->getTypeId() == Part::GeomCircle::getClassTypeId())
|
||||
center2= (static_cast<const Part::GeomCircle *>(geom2))->getCenter();
|
||||
else if( geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
|
||||
center2= (static_cast<const Part::GeomArcOfCircle *>(geom2))->getCenter();
|
||||
|
||||
Base::Vector3d direction=center2-center;
|
||||
double tapprox=atan2(direction.y,direction.x)-phi; // we approximate the eccentric anomally by the polar
|
||||
|
||||
Base::Vector3d PoE = Base::Vector3d(center.x+majord*cos(tapprox)*cos(phi)-minord*sin(tapprox)*sin(phi),
|
||||
center.y+majord*cos(tapprox)*sin(phi)+minord*sin(tapprox)*cos(phi), 0);
|
||||
|
||||
Base::Vector3d perp = Base::Vector3d(direction.y,-direction.x);
|
||||
|
||||
Base::Vector3d endpoint = PoE+perp;
|
||||
|
||||
int currentgeoid= Obj->getHighestCurveIndex();
|
||||
|
||||
openCommand("add tangent constraint");
|
||||
|
||||
try {
|
||||
//construct the point
|
||||
/*Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Point(App.Vector(%f,%f,0)))",
|
||||
Obj->getNameInDocument(),
|
||||
PoE.x,PoE.y);*/
|
||||
|
||||
// Add a construction line
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
|
||||
selection[0].getFeatName(),
|
||||
PoE.x,PoE.y,endpoint.x,endpoint.y); // create line for major axis
|
||||
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",Obj->getNameInDocument(),currentgeoid+1);
|
||||
|
||||
// Point on first object
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,Sketcher::start,GeoId1); // constrain major axis
|
||||
// Point on second object
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,Sketcher::start,GeoId2); // constrain major axis
|
||||
// tangent to first object
|
||||
Gui::Command::doCommand(
|
||||
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,GeoId1);
|
||||
// tangent to second object
|
||||
Gui::Command::doCommand(
|
||||
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,GeoId2);
|
||||
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::updateActive();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
commitCommand();
|
||||
updateActive();
|
||||
getSelection().clearSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( geom1 && geom2 &&
|
||||
( geom1->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
|
||||
geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() )){
|
||||
|
||||
if(geom1->getTypeId() != Part::GeomArcOfEllipse::getClassTypeId())
|
||||
std::swap(GeoId1,GeoId2);
|
||||
|
||||
// GeoId1 is the arc of ellipse
|
||||
geom1 = Obj->getGeometry(GeoId1);
|
||||
geom2 = Obj->getGeometry(GeoId2);
|
||||
|
||||
if( geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
|
||||
geom2->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ) {
|
||||
|
||||
const Part::GeomArcOfEllipse *aoe = static_cast<const Part::GeomArcOfEllipse *>(geom1);
|
||||
|
||||
Base::Vector3d center=aoe->getCenter();
|
||||
double majord=aoe->getMajorRadius();
|
||||
double minord=aoe->getMinorRadius();
|
||||
double phi=aoe->getAngleXU();
|
||||
|
||||
Base::Vector3d center2;
|
||||
|
||||
if( geom2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId())
|
||||
center2= (static_cast<const Part::GeomArcOfEllipse *>(geom2))->getCenter();
|
||||
else if( geom2->getTypeId() == Part::GeomCircle::getClassTypeId())
|
||||
center2= (static_cast<const Part::GeomCircle *>(geom2))->getCenter();
|
||||
else if( geom2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
|
||||
center2= (static_cast<const Part::GeomArcOfCircle *>(geom2))->getCenter();
|
||||
|
||||
Base::Vector3d direction=center2-center;
|
||||
double tapprox=atan2(direction.y,direction.x)-phi; // we approximate the eccentric anomally by the polar
|
||||
|
||||
Base::Vector3d PoE = Base::Vector3d(center.x+majord*cos(tapprox)*cos(phi)-minord*sin(tapprox)*sin(phi),
|
||||
center.y+majord*cos(tapprox)*sin(phi)+minord*sin(tapprox)*cos(phi), 0);
|
||||
|
||||
Base::Vector3d perp = Base::Vector3d(direction.y,-direction.x);
|
||||
|
||||
Base::Vector3d endpoint = PoE+perp;
|
||||
|
||||
int currentgeoid= Obj->getHighestCurveIndex();
|
||||
|
||||
openCommand("add tangent constraint");
|
||||
|
||||
try {
|
||||
|
||||
// Add a construction line
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.addGeometry(Part.Line(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))",
|
||||
selection[0].getFeatName(),
|
||||
PoE.x,PoE.y,endpoint.x,endpoint.y); // create line for major axis
|
||||
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.toggleConstruction(%d) ",Obj->getNameInDocument(),currentgeoid+1);
|
||||
|
||||
// Point on first object
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,Sketcher::start,GeoId1); // constrain major axis
|
||||
// Point on second object
|
||||
Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,Sketcher::start,GeoId2); // constrain major axis
|
||||
// tangent to first object
|
||||
Gui::Command::doCommand(
|
||||
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,GeoId1);
|
||||
// tangent to second object
|
||||
Gui::Command::doCommand(
|
||||
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d)) ",
|
||||
selection[0].getFeatName(),currentgeoid+1,GeoId2);
|
||||
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::updateActive();
|
||||
return;
|
||||
}
|
||||
|
||||
commitCommand();
|
||||
updateActive();
|
||||
getSelection().clearSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
openCommand("add tangent constraint");
|
||||
Gui::Command::doCommand(
|
||||
Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Tangent',%d,%d)) ",
|
||||
|
@ -1806,7 +2079,7 @@ void CmdSketcherConstrainEqual::activated(int iMsg)
|
|||
}
|
||||
|
||||
std::vector<int> ids;
|
||||
bool lineSel = false, arcSel = false, circSel = false, hasAlreadyExternal = false;
|
||||
bool lineSel = false, arcSel = false, circSel = false, ellipsSel = false, arcEllipsSel=false, hasAlreadyExternal = false;
|
||||
|
||||
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
|
||||
|
||||
|
@ -1838,8 +2111,12 @@ void CmdSketcherConstrainEqual::activated(int iMsg)
|
|||
lineSel = true;
|
||||
else if (geo->getTypeId() != Part::GeomArcOfCircle::getClassTypeId())
|
||||
arcSel = true;
|
||||
else if (geo->getTypeId() != Part::GeomCircle::getClassTypeId()) // TODO: ellipse
|
||||
else if (geo->getTypeId() != Part::GeomCircle::getClassTypeId())
|
||||
circSel = true;
|
||||
else if (geo->getTypeId() != Part::GeomEllipse::getClassTypeId()) // TODO: ellipse
|
||||
ellipsSel = true;
|
||||
else if (geo->getTypeId() != Part::GeomArcOfEllipse::getClassTypeId()) // TODO: ellipse
|
||||
arcEllipsSel = true;
|
||||
else {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select two or more edges of similar type"));
|
||||
|
@ -1849,7 +2126,7 @@ void CmdSketcherConstrainEqual::activated(int iMsg)
|
|||
ids.push_back(GeoId);
|
||||
}
|
||||
|
||||
if (lineSel && (arcSel || circSel)) {
|
||||
if (lineSel && (arcSel || circSel) && (ellipsSel || arcEllipsSel)) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select two or more edges of similar type"));
|
||||
return;
|
||||
|
|
|
@ -1887,13 +1887,10 @@ public:
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (Mode==STATUS_SEEK_Third) {
|
||||
double rx0 = EditCurve[1].fX - EditCurve[0].fX; // first semidiameter
|
||||
double ry0 = EditCurve[1].fY - EditCurve[0].fY; // first semidiameter
|
||||
|
||||
else if (Mode==STATUS_SEEK_Third) {
|
||||
// angle between the major axis of the ellipse and the X axis
|
||||
double a = (EditCurve[1]-EditCurve[0]).Length();
|
||||
double phi = atan2f(EditCurve[1].fY-EditCurve[0].fY,EditCurve[1].fX-EditCurve[0].fX);
|
||||
double phi = atan2(EditCurve[1].fY-EditCurve[0].fY,EditCurve[1].fX-EditCurve[0].fX);
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatpoint = acos((onSketchPos.fX-EditCurve[0].fX+(onSketchPos.fY-EditCurve[0].fY)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
|
||||
|
@ -1915,9 +1912,9 @@ public:
|
|||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2D(0.f,0.f),
|
||||
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2D(0.f,0.f),
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
renderSuggestConstraintsCursor(sugConstr3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1949,11 +1946,11 @@ public:
|
|||
|
||||
// angle between the major axis of the ellipse and the X axis
|
||||
double a = (EditCurve[1]-EditCurve[0]).Length();
|
||||
double phi = atan2f(EditCurve[1].fY-EditCurve[0].fY,EditCurve[1].fX-EditCurve[0].fX);
|
||||
double phi = atan2(EditCurve[1].fY-EditCurve[0].fY,EditCurve[1].fX-EditCurve[0].fX);
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatpoint = acos((EditCurve[2].fX-EditCurve[0].fX+(EditCurve[2].fY-EditCurve[0].fY)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
|
||||
double b=(EditCurve[2].fY-EditCurve[0].fY-a*cos(angleatpoint)*sin(phi))/(sin(angleatpoint)*cos(phi));
|
||||
double b=abs((EditCurve[2].fY-EditCurve[0].fY-a*cos(angleatpoint)*sin(phi))/(sin(angleatpoint)*cos(phi)));
|
||||
|
||||
Base::Vector2D majAxisDir,minAxisDir,minAxisPoint,majAxisPoint;
|
||||
// We always create a CCW ellipse, because we want our XY reference system to be in the +X +Y direction
|
||||
|
@ -2012,7 +2009,7 @@ public:
|
|||
protected:
|
||||
SelectMode Mode;
|
||||
std::vector<Base::Vector2D> EditCurve;
|
||||
std::vector<AutoConstraint> sugConstr1, sugConstr2;
|
||||
std::vector<AutoConstraint> sugConstr1, sugConstr2, sugConstr3;
|
||||
|
||||
};
|
||||
|
||||
|
@ -2136,13 +2133,10 @@ public:
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (Mode==STATUS_SEEK_Third) {
|
||||
double rx0 = EditCurve[1].fX - EditCurve[0].fX; // first semidiameter
|
||||
double ry0 = EditCurve[1].fY - EditCurve[0].fY; // first semidiameter
|
||||
|
||||
else if (Mode==STATUS_SEEK_Third) {
|
||||
// angle between the major axis of the ellipse and the X axis
|
||||
double a = (EditCurve[1]-EditCurve[0]).Length();
|
||||
double phi = atan2f(EditCurve[1].fY-EditCurve[0].fY,EditCurve[1].fX-EditCurve[0].fX);
|
||||
double phi = atan2(EditCurve[1].fY-EditCurve[0].fY,EditCurve[1].fX-EditCurve[0].fX);
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatpoint = acos((onSketchPos.fX-EditCurve[0].fX+(onSketchPos.fY-EditCurve[0].fY)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
|
||||
|
@ -2172,9 +2166,6 @@ public:
|
|||
}
|
||||
else if (Mode==STATUS_SEEK_Fourth) { // here we differ from ellipse creation
|
||||
|
||||
double rx0 = axisPoint.fX - centerPoint.fX; // first semidiameter
|
||||
double ry0 = axisPoint.fY - centerPoint.fY; // first semidiameter
|
||||
|
||||
// angle between the major axis of the ellipse and the X axis
|
||||
double a = (axisPoint-centerPoint).Length();
|
||||
double phi = atan2(axisPoint.fY-centerPoint.fY,axisPoint.fX-centerPoint.fX);
|
||||
|
@ -3119,9 +3110,11 @@ namespace SketcherGui {
|
|||
const Part::Geometry *geom = Sketch->getGeometry(GeoId);
|
||||
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomCircle::getClassTypeId()||
|
||||
geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
|
||||
geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()||
|
||||
geom->getTypeId() == Part::GeomEllipse::getClassTypeId()||
|
||||
geom->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()
|
||||
)
|
||||
return true;
|
||||
// TODO: ellipse
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -3201,9 +3194,9 @@ public:
|
|||
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(GeoId);
|
||||
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomCircle::getClassTypeId()
|
||||
// TODO: ellipse
|
||||
) {
|
||||
geom->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ||
|
||||
geom->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
|
||||
try {
|
||||
Gui::Command::openCommand("Trim edge");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.trim(%d,App.Vector(%f,%f,0))",
|
||||
|
|
|
@ -721,8 +721,14 @@ void CmdSketcherRestoreInternalAlignmentGeometry::activated(int iMsg)
|
|||
// go through the selected subelements
|
||||
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
|
||||
// only handle edges
|
||||
if (it->size() > 4 && it->substr(0,4) == "Edge") {
|
||||
int GeoId = std::atoi(it->substr(4,4000).c_str()) - 1;
|
||||
if ( (it->size() > 4 && it->substr(0,4) == "Edge") ||
|
||||
(it->size() > 12 && it->substr(0,12) == "ExternalEdge")) {
|
||||
int GeoId;
|
||||
if(it->substr(0,4) == "Edge")
|
||||
GeoId = std::atoi(it->substr(4,4000).c_str()) - 1;
|
||||
else
|
||||
GeoId = -std::atoi(it->substr(12,4000).c_str()) - 2;
|
||||
|
||||
const Part::Geometry *geo = Obj->getGeometry(GeoId);
|
||||
// Only for supported types
|
||||
if(geo->getTypeId() == Part::GeomEllipse::getClassTypeId() || geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
|
|
|
@ -200,6 +200,18 @@ void SketcherValidation::on_findButton_clicked()
|
|||
id.v = segm->getEndPoint();
|
||||
vertexIds.push_back(id);
|
||||
}
|
||||
else if (g->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
const Part::GeomArcOfEllipse *segm = dynamic_cast<const Part::GeomArcOfEllipse*>(g);
|
||||
VertexIds id;
|
||||
id.GeoId = (int)i;
|
||||
id.PosId = Sketcher::start;
|
||||
id.v = segm->getStartPoint();
|
||||
vertexIds.push_back(id);
|
||||
id.GeoId = (int)i;
|
||||
id.PosId = Sketcher::end;
|
||||
id.v = segm->getEndPoint();
|
||||
vertexIds.push_back(id);
|
||||
}
|
||||
}
|
||||
|
||||
std::set<ConstraintIds, Constraint_Less> coincidences;
|
||||
|
|
|
@ -2149,6 +2149,34 @@ void ViewProviderSketch::updateColor(void)
|
|||
if (index >= 0 && index < PtNum) pcolor[index] = SelectColor;
|
||||
index = edit->ActSketch.getPointId(constraint->Second, constraint->SecondPos) + 1;
|
||||
if (index >= 0 && index < PtNum) pcolor[index] = SelectColor;
|
||||
} else if (type == Sketcher::InternalAlignment) {
|
||||
switch(constraint->AlignmentType) {
|
||||
case EllipseMajorDiameter:
|
||||
case EllipseMinorDiameter:
|
||||
{
|
||||
// color line
|
||||
int CurvNum = edit->CurvesMaterials->diffuseColor.getNum();
|
||||
for (int i=0; i < CurvNum; i++) {
|
||||
int cGeoId = edit->CurvIdToGeoId[i];
|
||||
|
||||
if(cGeoId == constraint->First) {
|
||||
int indexes=(edit->CurveSet->numVertices[i]);
|
||||
color[i] = SelectColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EllipseFocus1:
|
||||
case EllipseFocus2:
|
||||
{
|
||||
int index = edit->ActSketch.getPointId(constraint->First, constraint->FirstPos) + 1;
|
||||
if (index >= 0 && index < PtNum) pcolor[index] = SelectColor;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (edit->PreselectConstraintSet.count(i)) {
|
||||
if (hasDatumLabel) {
|
||||
|
@ -2208,7 +2236,7 @@ QString ViewProviderSketch::iconTypeFromConstraint(Constraint *constraint)
|
|||
case Equal:
|
||||
return QString::fromAscii("small/Constraint_EqualLength_sm");
|
||||
case Symmetric:
|
||||
return QString::fromAscii("small/Constraint_Symmetric_sm");
|
||||
return QString::fromAscii("small/Constraint_Symmetric_sm");
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
|
@ -3117,10 +3145,18 @@ Restart:
|
|||
r1 = ellipse->getMajorRadius();
|
||||
angle1 = -ellipse->getAngleXU();
|
||||
midpos1 = ellipse->getCenter();
|
||||
} else if (geo1->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
// TODO: ellipse
|
||||
const Part::GeomArcOfEllipse *aoe = dynamic_cast<const Part::GeomArcOfEllipse *>(geo1);
|
||||
r1 = aoe->getMajorRadius();
|
||||
double startangle, endangle;
|
||||
aoe->getRange(startangle, endangle);
|
||||
angle1 = (startangle + endangle)/2-aoe->getAngleXU();
|
||||
midpos1 = aoe->getCenter();
|
||||
} else
|
||||
break;
|
||||
|
||||
if (geo2->getTypeId() == Part::GeomCircle::getClassTypeId()) { // TODO: ellipse
|
||||
if (geo2->getTypeId() == Part::GeomCircle::getClassTypeId()) {
|
||||
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo2);
|
||||
r2 = circle->getRadius();
|
||||
angle2 = M_PI/4;
|
||||
|
@ -3138,6 +3174,14 @@ Restart:
|
|||
r2 = ellipse->getMajorRadius();
|
||||
angle2 = -ellipse->getAngleXU();
|
||||
midpos2 = ellipse->getCenter();
|
||||
} else if (geo2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
|
||||
// TODO: ellipse
|
||||
const Part::GeomArcOfEllipse *aoe = dynamic_cast<const Part::GeomArcOfEllipse *>(geo2);
|
||||
r2 = aoe->getMajorRadius();
|
||||
double startangle, endangle;
|
||||
aoe->getRange(startangle, endangle);
|
||||
angle1 = (startangle + endangle)/2-aoe->getAngleXU();
|
||||
midpos1 = aoe->getCenter();
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue
Block a user