From 1ab0c5577bd2c18bad23fb591864c9b76bcad29e Mon Sep 17 00:00:00 2001 From: jfa Date: Mon, 22 Jun 2020 15:59:52 +0300 Subject: [PATCH] Sketch Offset: an attempt to add ellipses and bsplines --- src/GeomAPI/GeomAPI_Edge.cpp | 8 +- src/SketchPlugin/SketchPlugin_Offset.cpp | 113 ++++++++++++++++++++++- src/SketchPlugin/SketchPlugin_Offset.h | 5 + 3 files changed, 121 insertions(+), 5 deletions(-) diff --git a/src/GeomAPI/GeomAPI_Edge.cpp b/src/GeomAPI/GeomAPI_Edge.cpp index 03e44e808..82752f16e 100644 --- a/src/GeomAPI/GeomAPI_Edge.cpp +++ b/src/GeomAPI/GeomAPI_Edge.cpp @@ -175,9 +175,9 @@ bool GeomAPI_Edge::isEllipse() const Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast); if (aCurve.IsNull()) // degenerative edge return false; - if (aCurve->IsKind(STANDARD_TYPE(Geom_Ellipse))) - return true; - return false; + while (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) + aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve(); + return aCurve->IsKind(STANDARD_TYPE(Geom_Ellipse)); } bool GeomAPI_Edge::isBSpline() const @@ -234,6 +234,8 @@ std::shared_ptr GeomAPI_Edge::ellipse() const double aFirst, aLast; Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast); if (!aCurve.IsNull()) { + while (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) + aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve(); Handle(Geom_Ellipse) aElips = Handle(Geom_Ellipse)::DownCast(aCurve); if (!aElips.IsNull()) { gp_Elips aGpElips = aElips->Elips(); diff --git a/src/SketchPlugin/SketchPlugin_Offset.cpp b/src/SketchPlugin/SketchPlugin_Offset.cpp index 78d5e47c8..d789c85a7 100644 --- a/src/SketchPlugin/SketchPlugin_Offset.cpp +++ b/src/SketchPlugin/SketchPlugin_Offset.cpp @@ -24,12 +24,18 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include +#include +#include #include #include #include @@ -40,8 +46,11 @@ #include #include +#include +#include #include +#include #include @@ -243,7 +252,8 @@ void SketchPlugin_Offset::addToSketch(const std::shared_ptr& anOf std::shared_ptr aFP, aLP; std::shared_ptr aFP3d = aResEdge->firstPoint(); std::shared_ptr aLP3d = aResEdge->lastPoint(); - if (aFP3d.get() && aLP3d.get()) { + //if (aFP3d.get() && aLP3d.get()) { + if (aFP3d && aLP3d) { aFP = sketch()->to2D(aFP3d); aLP = sketch()->to2D(aLP3d); } @@ -266,7 +276,7 @@ void SketchPlugin_Offset::addToSketch(const std::shared_ptr& anOf bool aWasBlocked = aResFeature->data()->blockSendAttributeUpdated(true); std::dynamic_pointer_cast (aResFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->setValue(aCP); - std::dynamic_pointer_cast + std::dynamic_pointer_cast (aResFeature->attribute(SketchPlugin_Arc::START_ID()))->setValue(aFP); std::dynamic_pointer_cast (aResFeature->attribute(SketchPlugin_Arc::END_ID()))->setValue(aLP); @@ -282,6 +292,44 @@ void SketchPlugin_Offset::addToSketch(const std::shared_ptr& anOf (aResFeature->attribute(SketchPlugin_Circle::CENTER_ID()))->setValue(aCP); aResFeature->real(SketchPlugin_Circle::RADIUS_ID())->setValue(aCircEdge->radius()); } + else if (aResEdge->isEllipse()) { + std::shared_ptr anEllipseEdge = aResEdge->ellipse(); + + GeomPointPtr aCP3d = anEllipseEdge->center(); + GeomPnt2dPtr aCP = sketch()->to2D(aCP3d); + + GeomPointPtr aFocus3d = anEllipseEdge->firstFocus(); + GeomPnt2dPtr aFocus = sketch()->to2D(aFocus3d); + + if (aFP3d && aLP3d) { + // Elliptic arc + aResFeature = sketch()->addFeature(SketchPlugin_EllipticArc::ID()); + + bool aWasBlocked = aResFeature->data()->blockSendAttributeUpdated(true); + std::dynamic_pointer_cast + (aResFeature->attribute(SketchPlugin_EllipticArc::CENTER_ID()))->setValue(aCP); + std::dynamic_pointer_cast + (aResFeature->attribute(SketchPlugin_EllipticArc::FIRST_FOCUS_ID()))->setValue(aFocus); + std::dynamic_pointer_cast + (aResFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID()))->setValue(aFP); + std::dynamic_pointer_cast + (aResFeature->attribute(SketchPlugin_EllipticArc::END_POINT_ID()))->setValue(aLP); + aResFeature->data()->blockSendAttributeUpdated(aWasBlocked); + } + else { + // Ellipse + aResFeature = sketch()->addFeature(SketchPlugin_Ellipse::ID()); + + std::dynamic_pointer_cast + (aResFeature->attribute(SketchPlugin_Ellipse::CENTER_ID()))->setValue(aCP); + std::dynamic_pointer_cast + (aResFeature->attribute(SketchPlugin_Ellipse::FIRST_FOCUS_ID()))->setValue(aFocus); + aResFeature->real(SketchPlugin_Ellipse::MINOR_RADIUS_ID())->setValue(anEllipseEdge->minorRadius()); + } + } + else if (aResEdge->isBSpline()) { + mkBSpline(aResFeature, aResEdge); + } else { } @@ -296,6 +344,67 @@ void SketchPlugin_Offset::addToSketch(const std::shared_ptr& anOf } } +void SketchPlugin_Offset::mkBSpline (FeaturePtr& theResult, + const GeomEdgePtr& theEdge) +{ + if (!theEdge->isBSpline()) + return; + + GeomCurvePtr aCurve (new GeomAPI_Curve (theEdge)); + GeomAPI_BSpline aBSpline (aCurve); + + if (aBSpline.isPeriodic()) + theResult = sketch()->addFeature(SketchPlugin_BSplinePeriodic::ID()); + else + theResult = sketch()->addFeature(SketchPlugin_BSpline::ID()); + + theResult->integer(SketchPlugin_BSpline::DEGREE_ID())->setValue(aBSpline.degree()); + + AttributePoint2DArrayPtr aPolesAttr = std::dynamic_pointer_cast + (theResult->attribute(SketchPlugin_BSpline::POLES_ID())); + std::list aPoles = aBSpline.poles(); + aPolesAttr->setSize((int)aPoles.size()); + std::list::iterator anIt = aPoles.begin(); + for (int anIndex = 0; anIt != aPoles.end(); ++anIt, ++anIndex) { + GeomPnt2dPtr aPoleInSketch = sketch()->to2D(*anIt); + aPolesAttr->setPnt(anIndex, aPoleInSketch); + } + + AttributeDoubleArrayPtr aWeightsAttr = + theResult->data()->realArray(SketchPlugin_BSpline::WEIGHTS_ID()); + std::list aWeights = aBSpline.weights(); + if (aWeights.empty()) { // rational B-spline + int aSize = (int)aPoles.size(); + aWeightsAttr->setSize(aSize); + for (int anIndex = 0; anIndex < aSize; ++anIndex) + aWeightsAttr->setValue(anIndex, 1.0); + } + else { // non-rational B-spline + aWeightsAttr->setSize((int)aWeights.size()); + std::list::iterator anIt = aWeights.begin(); + for (int anIndex = 0; anIt != aWeights.end(); ++anIt, ++anIndex) + aWeightsAttr->setValue(anIndex, *anIt); + } + + AttributeDoubleArrayPtr aKnotsAttr = + theResult->data()->realArray(SketchPlugin_BSpline::KNOTS_ID()); + std::list aKnots = aBSpline.knots(); + int aSize = (int)aKnots.size(); + aKnotsAttr->setSize(aSize); + std::list::iterator aKIt = aKnots.begin(); + for (int index = 0; index < aSize; ++index, ++aKIt) + aKnotsAttr->setValue(index, *aKIt); + + AttributeIntArrayPtr aMultsAttr = + theResult->data()->intArray(SketchPlugin_BSpline::MULTS_ID()); + std::list aMultiplicities = aBSpline.mults(); + aSize = (int)aMultiplicities.size(); + aMultsAttr->setSize(aSize); + std::list::iterator aMIt = aMultiplicities.begin(); + for (int index = 0; index < aSize; ++index, ++aMIt) + aMultsAttr->setValue(index, *aMIt); +} + void SketchPlugin_Offset::attributeChanged(const std::string& theID) { ModelAPI_Tools::removeFeaturesAndReferences(myCreatedFeatures); diff --git a/src/SketchPlugin/SketchPlugin_Offset.h b/src/SketchPlugin/SketchPlugin_Offset.h index 85e837128..af74b7169 100644 --- a/src/SketchPlugin/SketchPlugin_Offset.h +++ b/src/SketchPlugin/SketchPlugin_Offset.h @@ -22,7 +22,9 @@ #include #include + #include +#include /**\class SketchPlugin_Offset * \ingroup Plugins @@ -108,6 +110,9 @@ private: // and store it in myCreatedFeatures to remove on next execute() void addToSketch (const std::shared_ptr& theOffsetResult); + // Create BSpline or BSplinePeriodic sketch feature from theEdge + void mkBSpline (FeaturePtr& theResult, const GeomEdgePtr& theEdge); + // Find edges that prolongate theEdgeFeature (in a chain) at theEndPoint // Recursive method. // \param[in] theFirstEdge Start edge of wire searching -- 2.39.2