Salome HOME
Refactoring of B-splines in SketchPlugin
authorazv <azv@opencascade.com>
Fri, 24 Jan 2020 09:13:50 +0000 (12:13 +0300)
committerazv <azv@opencascade.com>
Mon, 27 Jan 2020 09:51:05 +0000 (12:51 +0300)
src/GeomAPI/GeomAPI_BSpline2d.cpp
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_BSpline.cpp
src/SketchPlugin/SketchPlugin_BSpline.h
src/SketchPlugin/SketchPlugin_BSplineBase.cpp [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_BSplineBase.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_BSplinePeriodic.cpp
src/SketchPlugin/SketchPlugin_BSplinePeriodic.h

index 820d4cf15d338daf27dbaed320fd3eccc6ba4c82..f702a278a0bf1248ceebfb56ddba1ab74a31e312 100644 (file)
@@ -48,8 +48,8 @@ static Handle_Geom2d_BSplineCurve* newBSpline2d(
     return newBSpline2d(thePoles, theWeights, theDegree, thePeriodic);
 
   int anAuxPole = 0;
-  if (thePeriodic && thePoles.front()->distance(thePoles.back()) > Precision::Confusion())
-    anAuxPole = 1;
+  if (thePeriodic && thePoles.front()->distance(thePoles.back()) < Precision::Confusion())
+    anAuxPole = -1;
 
   // collect arrays of poles, weights, knots and multiplicities
   TColgp_Array1OfPnt2d aPoles(1, (int)thePoles.size() + anAuxPole);
@@ -59,11 +59,11 @@ static Handle_Geom2d_BSplineCurve* newBSpline2d(
 
   int anIndex = 1;
   for (std::list<GeomPnt2dPtr>::const_iterator aPIt = thePoles.begin();
-       aPIt != thePoles.end(); ++aPIt, ++anIndex)
+       aPIt != thePoles.end() && anIndex <= aPoles.Upper(); ++aPIt, ++anIndex)
     aPoles.SetValue(anIndex, gp_Pnt2d((*aPIt)->x(), (*aPIt)->y()));
   anIndex = 1;
   for (std::list<double>::const_iterator aWIt = theWeights.begin();
-       aWIt != theWeights.end(); ++aWIt, ++anIndex)
+       aWIt != theWeights.end() && anIndex <= aWeights.Upper(); ++aWIt, ++anIndex)
     aWeights.SetValue(anIndex, *aWIt);
   anIndex = 1;
   for (std::list<double>::const_iterator aKIt = theKnots.begin();
@@ -74,11 +74,6 @@ static Handle_Geom2d_BSplineCurve* newBSpline2d(
        aMIt != theMults.end(); ++aMIt, ++anIndex)
     aMults.SetValue(anIndex, *aMIt);
 
-  if (thePeriodic) {
-    aPoles.ChangeLast() = aPoles.First();
-    aWeights.ChangeLast() = aWeights.First();
-  }
-
   Handle(Geom2d_BSplineCurve) aCurve =
       new Geom2d_BSplineCurve(aPoles, aWeights, aKnots, aMults, theDegree, thePeriodic);
   return new Handle_Geom2d_BSplineCurve(aCurve);
@@ -99,8 +94,6 @@ Handle_Geom2d_BSplineCurve* newBSpline2d(
       aPoles.pop_back();
       aWeights.pop_back();
     }
-    aPoles.push_back(aPoles.front());
-    aWeights.push_back(aWeights.front());
     aMult = 1;
     aNbKnots = (int)aPoles.size() + 1;
   }
index 9855c5f4ca4e87ed3e1d0df3666e5a34bf2d2e28..3fde1ddf8684fafe8bf99d97e6c1000c142ff9a6 100644 (file)
@@ -24,6 +24,7 @@ SET(PROJECT_HEADERS
     SketchPlugin.h
     SketchPlugin_Arc.h
     SketchPlugin_BSpline.h
+    SketchPlugin_BSplineBase.h
     SketchPlugin_BSplinePeriodic.h
     SketchPlugin_Circle.h
     SketchPlugin_Constraint.h
@@ -77,6 +78,7 @@ SET(PROJECT_HEADERS
 SET(PROJECT_SOURCES
     SketchPlugin_Arc.cpp
     SketchPlugin_BSpline.cpp
+    SketchPlugin_BSplineBase.cpp
     SketchPlugin_BSplinePeriodic.cpp
     SketchPlugin_Circle.cpp
     SketchPlugin_Constraint.cpp
index a56d5281a0e8a18b5902510fae0a2f426d4d0531..01835735db0586cc4ccfec85d45f2b5794c199c2 100644 (file)
 //
 
 #include <SketchPlugin_BSpline.h>
-#include <SketchPlugin_Sketch.h>
-
-#include <GeomAlgoAPI_EdgeBuilder.h>
-
-#include <GeomAPI_Pnt2d.h>
 
 #include <GeomDataAPI_Point2D.h>
 #include <GeomDataAPI_Point2DArray.h>
 
-#include <ModelAPI_AttributeDoubleArray.h>
-#include <ModelAPI_AttributeIntArray.h>
-#include <ModelAPI_AttributeInteger.h>
-#include <ModelAPI_ResultConstruction.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Validator.h>
-
 
 SketchPlugin_BSpline::SketchPlugin_BSpline()
-  : SketchPlugin_SketchEntity()
+  : SketchPlugin_BSplineBase()
 {
 }
 
@@ -45,114 +33,11 @@ void SketchPlugin_BSpline::initDerivedClassAttributes()
   data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId());
   data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId());
 
-  data()->addAttribute(POLES_ID(), GeomDataAPI_Point2DArray::typeId());
-  data()->addAttribute(WEIGHTS_ID(), ModelAPI_AttributeDoubleArray::typeId());
-  data()->addAttribute(KNOTS_ID(), ModelAPI_AttributeDoubleArray::typeId());
-  data()->addAttribute(MULTS_ID(), ModelAPI_AttributeIntArray::typeId());
-  data()->addAttribute(DEGREE_ID(), ModelAPI_AttributeInteger::typeId());
-
-  data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
-}
-
-void SketchPlugin_BSpline::execute()
-{
-  SketchPlugin_Sketch* aSketch = sketch();
-  if(!aSketch) {
-    return;
-  }
-
-  AttributePoint2DArrayPtr aPolesArray =
-      std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
-  AttributeDoubleArrayPtr aWeightsArray = data()->realArray(WEIGHTS_ID());
-  AttributeDoubleArrayPtr aKnotsArray = data()->realArray(KNOTS_ID());
-  AttributeIntArrayPtr aMultsArray = data()->intArray(MULTS_ID());
-  AttributeIntegerPtr aDegreeAttr = data()->integer(DEGREE_ID());
-
-  // collect poles
-  std::list<GeomPnt2dPtr> aPoles2D;
-  for (int anIndex = 0; anIndex < aPolesArray->size(); ++anIndex) {
-    GeomPnt2dPtr aPole = aPolesArray->pnt(anIndex);
-    aPoles2D.push_back(aPole);
-  }
-  // collect weights
-  std::list<double> aWeights;
-  for (int anIndex = 0; anIndex < aWeightsArray->size(); ++anIndex)
-    aWeights.push_back(aWeightsArray->value(anIndex));
-  // collect knots
-  std::list<double> aKnots;
-  for (int anIndex = 0; anIndex < aKnotsArray->size(); ++anIndex)
-    aKnots.push_back(aKnotsArray->value(anIndex));
-  // collect multiplicities
-  std::list<int> aMults;
-  for (int anIndex = 0; anIndex < aMultsArray->size(); ++anIndex)
-    aMults.push_back(aMultsArray->value(anIndex));
-
-  // create result non-periodic B-spline curve
-  GeomShapePtr anEdge = GeomAlgoAPI_EdgeBuilder::bsplineOnPlane(aSketch->coordinatePlane(),
-      aPoles2D, aWeights, aKnots, aMults, aDegreeAttr->value(), false);
-
-  ResultConstructionPtr aResult = document()->createConstruction(data(), 0);
-  aResult->setShape(anEdge);
-  aResult->setIsInHistory(false);
-  setResult(aResult, 0);
-}
-
-bool SketchPlugin_BSpline::isFixed() {
-  return data()->selection(EXTERNAL_ID())->context().get() != NULL;
+  SketchPlugin_BSplineBase::initDerivedClassAttributes();
 }
 
 void SketchPlugin_BSpline::attributeChanged(const std::string& theID) {
-  // the second condition for unability to move external segments anywhere
-  if (theID == EXTERNAL_ID() || isFixed()) {
-    std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
-    if (!aSelection) {
-      // empty shape in selection shows that the shape is equal to context
-      ResultPtr anExtRes = selection(EXTERNAL_ID())->context();
-      if (anExtRes)
-        aSelection = anExtRes->shape();
-    }
-////    // update arguments due to the selection value
-////    if (aSelection && !aSelection->isNull() && aSelection->isEdge()) {
-////      std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aSelection));
-////      std::shared_ptr<GeomAPI_Ellipse> anEllipse = anEdge->ellipse();
-////
-////      bool aWasBlocked = data()->blockSendAttributeUpdated(true);
-////      std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
-////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_ID()));
-////      aCenterAttr->setValue(sketch()->to2D(anEllipse->center()));
-////
-////      std::shared_ptr<GeomDataAPI_Point2D> aFocusAttr =
-////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(FIRST_FOCUS_ID()));
-////      aFocusAttr->setValue(sketch()->to2D(anEllipse->firstFocus()));
-////
-////      std::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
-////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_ID()));
-////      aStartAttr->setValue(sketch()->to2D(anEdge->firstPoint()));
-////
-////      std::shared_ptr<GeomDataAPI_Point2D> aEndAttr =
-////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_ID()));
-////      aEndAttr->setValue(sketch()->to2D(anEdge->lastPoint()));
-////
-////      real(MAJOR_RADIUS_ID())->setValue(anEllipse->majorRadius());
-////      real(MINOR_RADIUS_ID())->setValue(anEllipse->minorRadius());
-////
-////      double aStartParam, aMidParam, aEndParam;
-////      anEllipse->parameter(anEdge->firstPoint(), tolerance, aStartParam);
-////      anEllipse->parameter(anEdge->middlePoint(), tolerance, aMidParam);
-////      anEllipse->parameter(anEdge->lastPoint(), tolerance, aEndParam);
-////      if (aEndParam < aStartParam)
-////        aEndParam += 2.0 * PI;
-////      if (aMidParam < aStartParam)
-////        aMidParam += 2.0 * PI;
-////      boolean(REVERSED_ID())->setValue(aMidParam > aEndParam);
-////
-////      data()->blockSendAttributeUpdated(aWasBlocked, false);
-////
-////      fillCharacteristicPoints();
-////    }
-  }
-  else if (theID == POLES_ID()) {
+  if (theID == POLES_ID()) {
     AttributePoint2DArrayPtr aPolesArray =
         std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
     std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
@@ -160,4 +45,6 @@ void SketchPlugin_BSpline::attributeChanged(const std::string& theID) {
     std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
         attribute(END_ID()))->setValue(aPolesArray->pnt(aPolesArray->size() - 1));
   }
+  else
+    SketchPlugin_BSplineBase::attributeChanged(theID);
 }
index a72126c91f87218a72ad6a6158a1520e9cd5b30d..ff27cd3a3d6b8bf37f13c1696cbb4cf04cc177b4 100644 (file)
 #ifndef SketchPlugin_BSpline_H_
 #define SketchPlugin_BSpline_H_
 
-#include <SketchPlugin.h>
-#include <SketchPlugin_SketchEntity.h>
+#include <SketchPlugin_BSplineBase.h>
 
 /**\class SketchPlugin_BSpline
  * \ingroup Plugins
  * \brief Feature for creation of the B-spline curve in the sketch.
  */
-class SketchPlugin_BSpline : public SketchPlugin_SketchEntity
+class SketchPlugin_BSpline : public SketchPlugin_BSplineBase
 {
 public:
-  /// Ellipse feature kind
+  /// B-spline feature kind
   inline static const std::string& ID()
   {
     static const std::string ID("SketchBSpline");
     return ID;
   }
 
-  /// list of B-spline poles
-  inline static const std::string& POLES_ID()
-  {
-    static const std::string ID("poles");
-    return ID;
-  }
-
-  /// list of B-spline weights
-  inline static const std::string& WEIGHTS_ID()
-  {
-    static const std::string ID("weights");
-    return ID;
-  }
-
-  /// attribute to store the degree of B-spline
-  inline static const std::string& DEGREE_ID()
-  {
-    static const std::string ID("degree");
-    return ID;
-  }
-
-  /// list of B-spline knots
-  inline static const std::string& KNOTS_ID()
-  {
-    static const std::string ID("knots");
-    return ID;
-  }
-
-  /// list of B-spline multiplicities
-  inline static const std::string& MULTS_ID()
-  {
-    static const std::string ID("multiplicities");
-    return ID;
-  }
-
   /// start point of B-spline curve
   inline static const std::string& START_ID()
   {
@@ -92,21 +56,17 @@ public:
     return MY_KIND;
   }
 
-  /// Returns true is sketch element is under the rigid constraint
-  SKETCHPLUGIN_EXPORT virtual bool isFixed();
-
   /// Called on change of any argument-attribute of this object
   SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
 
-  /// Creates a new part document if needed
-  SKETCHPLUGIN_EXPORT virtual void execute();
-
   /// Use plugin manager for features creation
   SketchPlugin_BSpline();
 
 protected:
   /// \brief Initializes attributes of derived class.
   virtual void initDerivedClassAttributes();
+
+  virtual bool isPeriodic() const { return false; }
 };
 
 #endif
diff --git a/src/SketchPlugin/SketchPlugin_BSplineBase.cpp b/src/SketchPlugin/SketchPlugin_BSplineBase.cpp
new file mode 100644 (file)
index 0000000..e39dfe6
--- /dev/null
@@ -0,0 +1,152 @@
+// Copyright (C) 2019-2020  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <SketchPlugin_BSplineBase.h>
+#include <SketchPlugin_Sketch.h>
+
+#include <GeomAlgoAPI_EdgeBuilder.h>
+
+#include <GeomAPI_Pnt2d.h>
+
+#include <GeomDataAPI_Point2D.h>
+#include <GeomDataAPI_Point2DArray.h>
+
+#include <ModelAPI_AttributeDoubleArray.h>
+#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+
+SketchPlugin_BSplineBase::SketchPlugin_BSplineBase()
+  : SketchPlugin_SketchEntity()
+{
+}
+
+void SketchPlugin_BSplineBase::initDerivedClassAttributes()
+{
+  data()->addAttribute(POLES_ID(), GeomDataAPI_Point2DArray::typeId());
+  data()->addAttribute(WEIGHTS_ID(), ModelAPI_AttributeDoubleArray::typeId());
+  data()->addAttribute(KNOTS_ID(), ModelAPI_AttributeDoubleArray::typeId());
+  data()->addAttribute(MULTS_ID(), ModelAPI_AttributeIntArray::typeId());
+  data()->addAttribute(DEGREE_ID(), ModelAPI_AttributeInteger::typeId());
+
+  data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
+}
+
+void SketchPlugin_BSplineBase::execute()
+{
+  SketchPlugin_Sketch* aSketch = sketch();
+  if(!aSketch) {
+    return;
+  }
+
+  AttributePoint2DArrayPtr aPolesArray =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
+  AttributeDoubleArrayPtr aWeightsArray = data()->realArray(WEIGHTS_ID());
+  AttributeDoubleArrayPtr aKnotsArray = data()->realArray(KNOTS_ID());
+  AttributeIntArrayPtr aMultsArray = data()->intArray(MULTS_ID());
+  AttributeIntegerPtr aDegreeAttr = data()->integer(DEGREE_ID());
+
+  // collect poles
+  std::list<GeomPnt2dPtr> aPoles2D;
+  for (int anIndex = 0; anIndex < aPolesArray->size(); ++anIndex) {
+    GeomPnt2dPtr aPole = aPolesArray->pnt(anIndex);
+    aPoles2D.push_back(aPole);
+  }
+  // collect weights
+  std::list<double> aWeights;
+  for (int anIndex = 0; anIndex < aWeightsArray->size(); ++anIndex)
+    aWeights.push_back(aWeightsArray->value(anIndex));
+  // collect knots
+  std::list<double> aKnots;
+  for (int anIndex = 0; anIndex < aKnotsArray->size(); ++anIndex)
+    aKnots.push_back(aKnotsArray->value(anIndex));
+  // collect multiplicities
+  std::list<int> aMults;
+  for (int anIndex = 0; anIndex < aMultsArray->size(); ++anIndex)
+    aMults.push_back(aMultsArray->value(anIndex));
+
+  // create result B-spline curve
+  GeomShapePtr anEdge = GeomAlgoAPI_EdgeBuilder::bsplineOnPlane(aSketch->coordinatePlane(),
+      aPoles2D, aWeights, aKnots, aMults, aDegreeAttr->value(), isPeriodic());
+
+  ResultConstructionPtr aResult = document()->createConstruction(data(), 0);
+  aResult->setShape(anEdge);
+  aResult->setIsInHistory(false);
+  setResult(aResult, 0);
+}
+
+bool SketchPlugin_BSplineBase::isFixed() {
+  return data()->selection(EXTERNAL_ID())->context().get() != NULL;
+}
+
+void SketchPlugin_BSplineBase::attributeChanged(const std::string& theID) {
+  // the second condition for unability to move external segments anywhere
+  if (theID == EXTERNAL_ID() || isFixed()) {
+    std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
+    if (!aSelection) {
+      // empty shape in selection shows that the shape is equal to context
+      ResultPtr anExtRes = selection(EXTERNAL_ID())->context();
+      if (anExtRes)
+        aSelection = anExtRes->shape();
+    }
+////    // update arguments due to the selection value
+////    if (aSelection && !aSelection->isNull() && aSelection->isEdge()) {
+////      std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aSelection));
+////      std::shared_ptr<GeomAPI_Ellipse> anEllipse = anEdge->ellipse();
+////
+////      bool aWasBlocked = data()->blockSendAttributeUpdated(true);
+////      std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
+////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_ID()));
+////      aCenterAttr->setValue(sketch()->to2D(anEllipse->center()));
+////
+////      std::shared_ptr<GeomDataAPI_Point2D> aFocusAttr =
+////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(FIRST_FOCUS_ID()));
+////      aFocusAttr->setValue(sketch()->to2D(anEllipse->firstFocus()));
+////
+////      std::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
+////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_ID()));
+////      aStartAttr->setValue(sketch()->to2D(anEdge->firstPoint()));
+////
+////      std::shared_ptr<GeomDataAPI_Point2D> aEndAttr =
+////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_ID()));
+////      aEndAttr->setValue(sketch()->to2D(anEdge->lastPoint()));
+////
+////      real(MAJOR_RADIUS_ID())->setValue(anEllipse->majorRadius());
+////      real(MINOR_RADIUS_ID())->setValue(anEllipse->minorRadius());
+////
+////      double aStartParam, aMidParam, aEndParam;
+////      anEllipse->parameter(anEdge->firstPoint(), tolerance, aStartParam);
+////      anEllipse->parameter(anEdge->middlePoint(), tolerance, aMidParam);
+////      anEllipse->parameter(anEdge->lastPoint(), tolerance, aEndParam);
+////      if (aEndParam < aStartParam)
+////        aEndParam += 2.0 * PI;
+////      if (aMidParam < aStartParam)
+////        aMidParam += 2.0 * PI;
+////      boolean(REVERSED_ID())->setValue(aMidParam > aEndParam);
+////
+////      data()->blockSendAttributeUpdated(aWasBlocked, false);
+////
+////      fillCharacteristicPoints();
+////    }
+  }
+}
diff --git a/src/SketchPlugin/SketchPlugin_BSplineBase.h b/src/SketchPlugin/SketchPlugin_BSplineBase.h
new file mode 100644 (file)
index 0000000..d84a17a
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2019-2020  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef SketchPlugin_BSplineBase_H_
+#define SketchPlugin_BSplineBase_H_
+
+#include <SketchPlugin.h>
+#include <SketchPlugin_SketchEntity.h>
+
+/**\class SketchPlugin_BSplineBase
+ * \ingroup Plugins
+ * \brief Base class for B-spline curves in the sketch.
+ */
+class SketchPlugin_BSplineBase : public SketchPlugin_SketchEntity
+{
+public:
+  /// list of B-spline poles
+  inline static const std::string& POLES_ID()
+  {
+    static const std::string ID("poles");
+    return ID;
+  }
+
+  /// list of B-spline weights
+  inline static const std::string& WEIGHTS_ID()
+  {
+    static const std::string ID("weights");
+    return ID;
+  }
+
+  /// attribute to store the degree of B-spline
+  inline static const std::string& DEGREE_ID()
+  {
+    static const std::string ID("degree");
+    return ID;
+  }
+
+  /// list of B-spline knots
+  inline static const std::string& KNOTS_ID()
+  {
+    static const std::string ID("knots");
+    return ID;
+  }
+
+  /// list of B-spline multiplicities
+  inline static const std::string& MULTS_ID()
+  {
+    static const std::string ID("multiplicities");
+    return ID;
+  }
+
+  /// Returns true is sketch element is under the rigid constraint
+  SKETCHPLUGIN_EXPORT virtual bool isFixed();
+
+  /// Called on change of any argument-attribute of this object
+  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
+  /// Creates a new part document if needed
+  SKETCHPLUGIN_EXPORT virtual void execute();
+
+protected:
+  /// Called from the derived class
+  SketchPlugin_BSplineBase();
+
+  /// \brief Initializes attributes of derived class.
+  virtual void initDerivedClassAttributes();
+
+  /// \brief Return \c true if the B-spline curve is periodic
+  virtual bool isPeriodic() const = 0;
+};
+
+#endif
index a20ec2abf534acd8175100276bc79776699046a9..eb5fa748a1bcd21fcd55d58cdb2d2941ca0f7540 100644 (file)
 //
 
 #include <SketchPlugin_BSplinePeriodic.h>
-#include <SketchPlugin_Sketch.h>
-
-#include <GeomAlgoAPI_EdgeBuilder.h>
-
-#include <GeomAPI_Pnt2d.h>
-
-#include <GeomDataAPI_Point2D.h>
-#include <GeomDataAPI_Point2DArray.h>
-
-#include <ModelAPI_AttributeDoubleArray.h>
-#include <ModelAPI_AttributeIntArray.h>
-#include <ModelAPI_AttributeInteger.h>
-#include <ModelAPI_ResultConstruction.h>
-#include <ModelAPI_Session.h>
-#include <ModelAPI_Validator.h>
-
 
 SketchPlugin_BSplinePeriodic::SketchPlugin_BSplinePeriodic()
-  : SketchPlugin_SketchEntity()
-{
-}
-
-void SketchPlugin_BSplinePeriodic::initDerivedClassAttributes()
-{
-  data()->addAttribute(POLES_ID(), GeomDataAPI_Point2DArray::typeId());
-  data()->addAttribute(WEIGHTS_ID(), ModelAPI_AttributeDoubleArray::typeId());
-  data()->addAttribute(KNOTS_ID(), ModelAPI_AttributeDoubleArray::typeId());
-  data()->addAttribute(MULTS_ID(), ModelAPI_AttributeIntArray::typeId());
-  data()->addAttribute(DEGREE_ID(), ModelAPI_AttributeInteger::typeId());
-
-  data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
-}
-
-void SketchPlugin_BSplinePeriodic::execute()
+  : SketchPlugin_BSplineBase()
 {
-  SketchPlugin_Sketch* aSketch = sketch();
-  if(!aSketch) {
-    return;
-  }
-
-  AttributePoint2DArrayPtr aPolesArray =
-      std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(attribute(POLES_ID()));
-  AttributeDoubleArrayPtr aWeightsArray = data()->realArray(WEIGHTS_ID());
-  AttributeDoubleArrayPtr aKnotsArray = data()->realArray(KNOTS_ID());
-  AttributeIntArrayPtr aMultsArray = data()->intArray(MULTS_ID());
-  AttributeIntegerPtr aDegreeAttr = data()->integer(DEGREE_ID());
-
-  // collect poles
-  std::list<GeomPnt2dPtr> aPoles2D;
-  for (int anIndex = 0; anIndex < aPolesArray->size(); ++anIndex) {
-    GeomPnt2dPtr aPole = aPolesArray->pnt(anIndex);
-    aPoles2D.push_back(aPole);
-  }
-  // collect weights
-  std::list<double> aWeights;
-  for (int anIndex = 0; anIndex < aWeightsArray->size(); ++anIndex)
-    aWeights.push_back(aWeightsArray->value(anIndex));
-  // collect knots
-  std::list<double> aKnots;
-  for (int anIndex = 0; anIndex < aKnotsArray->size(); ++anIndex)
-    aKnots.push_back(aKnotsArray->value(anIndex));
-  // collect multiplicities
-  std::list<int> aMults;
-  for (int anIndex = 0; anIndex < aMultsArray->size(); ++anIndex)
-    aMults.push_back(aMultsArray->value(anIndex));
-
-  // create result non-periodic B-spline curve
-  GeomShapePtr anEdge = GeomAlgoAPI_EdgeBuilder::bsplineOnPlane(aSketch->coordinatePlane(),
-      aPoles2D, aWeights, aKnots, aMults, aDegreeAttr->value(), true);
-
-  ResultConstructionPtr aResult = document()->createConstruction(data(), 0);
-  aResult->setShape(anEdge);
-  aResult->setIsInHistory(false);
-  setResult(aResult, 0);
-}
-
-bool SketchPlugin_BSplinePeriodic::isFixed() {
-  return data()->selection(EXTERNAL_ID())->context().get() != NULL;
-}
-
-void SketchPlugin_BSplinePeriodic::attributeChanged(const std::string& theID) {
-  // the second condition for unability to move external segments anywhere
-  if (theID == EXTERNAL_ID() || isFixed()) {
-    std::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
-    if (!aSelection) {
-      // empty shape in selection shows that the shape is equal to context
-      ResultPtr anExtRes = selection(EXTERNAL_ID())->context();
-      if (anExtRes)
-        aSelection = anExtRes->shape();
-    }
-////    // update arguments due to the selection value
-////    if (aSelection && !aSelection->isNull() && aSelection->isEdge()) {
-////      std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aSelection));
-////      std::shared_ptr<GeomAPI_Ellipse> anEllipse = anEdge->ellipse();
-////
-////      bool aWasBlocked = data()->blockSendAttributeUpdated(true);
-////      std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
-////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_ID()));
-////      aCenterAttr->setValue(sketch()->to2D(anEllipse->center()));
-////
-////      std::shared_ptr<GeomDataAPI_Point2D> aFocusAttr =
-////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(FIRST_FOCUS_ID()));
-////      aFocusAttr->setValue(sketch()->to2D(anEllipse->firstFocus()));
-////
-////      std::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
-////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_ID()));
-////      aStartAttr->setValue(sketch()->to2D(anEdge->firstPoint()));
-////
-////      std::shared_ptr<GeomDataAPI_Point2D> aEndAttr =
-////        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_ID()));
-////      aEndAttr->setValue(sketch()->to2D(anEdge->lastPoint()));
-////
-////      real(MAJOR_RADIUS_ID())->setValue(anEllipse->majorRadius());
-////      real(MINOR_RADIUS_ID())->setValue(anEllipse->minorRadius());
-////
-////      double aStartParam, aMidParam, aEndParam;
-////      anEllipse->parameter(anEdge->firstPoint(), tolerance, aStartParam);
-////      anEllipse->parameter(anEdge->middlePoint(), tolerance, aMidParam);
-////      anEllipse->parameter(anEdge->lastPoint(), tolerance, aEndParam);
-////      if (aEndParam < aStartParam)
-////        aEndParam += 2.0 * PI;
-////      if (aMidParam < aStartParam)
-////        aMidParam += 2.0 * PI;
-////      boolean(REVERSED_ID())->setValue(aMidParam > aEndParam);
-////
-////      data()->blockSendAttributeUpdated(aWasBlocked, false);
-////
-////      fillCharacteristicPoints();
-////    }
-  }
 }
index 80e6bfaec47c2b37cd371e09976d1f9802179b37..b5b4e625ddbecb4b2645bb91e38ad154cfca38ee 100644 (file)
 #ifndef SketchPlugin_BSplinePeriodic_H_
 #define SketchPlugin_BSplinePeriodic_H_
 
-#include <SketchPlugin.h>
-#include <SketchPlugin_SketchEntity.h>
+#include <SketchPlugin_BSplineBase.h>
 
 /**\class SketchPlugin_BSplinePeriodic
  * \ingroup Plugins
  * \brief Feature for creation of the periodic B-spline curve in the sketch.
  */
-class SketchPlugin_BSplinePeriodic : public SketchPlugin_SketchEntity
+class SketchPlugin_BSplinePeriodic : public SketchPlugin_BSplineBase
 {
 public:
-  /// Ellipse feature kind
+  /// B-spline feature kind
   inline static const std::string& ID()
   {
     static const std::string ID("SketchBSplinePeriodic");
     return ID;
   }
 
-  /// list of B-spline poles
-  inline static const std::string& POLES_ID()
-  {
-    static const std::string ID("poles");
-    return ID;
-  }
-
-  /// list of B-spline weights
-  inline static const std::string& WEIGHTS_ID()
-  {
-    static const std::string ID("weights");
-    return ID;
-  }
-
-  /// attribute to store the degree of B-spline
-  inline static const std::string& DEGREE_ID()
-  {
-    static const std::string ID("degree");
-    return ID;
-  }
-
-  /// list of B-spline knots
-  inline static const std::string& KNOTS_ID()
-  {
-    static const std::string ID("knots");
-    return ID;
-  }
-
-  /// list of B-spline multiplicities
-  inline static const std::string& MULTS_ID()
-  {
-    static const std::string ID("multiplicities");
-    return ID;
-  }
-
   /// Returns the kind of a feature
   SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
   {
@@ -79,21 +43,11 @@ public:
     return MY_KIND;
   }
 
-  /// Returns true is sketch element is under the rigid constraint
-  SKETCHPLUGIN_EXPORT virtual bool isFixed();
-
-  /// Called on change of any argument-attribute of this object
-  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
-
-  /// Creates a new part document if needed
-  SKETCHPLUGIN_EXPORT virtual void execute();
-
   /// Use plugin manager for features creation
   SketchPlugin_BSplinePeriodic();
 
 protected:
-  /// \brief Initializes attributes of derived class.
-  virtual void initDerivedClassAttributes();
+  virtual bool isPeriodic() const { return true; }
 };
 
 #endif