diff --git a/src/Mod/Sketcher/App/Constraint.h b/src/Mod/Sketcher/App/Constraint.h index 0b15c5c2f0..c995cb0731 100644 --- a/src/Mod/Sketcher/App/Constraint.h +++ b/src/Mod/Sketcher/App/Constraint.h @@ -76,6 +76,7 @@ enum InternalAlignmentType { ParabolaFocus = 8, BSplineControlPoint = 9, BSplineKnotPoint = 10, + ParabolaFocalAxis = 11, NumInternalAlignmentType // must be the last item! }; @@ -144,7 +145,7 @@ private: constexpr static std::array internalAlignmentType2str { { "Undef", "EllipseMajorDiameter", "EllipseMinorDiameter", "EllipseFocus1", "EllipseFocus2", "HyperbolaMajor", "HyperbolaMinor", - "HyperbolaFocus", "ParabolaFocus", "BSplineControlPoint", "BSplineKnotPoint"} + "HyperbolaFocus", "ParabolaFocus", "BSplineControlPoint", "BSplineKnotPoint", "ParabolaFocalAxis"} }; public: diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp index 6ee720b5b5..2b3d3d11ac 100644 --- a/src/Mod/Sketcher/App/Sketch.cpp +++ b/src/Mod/Sketcher/App/Sketch.cpp @@ -1898,6 +1898,9 @@ int Sketch::addConstraint(const Constraint *constraint) case BSplineKnotPoint: rtn = addInternalAlignmentKnotPoint(constraint->First,constraint->Second, constraint->InternalAlignmentIndex); break; + case ParabolaFocalAxis: + rtn = addInternalAlignmentParabolaFocalDistance(constraint->First,constraint->Second); + break; default: break; } @@ -3256,6 +3259,44 @@ int Sketch::addInternalAlignmentParabolaFocus(int geoId1, int geoId2) return -1; } +int Sketch::addInternalAlignmentParabolaFocalDistance(int geoId1, int geoId2) +{ + std::swap(geoId1, geoId2); + + geoId1 = checkGeoId(geoId1); + geoId2 = checkGeoId(geoId2); + + if (Geoms[geoId1].type != ArcOfParabola) + return -1; + if (Geoms[geoId2].type != Line) + return -1; + + int pointId1 = getPointId(geoId2, PointPos::start); + int pointId2 = getPointId(geoId2, PointPos::end); + + if (pointId1 >= 0 && pointId1 < int(Points.size()) && + pointId2 >= 0 && pointId2 < int(Points.size())) { + + GCS::Point &p1 = Points[pointId1]; + GCS::Point &p2 = Points[pointId2]; + + GCS::ArcOfParabola &a1 = ArcsOfParabola[Geoms[geoId1].index]; + + auto & vertexpoint = a1.vertex; + auto & focuspoint = a1.focus1; + + int tag = ++ConstraintsCounter; + GCSsys.addConstraintP2PCoincident(p1, vertexpoint, tag); + + tag = ++ConstraintsCounter; + GCSsys.addConstraintP2PCoincident(p2, focuspoint, tag); + + return ConstraintsCounter; + } + + return -1; +} + int Sketch::addInternalAlignmentBSplineControlPoint(int geoId1, int geoId2, int poleindex) { std::swap(geoId1, geoId2); diff --git a/src/Mod/Sketcher/App/Sketch.h b/src/Mod/Sketcher/App/Sketch.h index 54f7e1b862..32b31c1f23 100644 --- a/src/Mod/Sketcher/App/Sketch.h +++ b/src/Mod/Sketcher/App/Sketch.h @@ -374,6 +374,7 @@ public: int addInternalAlignmentHyperbolaMinorDiameter(int geoId1, int geoId2); int addInternalAlignmentHyperbolaFocus(int geoId1, int geoId2); int addInternalAlignmentParabolaFocus(int geoId1, int geoId2); + int addInternalAlignmentParabolaFocalDistance(int geoId1, int geoId2); int addInternalAlignmentBSplineControlPoint(int geoId1, int geoId2, int poleindex); int addInternalAlignmentKnotPoint(int geoId1, int geoId2, int knotindex); //@} diff --git a/src/Mod/Sketcher/App/SketchGeometryExtension.h b/src/Mod/Sketcher/App/SketchGeometryExtension.h index 5cd31b639c..54a98c71f5 100644 --- a/src/Mod/Sketcher/App/SketchGeometryExtension.h +++ b/src/Mod/Sketcher/App/SketchGeometryExtension.h @@ -47,6 +47,7 @@ namespace Sketcher ParabolaFocus = 8, BSplineControlPoint = 9, BSplineKnotPoint = 10, + ParabolaFocalAxis = 11, NumInternalGeometryType // Must be the last }; } @@ -104,7 +105,7 @@ public: int getGeometryLayerId() const override { return GeometryLayer;} void setGeometryLayerId(int geolayer) override { GeometryLayer = geolayer;} - constexpr static std::array internaltype2str {{ "None", "EllipseMajorDiameter", "EllipseMinorDiameter","EllipseFocus1", "EllipseFocus2", "HyperbolaMajor", "HyperbolaMinor", "HyperbolaFocus", "ParabolaFocus", "BSplineControlPoint", "BSplineKnotPoint" }}; + constexpr static std::array internaltype2str {{ "None", "EllipseMajorDiameter", "EllipseMinorDiameter","EllipseFocus1", "EllipseFocus2", "HyperbolaMajor", "HyperbolaMinor", "HyperbolaFocus", "ParabolaFocus", "BSplineControlPoint", "BSplineKnotPoint", "ParabolaFocalAxis" }}; constexpr static std::array geometrymode2str {{ "Blocked", "Construction" }}; diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 2d60c12fcc..3f9eefa446 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -5069,7 +5069,6 @@ int SketchObject::exposeInternalGeometry(int GeoId) else if(geo->getTypeId() == Part::GeomArcOfParabola::getClassTypeId()) { // First we search what has to be restored bool focus=false; - int focusgeoid=-1; bool focus_to_vertex=false; const std::vector< Sketcher::Constraint * > &vals = Constraints.getValues(); @@ -5081,7 +5080,9 @@ int SketchObject::exposeInternalGeometry(int GeoId) switch((*it)->AlignmentType){ case Sketcher::ParabolaFocus: focus=true; - focusgeoid=(*it)->First; + break; + case Sketcher::ParabolaFocalAxis: + focus_to_vertex = true; break; default: return -1; @@ -5089,42 +5090,13 @@ int SketchObject::exposeInternalGeometry(int GeoId) } } - if(focus) { - // look for a line from focusgeoid:start to Geoid:mid_external - std::vector focusgeoidlistgeoidlist; - std::vector focusposidlist; - getDirectlyCoincidentPoints(focusgeoid, Sketcher::PointPos::start, focusgeoidlistgeoidlist, - focusposidlist); - - std::vector parabgeoidlistgeoidlist; - std::vector parabposidlist; - getDirectlyCoincidentPoints(GeoId, Sketcher::PointPos::mid, parabgeoidlistgeoidlist, - parabposidlist); - - if (!focusgeoidlistgeoidlist.empty() && !parabgeoidlistgeoidlist.empty()) { - std::size_t i,j; - for(i=0;igetTypeId() == Part::GeomLineSegment::getClassTypeId()) { - if((focusposidlist[i] == Sketcher::PointPos::start && parabposidlist[j] == Sketcher::PointPos::end) || - (focusposidlist[i] == Sketcher::PointPos::end && parabposidlist[j] == Sketcher::PointPos::start)) - focus_to_vertex=true; - } - } - } - } - } - } - int currentgeoid= getHighestCurveIndex(); int incrgeo= 0; - const Part::GeomArcOfParabola *aoh = static_cast(geo); + const Part::GeomArcOfParabola *aop = static_cast(geo); - Base::Vector3d center = aoh->getCenter(); - Base::Vector3d focusp = aoh->getFocus(); + Base::Vector3d center = aop->getCenter(); + Base::Vector3d focusp = aop->getFocus(); std::vector igeo; std::vector icon; @@ -5142,37 +5114,25 @@ int SketchObject::exposeInternalGeometry(int GeoId) newConstr->FirstPos = Sketcher::PointPos::start; newConstr->Second = GeoId; - focusgeoid = currentgeoid+incrgeo+1; - icon.push_back(newConstr); incrgeo++; } - if(!focus_to_vertex) - { + if (!focus_to_vertex) { Part::GeomLineSegment *paxis = new Part::GeomLineSegment(); paxis->setPoints(center,focusp); igeo.push_back(paxis); Sketcher::Constraint *newConstr = new Sketcher::Constraint(); - newConstr->Type = Sketcher::Coincident; - newConstr->First = focusgeoid; - newConstr->FirstPos = Sketcher::PointPos::start; - newConstr->Second = currentgeoid+incrgeo+1; // just added line - newConstr->SecondPos = Sketcher::PointPos::end; + newConstr->Type = Sketcher::InternalAlignment; + newConstr->AlignmentType = Sketcher::ParabolaFocalAxis; + newConstr->First = currentgeoid+incrgeo+1; + newConstr->FirstPos = Sketcher::PointPos::none; + newConstr->Second = GeoId; icon.push_back(newConstr); - Sketcher::Constraint *newConstr2 = new Sketcher::Constraint(); - newConstr2->Type = Sketcher::Coincident; - newConstr2->First = GeoId; - newConstr2->FirstPos = Sketcher::PointPos::mid; - newConstr2->Second = currentgeoid+incrgeo+1; // just added line - newConstr2->SecondPos = Sketcher::PointPos::start; - - icon.push_back(newConstr2); - incrgeo++; } @@ -5464,41 +5424,15 @@ int SketchObject::deleteUnusedInternalGeometry(int GeoId, bool delgeoid) case Sketcher::ParabolaFocus: focus1elementindex = (*it)->First; break; + case Sketcher::ParabolaFocalAxis: + majorelementindex = (*it)->First; + break; default: return -1; } } } - if (focus1elementindex!=-1) { - // look for a line from focusgeoid:start to Geoid:mid_external - std::vector focusgeoidlistgeoidlist; - std::vector focusposidlist; - getDirectlyCoincidentPoints(focus1elementindex, Sketcher::PointPos::start, focusgeoidlistgeoidlist, - focusposidlist); - - std::vector parabgeoidlistgeoidlist; - std::vector parabposidlist; - getDirectlyCoincidentPoints(GeoId, Sketcher::PointPos::mid, parabgeoidlistgeoidlist, - parabposidlist); - - if (!focusgeoidlistgeoidlist.empty() && !parabgeoidlistgeoidlist.empty()) { - std::size_t i,j; - for (i=0;igetTypeId() == Part::GeomLineSegment::getClassTypeId()) { - if((focusposidlist[i] == Sketcher::PointPos::start && parabposidlist[j] == Sketcher::PointPos::end) || - (focusposidlist[i] == Sketcher::PointPos::end && parabposidlist[j] == Sketcher::PointPos::start)) - majorelementindex = focusgeoidlistgeoidlist[i]; - } - } - } - } - } - } - // Hide unused geometry here int majorconstraints=0; // number of constraints associated to the geoid of the major axis other than the coincident ones int focus1constraints=0; @@ -5516,12 +5450,12 @@ int SketchObject::deleteUnusedInternalGeometry(int GeoId, bool delgeoid) std::vector delgeometries; - if (majorelementindex !=-1 && majorconstraints<3) { // major as two coincidents to focus and vertex + // major has minimum one constraint, the specific internal alignment constraint + if (majorelementindex !=-1 && majorconstraints<2) delgeometries.push_back(majorelementindex); - majorelementindex = -1; - } - if (majorelementindex == -1 && focus1elementindex !=-1 && focus1constraints<3) // focus has one coincident and one internal align + // focus has minimum one constraint now, the specific internal alignment constraint + if (focus1elementindex !=-1 && focus1constraints<2) delgeometries.push_back(focus1elementindex); if(delgeoid) @@ -8068,6 +8002,9 @@ bool SketchObject::getInternalTypeState(const Constraint * cstr, Sketcher::Inter case BSplineKnotPoint: internaltypestate = InternalType::BSplineKnotPoint; break; + case ParabolaFocalAxis: + internaltypestate = InternalType::ParabolaFocalAxis; + break; } return true; diff --git a/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp b/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp index cc35a06ae1..eaceec9db7 100644 --- a/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp +++ b/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp @@ -1307,9 +1307,9 @@ void EditModeConstraintCoinManager::updateConstraintColor(const std::vectorFirst); - } break; case EllipseFocus1: