Salome HOME
Issue #19207: planes of imported STEP not usable
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_MacroBSpline.cpp
index 28200494663ca0d248c31f3a55e9e85c156f042f..48158f1a826c86f48da608976153abbee07f3261 100644 (file)
@@ -20,6 +20,7 @@
 #include <SketchPlugin_MacroBSpline.h>
 
 #include <SketchPlugin_BSpline.h>
+#include <SketchPlugin_BSplinePeriodic.h>
 #include <SketchPlugin_ConstraintCoincidenceInternal.h>
 #include <SketchPlugin_Line.h>
 #include <SketchPlugin_Point.h>
@@ -30,7 +31,6 @@
 #include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeRefAttrList.h>
 #include <ModelAPI_Events.h>
-#include <ModelAPI_EventReentrantMessage.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
 
 
 #include <sstream>
 
-// Create Point feature coincident with the B-spline pole
-static FeaturePtr createAuxiliaryPole(FeaturePtr theBSpline,
-                                      AttributePoint2DArrayPtr theBSplinePoles,
-                                      const int thePoleIndex);
-// Create segment between consequtive B-spline poles
-static void createAuxiliarySegment(FeaturePtr theBSpline,
-                                   AttributePoint2DArrayPtr theBSplinePoles,
-                                   const int thePoleIndex1,
-                                   const int thePoleIndex2);
-// Create internal coincidence constraint with B-spline pole
+/// Create internal coincidence constraint with B-spline pole
 static void createInternalConstraint(SketchPlugin_Sketch* theSketch,
                                      AttributePtr thePoint,
                                      AttributePtr theBSplinePoles,
@@ -67,6 +58,13 @@ SketchPlugin_MacroBSpline::SketchPlugin_MacroBSpline()
 {
 }
 
+SketchPlugin_MacroBSpline::SketchPlugin_MacroBSpline(bool isPeriodic)
+  : SketchPlugin_SketchEntity(),
+    myDegree(3),
+    myIsPeriodic(isPeriodic)
+{
+}
+
 void SketchPlugin_MacroBSpline::initAttributes()
 {
   data()->addAttribute(POLES_ID(), GeomDataAPI_Point2DArray::typeId());
@@ -88,73 +86,27 @@ void SketchPlugin_MacroBSpline::execute()
     std::list<FeaturePtr> aControlPoles;
     createControlPolygon(aBSpline, aControlPoles);
     constraintsForPoles(aControlPoles);
-
-    // message to init reentrant operation
-    static Events_ID anId = ModelAPI_EventReentrantMessage::eventId();
-    ReentrantMessagePtr aMessage(new ModelAPI_EventReentrantMessage(anId, this));
-    // set here the last pole to make coincidence with the start point of the next B-spline curve
-    aMessage->setCreatedFeature(aControlPoles.back());
-    Events_Loop::loop()->send(aMessage);
-  }
-}
-
-// LCOV_EXCL_START
-std::string SketchPlugin_MacroBSpline::processEvent(
-                                              const std::shared_ptr<Events_Message>& theMessage)
-{
-  ReentrantMessagePtr aReentrantMessage =
-      std::dynamic_pointer_cast<ModelAPI_EventReentrantMessage>(theMessage);
-  if (aReentrantMessage) {
-    FeaturePtr aCreatedFeature = aReentrantMessage->createdFeature();
-    ObjectPtr anObject = aReentrantMessage->selectedObject();
-    AttributePtr anAttribute = aReentrantMessage->selectedAttribute();
-    std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = aReentrantMessage->clickedPoint();
-
-    if (aClickedPoint) {
-      // fill points list (it consists of 2 points to make editable the second one)
-      AttributePoint2DArrayPtr aPointArrayAttr =
-          std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
-      aPointArrayAttr->setSize(2);
-      aPointArrayAttr->setPnt(0, aClickedPoint);
-      aPointArrayAttr->setPnt(1, aClickedPoint);
-
-      // fill weights
-      AttributeDoubleArrayPtr aWeightsArrayAttr = data()->realArray(WEIGHTS_ID());
-      aWeightsArrayAttr->setSize(2);
-      aWeightsArrayAttr->setValue(0, 1.0);
-      aWeightsArrayAttr->setValue(1, 1.0);
-
-      // fill reference attribute
-      AttributeRefAttrListPtr aRefAttrList =
-          std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(attribute(REF_POLES_ID()));
-      if (anAttribute) {
-        if (!anAttribute->owner() || !anAttribute->owner()->data()->isValid()) {
-          if (aCreatedFeature && anAttribute->id() == SketchPlugin_Point::COORD_ID())
-            anAttribute = aCreatedFeature->attribute(SketchPlugin_Point::COORD_ID());
-        }
-        aRefAttrList->append(anAttribute);
-      }
-    }
-    Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
   }
-  return std::string();
 }
-// LCOV_EXCL_STOP
 
 FeaturePtr SketchPlugin_MacroBSpline::createBSplineFeature()
 {
-  FeaturePtr aBSpline = sketch()->addFeature(SketchPlugin_BSpline::ID());
+  if (myKnots.empty() || myMultiplicities.empty())
+    getAISObject(AISObjectPtr()); // fill B-spline parameters
+
+  FeaturePtr aBSpline = sketch()->addFeature(
+      myIsPeriodic ? SketchPlugin_BSplinePeriodic::ID() : SketchPlugin_BSpline::ID());
 
-  aBSpline->integer(SketchPlugin_BSpline::DEGREE_ID())->setValue(myDegree);
+  aBSpline->integer(SketchPlugin_BSplineBase::DEGREE_ID())->setValue(myDegree);
 
   AttributePoint2DArrayPtr aPoles = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
-      aBSpline->attribute(SketchPlugin_BSpline::POLES_ID()));
+      aBSpline->attribute(SketchPlugin_BSplineBase::POLES_ID()));
   AttributePoint2DArrayPtr aPolesMacro =
       std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
   aPoles->assign(aPolesMacro);
 
   AttributeDoubleArrayPtr aWeights =
-      aBSpline->data()->realArray(SketchPlugin_BSpline::WEIGHTS_ID());
+      aBSpline->data()->realArray(SketchPlugin_BSplineBase::WEIGHTS_ID());
   AttributeDoubleArrayPtr aWeightsMacro = data()->realArray(WEIGHTS_ID());
   int aSize = aWeightsMacro->size();
   aWeights->setSize(aSize);
@@ -162,33 +114,31 @@ FeaturePtr SketchPlugin_MacroBSpline::createBSplineFeature()
     aWeights->setValue(index, aWeightsMacro->value(index));
 
   AttributeDoubleArrayPtr aKnots =
-      aBSpline->data()->realArray(SketchPlugin_BSpline::KNOTS_ID());
+      aBSpline->data()->realArray(SketchPlugin_BSplineBase::KNOTS_ID());
   aSize = (int)myKnots.size();
   aKnots->setSize(aSize);
   std::list<double>::iterator aKIt = myKnots.begin();
   for (int index = 0; index < aSize; ++index, ++aKIt)
     aKnots->setValue(index, *aKIt);
 
-  AttributeIntArrayPtr aMults =
-      aBSpline->data()->intArray(SketchPlugin_BSpline::MULTS_ID());
+  AttributeIntArrayPtr aMults = aBSpline->data()->intArray(SketchPlugin_BSplineBase::MULTS_ID());
   aSize = (int)myMultiplicities.size();
   aMults->setSize(aSize);
   std::list<int>::iterator aMIt = myMultiplicities.begin();
   for (int index = 0; index < aSize; ++index, ++aMIt)
     aMults->setValue(index, *aMIt);
 
-  SketchPlugin_Sketch* aSketch =
-      std::dynamic_pointer_cast<SketchPlugin_Feature>(aBSpline)->sketch();
+  if (!myIsPeriodic) {
+    AttributePoint2DPtr aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+        aBSpline->attribute(SketchPlugin_BSpline::START_ID()));
+    aStartPoint->setValue(aPoles->pnt(0));
 
-  AttributePoint2DPtr aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      aBSpline->attribute(SketchPlugin_BSpline::START_ID()));
-  aStartPoint->setValue(aPoles->pnt(0));
-
-  AttributePoint2DPtr aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      aBSpline->attribute(SketchPlugin_BSpline::END_ID()));
-  aEndPoint->setValue(aPoles->pnt(aPoles->size() - 1));
+    AttributePoint2DPtr aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+       aBSpline->attribute(SketchPlugin_BSpline::END_ID()));
+    aEndPoint->setValue(aPoles->pnt(aPoles->size() - 1));
+  }
 
-  aBSpline->boolean(SketchPlugin_BSpline::AUXILIARY_ID())->setValue(
+  aBSpline->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(
       boolean(AUXILIARY_ID())->value());
 
   aBSpline->execute();
@@ -204,10 +154,14 @@ void SketchPlugin_MacroBSpline::createControlPolygon(FeaturePtr theBSpline,
   int aSize = aPoles->size();
   // poles
   for (int index = 0; index < aSize; ++index)
-    thePoles.push_back(createAuxiliaryPole(theBSpline, aPoles, index));
+    thePoles.push_back(createAuxiliaryPole(aPoles, index));
   // segments
   for (int index = 1; index < aSize; ++index)
-    createAuxiliarySegment(theBSpline, aPoles, index - 1, index);
+    createAuxiliarySegment(aPoles, index - 1, index);
+  if (myIsPeriodic) {
+    // additional segment to close the control polygon
+    createAuxiliarySegment(aPoles, aSize - 1, 0);
+  }
 }
 
 void SketchPlugin_MacroBSpline::constraintsForPoles(const std::list<FeaturePtr>& thePoles)
@@ -243,8 +197,6 @@ AISObjectPtr SketchPlugin_MacroBSpline::getAISObject(AISObjectPtr thePrevious)
   if (!aSketch)
     return AISObjectPtr();
 
-  static const bool PERIODIC = false;
-
   AttributePoint2DArrayPtr aPolesArray =
       std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
   AttributeDoubleArrayPtr aWeightsArray = data()->realArray(WEIGHTS_ID());
@@ -273,7 +225,7 @@ AISObjectPtr SketchPlugin_MacroBSpline::getAISObject(AISObjectPtr thePrevious)
   // create result non-periodic B-spline curve
   std::shared_ptr<GeomAPI_BSpline2d> aBSplineCurve;
   try {
-    aBSplineCurve.reset(new GeomAPI_BSpline2d(aPoles2D, aWeights, PERIODIC));
+    aBSplineCurve.reset(new GeomAPI_BSpline2d(aPoles2D, aWeights, myIsPeriodic));
   } catch (...) {
     // cannot build a B-spline curve
     return AISObjectPtr();
@@ -306,17 +258,36 @@ AISObjectPtr SketchPlugin_MacroBSpline::getAISObject(AISObjectPtr thePrevious)
 
 // ==========================     Auxiliary functions    ===========================================
 
-FeaturePtr createAuxiliaryPole(FeaturePtr theBSpline,
-                               AttributePoint2DArrayPtr theBSplinePoles,
-                               const int thePoleIndex)
+void SketchPlugin_MacroBSpline::assignDefaultNameForAux(FeaturePtr theAuxFeature,
+                                                        AttributePoint2DArrayPtr theBSplinePoles,
+                                                        const int thePoleIndex1,
+                                                        const int thePoleIndex2)
+{
+  FeaturePtr aBSpline = ModelAPI_Feature::feature(theBSplinePoles->owner());
+
+  std::ostringstream aName;
+  aName << aBSpline->name();
+  if (theAuxFeature->getKind() == SketchPlugin_Point::ID())
+    aName << "_" << theBSplinePoles->id() << "_" << thePoleIndex1;
+  else
+    aName << "_segment_" << thePoleIndex1 << "_" << thePoleIndex2;
+
+  theAuxFeature->data()->setName(aName.str());
+  theAuxFeature->lastResult()->data()->setName(aName.str());
+}
+
+FeaturePtr SketchPlugin_MacroBSpline::createAuxiliaryPole(AttributePoint2DArrayPtr theBSplinePoles,
+                                                          const int thePoleIndex)
 {
+  FeaturePtr aBSpline = ModelAPI_Feature::feature(theBSplinePoles->owner());
+
   SketchPlugin_Sketch* aSketch =
-      std::dynamic_pointer_cast<SketchPlugin_Feature>(theBSpline)->sketch();
+      std::dynamic_pointer_cast<SketchPlugin_Feature>(aBSpline)->sketch();
 
   // create child point equal to the B-spline's pole
   FeaturePtr aPointFeature = aSketch->addFeature(SketchPlugin_Point::ID());
   aPointFeature->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
-  aPointFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theBSpline);
+  aPointFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(aBSpline);
 
   GeomPnt2dPtr aPole = theBSplinePoles->pnt(thePoleIndex);
 
@@ -325,11 +296,7 @@ FeaturePtr createAuxiliaryPole(FeaturePtr theBSpline,
   aCoord->setValue(aPole);
 
   aPointFeature->execute();
-
-  std::ostringstream aName;
-  aName << theBSpline->name() << "_" << theBSplinePoles->id() << "_" << thePoleIndex;
-  aPointFeature->data()->setName(aName.str());
-  aPointFeature->lastResult()->data()->setName(aName.str());
+  assignDefaultNameForAux(aPointFeature, theBSplinePoles, thePoleIndex);
 
   // internal constraint to keep position of the point
   createInternalConstraint(aSketch, aCoord, theBSplinePoles, thePoleIndex);
@@ -337,18 +304,19 @@ FeaturePtr createAuxiliaryPole(FeaturePtr theBSpline,
   return aPointFeature;
 }
 
-void createAuxiliarySegment(FeaturePtr theBSpline,
-                            AttributePoint2DArrayPtr theBSplinePoles,
-                            const int thePoleIndex1,
-                            const int thePoleIndex2)
+void SketchPlugin_MacroBSpline::createAuxiliarySegment(AttributePoint2DArrayPtr theBSplinePoles,
+                                                       const int thePoleIndex1,
+                                                       const int thePoleIndex2)
 {
+  FeaturePtr aBSpline = ModelAPI_Feature::feature(theBSplinePoles->owner());
+
   SketchPlugin_Sketch* aSketch =
-    std::dynamic_pointer_cast<SketchPlugin_Feature>(theBSpline)->sketch();
+      std::dynamic_pointer_cast<SketchPlugin_Feature>(aBSpline)->sketch();
 
   // create child segment between B-spline poles
   FeaturePtr aLineFeature = aSketch->addFeature(SketchPlugin_Line::ID());
   aLineFeature->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
-  aLineFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theBSpline);
+  aLineFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(aBSpline);
 
   AttributePoint2DPtr aLineStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
     aLineFeature->attribute(SketchPlugin_Line::START_ID()));
@@ -359,11 +327,7 @@ void createAuxiliarySegment(FeaturePtr theBSpline,
   aLineEnd->setValue(theBSplinePoles->pnt(thePoleIndex2));
 
   aLineFeature->execute();
-
-  std::ostringstream aName;
-  aName << theBSpline->name() << "_segment_" << thePoleIndex1 << "_" << thePoleIndex2;
-  aLineFeature->data()->setName(aName.str());
-  aLineFeature->lastResult()->data()->setName(aName.str());
+  assignDefaultNameForAux(aLineFeature, theBSplinePoles, thePoleIndex1, thePoleIndex2);
 
   // internal constraints to keep the segment position
   createInternalConstraint(aSketch, aLineStart, theBSplinePoles, thePoleIndex1);