diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp index 8a21e0b65c..8c619b23ad 100644 --- a/src/Mod/Part/App/Geometry.cpp +++ b/src/Mod/Part/App/Geometry.cpp @@ -2231,6 +2231,16 @@ bool GeomConic::isReversed() const return conic->Axis().Direction().Z() < 0; } +bool GeomConic::reverseIfReversed() +{ + Handle(Geom_Conic) hConic = Handle(Geom_Conic)::DownCast(handle()); + if (isReversed()) { + hConic->Reverse(); + return true; + } + return false; +} + GeomBSplineCurve* GeomConic::toNurbs(double first, double last) const { Handle(Geom_Conic) conic = Handle(Geom_Conic)::DownCast(handle()); @@ -2501,6 +2511,18 @@ bool GeomArcOfConic::isReversed() const return conic->Axis().Direction().Z() < 0; } +bool GeomArcOfConic::reverseIfReversed() +{ + Handle(Geom_TrimmedCurve) tCurve = Handle(Geom_TrimmedCurve)::DownCast(handle()); + if (tCurve) { + if (isReversed()) { + tCurve->Reverse(); + return true; + } + } + return false; +} + /*! * \brief GeomArcOfConic::getAngleXU * \return The angle between ellipse's major axis (in direction to focus1) and @@ -7075,3 +7097,4 @@ std::unique_ptr makeFromCurveAdaptor(const Adaptor3d_Curve& adapt, bo } // namespace Part + diff --git a/src/Mod/Part/App/Geometry.h b/src/Mod/Part/App/Geometry.h index d1f5e37288..97aae6930c 100644 --- a/src/Mod/Part/App/Geometry.h +++ b/src/Mod/Part/App/Geometry.h @@ -129,6 +129,11 @@ public: void transform(const Base::Matrix4D& mat) const; void translate(const Base::Vector3d& vec) const; + virtual bool reverseIfReversed() + { + return false; + }; + protected: /// create a new tag for the geometry object void createNewTag(); @@ -420,6 +425,7 @@ public: double getAngleXU() const; void setAngleXU(double angle); bool isReversed() const; + bool reverseIfReversed() override; Base::Vector3d getAxisDirection() const; @@ -505,6 +511,7 @@ public: inline void setRange(double u, double v) override { setRange(u,v,false);} bool isReversed() const; + bool reverseIfReversed() override; double getAngleXU() const; void setAngleXU(double angle); diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerOffset.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerOffset.h index ed234e18cd..dd82b3a05d 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerOffset.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerOffset.h @@ -305,11 +305,6 @@ private: gCircle->setRadius(circle.Radius()); gCircle->setCenter(Base::Vector3d(cnt.X(), cnt.Y(), cnt.Z())); - if (edge.Orientation() == TopAbs_REVERSED) { - Handle(Geom_Circle) hCircle = Handle(Geom_Circle)::DownCast(gCircle->handle()); - hCircle->Reverse(); - } - GeometryFacade::setConstruction(gCircle, false); return gCircle; } @@ -319,17 +314,12 @@ private: double u1 = curve.FirstParameter(); double u2 = curve.LastParameter(); - if (edge.Orientation() == TopAbs_REVERSED) { - hCircle->Reverse(); // Reverses the axis of the underlying circle - std::swap(u1, u2); - u1 = -u1; - u2 = -u2; - } - auto* gArc = new Part::GeomArcOfCircle(); Handle(Geom_TrimmedCurve) tCurve = new Geom_TrimmedCurve(hCircle, u1, u2); gArc->setHandle(tCurve); + gArc->reverseIfReversed(); + GeometryFacade::setConstruction(gArc, false); return gArc; } @@ -345,11 +335,10 @@ private: auto* gEllipse = new Part::GeomEllipse(); Handle(Geom_Ellipse) hEllipse = new Geom_Ellipse(ellipse); - if (edge.Orientation() == TopAbs_REVERSED) { - hEllipse->Reverse(); - } - gEllipse->setHandle(hEllipse); + + gEllipse->reverseIfReversed(); + GeometryFacade::setConstruction(gEllipse, false); return gEllipse; } @@ -359,17 +348,12 @@ private: double u1 = curve.FirstParameter(); double u2 = curve.LastParameter(); - if (edge.Orientation() == TopAbs_REVERSED) { - hEllipse->Reverse(); // Reverses the axis of the underlying ellipse - std::swap(u1, u2); - u1 = -u1; - u2 = -u2; - } - Handle(Geom_TrimmedCurve) tCurve = new Geom_TrimmedCurve(hEllipse, u1, u2); auto* gArc = new Part::GeomArcOfEllipse(); gArc->setHandle(tCurve); + gArc->reverseIfReversed(); + GeometryFacade::setConstruction(gArc, false); return gArc; } @@ -386,7 +370,6 @@ private: TopExp_Explorer expl(offsetShape, TopAbs_EDGE); int geoIdToAdd = firstCurveCreated; for (; expl.More(); expl.Next(), geoIdToAdd++) { - const TopoDS_Edge& edge = TopoDS::Edge(expl.Current()); BRepAdaptor_Curve curve(edge); if (curve.GetType() == GeomAbs_Line) { @@ -977,8 +960,19 @@ private: for (auto& CC : vCC) { BRepBuilderAPI_MakeWire mkWire; - for (auto& curve : CC) { - mkWire.Add(TopoDS::Edge(Obj->getGeometry(curve)->toShape())); + if (CC.size() > 1) { + // The element to become the new first element is the last one. + // The iterator to this element is one before the end. + std::rotate(CC.begin(), CC.end() - 1, CC.end()); + } + for (auto& curveId : CC) { + const Part::Geometry* pGeo = Obj->getGeometry(curveId); + auto geoCopy = std::unique_ptr(pGeo->copy()); + Part::Geometry* geo = geoCopy.get(); + geo->reverseIfReversed(); // make sure we don't have reversed conics + + // Use the normalized copy to create the edge for the wire + mkWire.Add(TopoDS::Edge(geo->toShape())); } // Here we make sure that if possible the first wire is not a single line. diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerRotate.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerRotate.h index 661fd14071..3616afc32f 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerRotate.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerRotate.h @@ -297,68 +297,14 @@ private: auto geoUniquePtr = std::unique_ptr(pGeo->copy()); Part::Geometry* geo = geoUniquePtr.get(); + if (!onlyeditoutline) { + geo->reverseIfReversed(); // make sure we don't have reversed conics + } + double angle = individualAngle * i; - if (isCircle(*geo)) { - auto* circle = static_cast(geo); // NOLINT - circle->setCenter(getRotatedPoint(circle->getCenter(), centerPoint, angle)); - } - else if (isArcOfCircle(*geo)) { - auto* arcOfCircle = static_cast(geo); // NOLINT - arcOfCircle->setCenter( - getRotatedPoint(arcOfCircle->getCenter(), centerPoint, angle)); - double arcStartAngle, arcEndAngle; // NOLINT - arcOfCircle->getRange(arcStartAngle, arcEndAngle, /*emulateCCWXY=*/true); - arcOfCircle->setRange(arcStartAngle + angle, - arcEndAngle + angle, - /*emulateCCWXY=*/true); - } - else if (isLineSegment(*geo)) { - auto* line = static_cast(geo); // NOLINT - line->setPoints(getRotatedPoint(line->getStartPoint(), centerPoint, angle), - getRotatedPoint(line->getEndPoint(), centerPoint, angle)); - } - else if (isEllipse(*geo)) { - auto* ellipse = static_cast(geo); // NOLINT - ellipse->setCenter(getRotatedPoint(ellipse->getCenter(), centerPoint, angle)); - ellipse->setMajorAxisDir( - getRotatedPoint(ellipse->getMajorAxisDir(), Base::Vector2d(0., 0.), angle)); - } - else if (isArcOfEllipse(*geo)) { - auto* arcOfEllipse = static_cast(geo); // NOLINT - arcOfEllipse->setCenter( - getRotatedPoint(arcOfEllipse->getCenter(), centerPoint, angle)); - arcOfEllipse->setMajorAxisDir(getRotatedPoint(arcOfEllipse->getMajorAxisDir(), - Base::Vector2d(0., 0.), - angle)); - } - else if (isArcOfHyperbola(*geo)) { - auto* arcOfHyperbola = static_cast(geo); // NOLINT - arcOfHyperbola->setCenter( - getRotatedPoint(arcOfHyperbola->getCenter(), centerPoint, angle)); - arcOfHyperbola->setMajorAxisDir( - getRotatedPoint(arcOfHyperbola->getMajorAxisDir(), - Base::Vector2d(0., 0.), - angle)); - } - else if (isArcOfParabola(*geo)) { - auto* arcOfParabola = static_cast(geo); // NOLINT - arcOfParabola->setCenter( - getRotatedPoint(arcOfParabola->getCenter(), centerPoint, angle)); - arcOfParabola->setAngleXU(arcOfParabola->getAngleXU() + angle); - } - else if (isBSplineCurve(*geo)) { - auto* bSpline = static_cast(geo); // NOLINT - std::vector poles = bSpline->getPoles(); - for (size_t p = 0; p < poles.size(); p++) { - poles[p] = getRotatedPoint(std::move(poles[p]), centerPoint, angle); - } - bSpline->setPoles(poles); - } - else if (isPoint(*geo)) { - auto* point = static_cast(geo); // NOLINT - point->setPoint(getRotatedPoint(point->getPoint(), centerPoint, angle)); - } + Base::Matrix4D matrix(toVector3d(centerPoint), Base::Vector3d(0, 0, 1), angle); + geo->transform(matrix); ShapeGeometry.emplace_back(std::move(geoUniquePtr)); } @@ -473,24 +419,6 @@ private: } } } - - Base::Vector3d - getRotatedPoint(Base::Vector3d&& pointToRotate, const Base::Vector2d& centerPoint, double angle) - { - Base::Vector2d pointToRotate2D = Base::Vector2d(pointToRotate.x, pointToRotate.y); - - double initialAngle = (pointToRotate2D - centerPoint).Angle(); - double lengthToCenter = (pointToRotate2D - centerPoint).Length(); - - pointToRotate2D = centerPoint - + lengthToCenter * Base::Vector2d(cos(angle + initialAngle), sin(angle + initialAngle)); - - - pointToRotate.x = pointToRotate2D.x; - pointToRotate.y = pointToRotate2D.y; - - return pointToRotate; - } }; template<>