]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Sketch Offset: an attempt to add ellipses and bsplines
authorjfa <jfa@opencascade.com>
Mon, 22 Jun 2020 12:59:52 +0000 (15:59 +0300)
committerjfa <jfa@opencascade.com>
Mon, 22 Jun 2020 12:59:52 +0000 (15:59 +0300)
src/GeomAPI/GeomAPI_Edge.cpp
src/SketchPlugin/SketchPlugin_Offset.cpp
src/SketchPlugin/SketchPlugin_Offset.h

index 03e44e8084844cc8f90ff5c4f605805d1f581d6a..82752f16e01ac82c07c4ffa521255a33689d4ad6 100644 (file)
@@ -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_Ellipse> 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();
index 78d5e47c8739f5d9c591f4a6f2b6eeab560e682a..d789c85a714c8c7002d8125bd5b47501ce94bdbb 100644 (file)
 #include <SketchPlugin_Point.h>
 #include <SketchPlugin_Arc.h>
 #include <SketchPlugin_Circle.h>
+#include <SketchPlugin_Ellipse.h>
+#include <SketchPlugin_EllipticArc.h>
+#include <SketchPlugin_BSpline.h>
+#include <SketchPlugin_BSplinePeriodic.h>
 #include <SketchPlugin_Tools.h>
 
 #include <Events_InfoMessage.h>
 
 #include <ModelAPI_AttributeBoolean.h>
 #include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeDoubleArray.h>
+#include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_Tools.h>
 
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Circ.h>
+#include <GeomAPI_Ellipse.h>
+#include <GeomAPI_BSpline.h>
 
 #include <GeomDataAPI_Point2D.h>
+#include <GeomDataAPI_Point2DArray.h>
 
 #include <iostream>
 
@@ -243,7 +252,8 @@ void SketchPlugin_Offset::addToSketch(const std::shared_ptr<GeomAPI_Shape>& anOf
       std::shared_ptr<GeomAPI_Pnt2d> aFP, aLP;
       std::shared_ptr<GeomAPI_Pnt> aFP3d = aResEdge->firstPoint();
       std::shared_ptr<GeomAPI_Pnt> 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<GeomAPI_Shape>& anOf
         bool aWasBlocked = aResFeature->data()->blockSendAttributeUpdated(true);
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>
           (aResFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->setValue(aCP);
-       std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>
           (aResFeature->attribute(SketchPlugin_Arc::START_ID()))->setValue(aFP);
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>
           (aResFeature->attribute(SketchPlugin_Arc::END_ID()))->setValue(aLP);
@@ -282,6 +292,44 @@ void SketchPlugin_Offset::addToSketch(const std::shared_ptr<GeomAPI_Shape>& 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<GeomAPI_Ellipse> 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<GeomDataAPI_Point2D>
+            (aResFeature->attribute(SketchPlugin_EllipticArc::CENTER_ID()))->setValue(aCP);
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+            (aResFeature->attribute(SketchPlugin_EllipticArc::FIRST_FOCUS_ID()))->setValue(aFocus);
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+            (aResFeature->attribute(SketchPlugin_EllipticArc::START_POINT_ID()))->setValue(aFP);
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+            (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<GeomDataAPI_Point2D>
+            (aResFeature->attribute(SketchPlugin_Ellipse::CENTER_ID()))->setValue(aCP);
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+            (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<GeomAPI_Shape>& 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<GeomDataAPI_Point2DArray>
+    (theResult->attribute(SketchPlugin_BSpline::POLES_ID()));
+  std::list<GeomPointPtr> aPoles = aBSpline.poles();
+  aPolesAttr->setSize((int)aPoles.size());
+  std::list<GeomPointPtr>::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<double> 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<double>::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<double> aKnots = aBSpline.knots();
+  int aSize = (int)aKnots.size();
+  aKnotsAttr->setSize(aSize);
+  std::list<double>::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<int> aMultiplicities = aBSpline.mults();
+  aSize = (int)aMultiplicities.size();
+  aMultsAttr->setSize(aSize);
+  std::list<int>::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);
index 85e8371288d3078f3e2de0be2871d945c49f53a0..af74b7169659ee2066f4c12c6ed6e902458d1f9d 100644 (file)
@@ -22,7 +22,9 @@
 
 #include <SketchPlugin.h>
 #include <SketchPlugin_SketchEntity.h>
+
 #include <GeomDataAPI_Point2D.h>
+#include <GeomAPI_Edge.h>
 
 /**\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<GeomAPI_Shape>& 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