From 5f963c8d02e91a8d68f78027b1ad676e73d07597 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Sat, 17 Dec 2016 22:46:33 +0100 Subject: [PATCH] Sketcher: Parabola Solver Sketch Implementation =============================================== Main Sketch solver parabola addition and update, with exception of the rules of the parabola arc, that will be implemented with the solver constraints. --- src/Mod/Sketcher/App/Sketch.cpp | 151 +++++++++++++++++++++++++++++++- src/Mod/Sketcher/App/Sketch.h | 6 +- 2 files changed, 154 insertions(+), 3 deletions(-) diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp index 4415f2379..f5fafeff5 100644 --- a/src/Mod/Sketcher/App/Sketch.cpp +++ b/src/Mod/Sketcher/App/Sketch.cpp @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include #include @@ -84,6 +86,7 @@ void Sketch::clear(void) Ellipses.clear(); ArcsOfEllipse.clear(); ArcsOfHyperbola.clear(); + ArcsOfParabola.clear(); // deleting the doubles allocated with new for (std::vector::iterator it = Parameters.begin(); it != Parameters.end(); ++it) @@ -177,6 +180,8 @@ const char* nameByType(Sketch::GeoType type) return "arcofellipse"; case Sketch::ArcOfHyperbola: return "arcofhyperbola"; + case Sketch::ArcOfParabola: + return "arcofparabola"; case Sketch::None: default: return "unknown"; @@ -215,7 +220,12 @@ int Sketch::addGeometry(const Part::Geometry *geo, bool fixed) const GeomArcOfHyperbola *aoh = dynamic_cast(geo); // create the definition struct for that geom return addArcOfHyperbola(*aoh, fixed); - } else { + } else if (geo->getTypeId() == GeomArcOfParabola::getClassTypeId()) { // add an arc of parabola + const GeomArcOfParabola *aop = dynamic_cast(geo); + // create the definition struct for that geom + return addArcOfParabola(*aop, fixed); + } + else { throw Base::TypeError("Sketch::addGeometry(): Unknown or unsupported type added to a sketch"); } } @@ -560,6 +570,82 @@ int Sketch::addArcOfHyperbola(const Part::GeomArcOfHyperbola &hyperbolaSegment, return Geoms.size()-1; } +int Sketch::addArcOfParabola(const Part::GeomArcOfParabola ¶bolaSegment, bool fixed) +{ + std::vector ¶ms = fixed ? FixParameters : Parameters; + + // create our own copy + GeomArcOfParabola *aop = static_cast(parabolaSegment.clone()); + // create the definition struct for that geom + GeoDef def; + def.geo = aop; + def.type = ArcOfParabola; + + Base::Vector3d vertex = aop->getCenter(); + Base::Vector3d startPnt = aop->getStartPoint(); + Base::Vector3d endPnt = aop->getEndPoint(); + Base::Vector3d focus = aop->getFocus(); + + double startAngle, endAngle; + aop->getRange(startAngle, endAngle,/*emulateCCW=*/true); + + GCS::Point p1, p2, p3, p4; + + 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(vertex.x)); + params.push_back(new double(vertex.y)); + p3.x = params[params.size()-2]; + p3.y = params[params.size()-1]; + + params.push_back(new double(focus.x)); + params.push_back(new double(focus.y)); + p4.x = params[params.size()-2]; + p4.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); + + // add the radius parameters + 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::ArcOfParabola a; + a.start = p1; + a.end = p2; + a.vertex = p3; + a.focus1 = p4; + a.startAngle = a1; + a.endAngle = a2; + def.index = ArcsOfParabola.size(); + ArcsOfParabola.push_back(a); + + // store complete set + Geoms.push_back(def); + + // arcs require an ArcRules constraint for the end points + //if (!fixed) + // GCSsys.addConstraintArcOfParabolaRules(a); + + // return the position of the newly added geometry + return Geoms.size()-1; +} + int Sketch::addCircle(const Part::GeomCircle &cir, bool fixed) { std::vector ¶ms = fixed ? FixParameters : Parameters; @@ -700,6 +786,9 @@ Py::Tuple Sketch::getPyGeometry(void) const } else if (it->type == ArcOfHyperbola) { GeomArcOfHyperbola *aoh = dynamic_cast(it->geo->clone()); tuple[i] = Py::asObject(new ArcOfHyperbolaPy(aoh)); + } else if (it->type == ArcOfParabola) { + GeomArcOfParabola *aop = dynamic_cast(it->geo->clone()); + tuple[i] = Py::asObject(new ArcOfParabolaPy(aop)); } else { // not implemented type in the sketch! } @@ -737,7 +826,10 @@ GCS::Curve* Sketch::getGCSCurveByGeoId(int geoId) break; case ArcOfHyperbola: return &ArcsOfHyperbola[Geoms[geoId].index]; - break; + break; + case ArcOfParabola: + return &ArcsOfParabola[Geoms[geoId].index]; + break; default: return 0; }; @@ -2300,6 +2392,21 @@ bool Sketch::updateGeometry() } aoh->setMajorAxisDir(fd); aoh->setRange(*myArc.startAngle, *myArc.endAngle, /*emulateCCW=*/true); + } else if (it->type == ArcOfParabola) { + GCS::ArcOfParabola &myArc = ArcsOfParabola[it->index]; + + GeomArcOfParabola *aop = dynamic_cast(it->geo); + + Base::Vector3d vertex = Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0); + Base::Vector3d f1 = Vector3d(*myArc.focus1.x, *myArc.focus1.y, 0.0); + + Base::Vector3d fd=f1-vertex; + + aop->setXAxisDir(fd); + + aop->setCenter(vertex); + + aop->setRange(*myArc.startAngle, *myArc.endAngle, /*emulateCCW=*/true); } } catch (Base::Exception e) { Base::Console().Error("Updating geometry: Error build geometry(%d): %s\n", @@ -2607,6 +2714,41 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine) } else if (Geoms[geoId].type == ArcOfHyperbola) { + GCS::Point ¢er = Points[Geoms[geoId].midPointId]; + GCS::Point p0,p1; + if (pos == mid || pos == none) { + 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) { + + 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); + } + 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 == ArcOfParabola) { + GCS::Point ¢er = Points[Geoms[geoId].midPointId]; GCS::Point p0,p1; if (pos == mid || pos == none) { @@ -2742,6 +2884,11 @@ 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 == ArcOfParabola) { + if (pos == start || pos == end || pos == mid || pos == none) { + MoveParameters[0] = toPoint.x; + MoveParameters[1] = toPoint.y; + } } return solve(); diff --git a/src/Mod/Sketcher/App/Sketch.h b/src/Mod/Sketcher/App/Sketch.h index 185f8085c..0d88fa2ab 100644 --- a/src/Mod/Sketcher/App/Sketch.h +++ b/src/Mod/Sketcher/App/Sketch.h @@ -130,6 +130,8 @@ public: int addArcOfEllipse(const Part::GeomArcOfEllipse &ellipseSegment, bool fixed=false); /// add an arc of hyperbola int addArcOfHyperbola(const Part::GeomArcOfHyperbola &hyperbolaSegment, bool fixed=false); + /// add an arc of parabola + int addArcOfParabola(const Part::GeomArcOfParabola ¶bolaSegment, bool fixed=false); //@} @@ -335,7 +337,8 @@ public: Circle = 4, // 1 Point(mid), 3 Parameters(x,y,r) Ellipse = 5, // 1 Point(mid), 5 Parameters(x,y,r1,r2,phi) phi=angle xaxis of elipse with respect of sketch xaxis ArcOfEllipse = 6, - ArcOfHyperbola = 7 + ArcOfHyperbola = 7, + ArcOfParabola = 8 }; float SolveTime; @@ -383,6 +386,7 @@ protected: std::vector Ellipses; std::vector ArcsOfEllipse; std::vector ArcsOfHyperbola; + std::vector ArcsOfParabola; bool isInitMove; bool isFine;