]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fix incorrect processing of the copied entities after the "Multi" constraint has...
authorazv <azv@opencascade.com>
Tue, 16 May 2017 12:54:43 +0000 (15:54 +0300)
committerazv <azv@opencascade.com>
Tue, 16 May 2017 14:34:26 +0000 (17:34 +0300)
14 files changed:
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_AttributeBuilder.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_AttributeBuilder.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_EntityBuilder.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_EntityDestroyer.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_FeatureBuilder.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_FeatureBuilder.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.h
src/SketchSolver/SketchSolver_ConstraintMulti.cpp
src/SketchSolver/SketchSolver_Storage.h

index a6feb1f9ea6b3c099eb7cea4f931661b867aeeaa..c85a2d163abe3f93f444016ebee7e2b458e17c0d 100644 (file)
@@ -90,9 +90,3 @@ EntityWrapperPtr PlaneGCSSolver_AttributeBuilder::createAttribute(
     aResult->setExternal(true);
   return aResult;
 }
-
-const std::list<GCSConstraintPtr>& PlaneGCSSolver_AttributeBuilder::constraints() const
-{
-  static std::list<GCSConstraintPtr> aList;
-  return aList;
-}
index 4c8e44ed6dc6b2eccfe6564889a7178bbe34d27c..28c182a2fcd949d6092398fd2f283feb154d67c3 100644 (file)
@@ -28,9 +28,6 @@ public:
   /// \brief Blank. To be defined in derived class.
   virtual EntityWrapperPtr createFeature(FeaturePtr)
   { return EntityWrapperPtr(); }
-
-  /// \brief Blank. To be defined in derived class.
-  virtual const std::list<GCSConstraintPtr>& constraints() const;
 };
 
 #endif
index d4eb9d9d2d3377298eb89850149914b284491b58..94279ee81359828dadff422b23c5a115d899e098 100644 (file)
@@ -37,9 +37,6 @@ public:
   /// \param theFeature [in]  feature to create
   virtual EntityWrapperPtr createFeature(FeaturePtr) = 0;
 
-  /// \brief Return list of constraints necessary to fix feature's extra DoF
-  virtual const std::list<GCSConstraintPtr>& constraints() const = 0;
-
 protected:
   PlaneGCSSolver_Storage* myStorage;
 };
index 97a3b83f05bf067f26295d53d0cf5299c70c04df..7b93798ffe41b6ca4b29a9dc8d974efc86b70c68 100644 (file)
@@ -9,79 +9,13 @@
 #include <PlaneGCSSolver_PointWrapper.h>
 #include <PlaneGCSSolver_ScalarWrapper.h>
 #include <PlaneGCSSolver_EdgeWrapper.h>
-
-static void destroyScalar(const EntityWrapperPtr& theEntity, GCS::SET_pD& theParams)
-{
-  ScalarWrapperPtr aScalar = std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(theEntity);
-  theParams.insert(aScalar->scalar());
-}
-
-static void destroyPoint(const EntityWrapperPtr& theEntity, GCS::SET_pD& theParams)
-{
-  std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
-      std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theEntity);
-  theParams.insert(aPoint->point()->x);
-  theParams.insert(aPoint->point()->y);
-}
-
-static void destroyLine(const EntityWrapperPtr& theEntity, GCS::SET_pD& theParams)
-{
-  std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
-      std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
-  std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(anEntity->entity());
-  theParams.insert(aLine->p1.x);
-  theParams.insert(aLine->p1.y);
-  theParams.insert(aLine->p2.x);
-  theParams.insert(aLine->p2.y);
-}
-
-static void destroyCircle(const EntityWrapperPtr& theEntity, GCS::SET_pD& theParams)
-{
-  std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
-      std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
-  std::shared_ptr<GCS::Circle> aCirc = std::dynamic_pointer_cast<GCS::Circle>(anEntity->entity());
-  theParams.insert(aCirc->center.x);
-  theParams.insert(aCirc->center.y);
-  theParams.insert(aCirc->rad);
-}
-
-static void destroyArc(const EntityWrapperPtr& theEntity, GCS::SET_pD& theParams)
-{
-  std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
-      std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
-  std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEntity->entity());
-  theParams.insert(anArc->center.x);
-  theParams.insert(anArc->center.y);
-  theParams.insert(anArc->start.x);
-  theParams.insert(anArc->start.y);
-  theParams.insert(anArc->end.x);
-  theParams.insert(anArc->end.y);
-  theParams.insert(anArc->startAngle);
-  theParams.insert(anArc->endAngle);
-  theParams.insert(anArc->rad);
-}
+#include <PlaneGCSSolver_Tools.h>
 
 void PlaneGCSSolver_EntityDestroyer::remove(const EntityWrapperPtr& theEntity)
 {
-  GCS::SET_pD& aParamSet = theEntity->isExternal() ? myParamsOutOfStorage : myParams;
-
-  switch (theEntity->type()) {
-  case ENTITY_SCALAR:
-  case ENTITY_ANGLE:
-    destroyScalar(theEntity, aParamSet);
-    break;
-  case ENTITY_POINT:
-    destroyPoint(theEntity, aParamSet);
-    break;
-  case ENTITY_LINE:
-    destroyLine(theEntity, aParamSet);
-    break;
-  case ENTITY_CIRCLE:
-    destroyCircle(theEntity, aParamSet);
-    break;
-  case ENTITY_ARC:
-    destroyArc(theEntity, aParamSet);
-    break;
-  default: break;
-  }
+  GCS::SET_pD aParameters = PlaneGCSSolver_Tools::parameters(theEntity);
+  if (theEntity->isExternal())
+    myParamsOutOfStorage.insert(aParameters.begin(), aParameters.end());
+  else
+    myParams.insert(aParameters.begin(), aParameters.end());
 }
index e9cf468a9aa7e8c1ab2c9dac0f8b7212172a6634..035d6c895d6741453d427900f13e20e8c3c060f4 100644 (file)
@@ -25,8 +25,7 @@ static bool isAttributeApplicable(const std::string& theAttrName,
 static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
 static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
 static EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
-                                  PlaneGCSSolver_Storage*      theStorage,
-                                  std::list<GCSConstraintPtr>& theArcConstraints);
+                                  PlaneGCSSolver_Storage*      theStorage);
 
 
 PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
@@ -76,7 +75,7 @@ EntityWrapperPtr PlaneGCSSolver_FeatureBuilder::createFeature(FeaturePtr theFeat
     aResult = createCircle(myAttributes);
   // Arc
   else if (aFeatureKind == SketchPlugin_Arc::ID())
-    aResult = createArc(myAttributes, myStorage, myFeatureConstraints);
+    aResult = createArc(myAttributes, myStorage);
   // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
   else if (aFeatureKind == SketchPlugin_Point::ID() ||
            aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
@@ -147,8 +146,7 @@ static double* createParameter(PlaneGCSSolver_Storage* theStorage)
 }
 
 EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
-                           PlaneGCSSolver_Storage*      theStorage,
-                           std::list<GCSConstraintPtr>& theArcConstraints)
+                           PlaneGCSSolver_Storage*      theStorage)
 {
   std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
 
@@ -189,20 +187,6 @@ EntityWrapperPtr createArc(const AttributeEntityMap&    theAttributes,
       new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
   *aNewArc->endAngle = OX->angle(aDir);
 
-  if (theStorage) {
-    // Additional constaints to fix arc's extra DoF (if the arc is not external):
-    // 1. distances from center till start and end points are equal to radius
-    theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
-        aNewArc->center, aNewArc->start, aNewArc->rad)));
-    theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
-        aNewArc->center, aNewArc->end, aNewArc->rad)));
-    // 2. angles of start and end points should be equal to the arc angles
-    theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
-        aNewArc->center, aNewArc->start, aNewArc->startAngle)));
-    theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
-        aNewArc->center, aNewArc->end, aNewArc->endAngle)));
-  }
-
   return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewArc));
 }
 
index af796cda3545eacb8343599ef275d15310f564b9..fc3a98beafc0b2bed8ca35be60a36e1be0d56276 100644 (file)
@@ -32,17 +32,9 @@ public:
   /// \param theFeature [in]  feature to create
   virtual EntityWrapperPtr createFeature(FeaturePtr theFeature);
 
-  /// \brief Return list of constraints necessary to fix feature's extra DoF
-  virtual const std::list<GCSConstraintPtr>& constraints() const
-  { return myFeatureConstraints; }
-
 private:
   /// list of converted attributes (will be cleared when the feature is created)
   AttributeEntityMap myAttributes;
-
-  /// constraints for the feature
-  /// (primarily used for constrain arcs, which have 9 parameters but 5 DoF)
-  std::list<GCSConstraintPtr> myFeatureConstraints;
 };
 
 #endif
index d06446e6f534ccb4d22fe7c0845a60f74e77c6a7..57529dc35510836b69f62ac5f02261abaf3ffd44 100644 (file)
@@ -63,6 +63,22 @@ double* PlaneGCSSolver_Solver::createParameter()
   return aResult;
 }
 
+void PlaneGCSSolver_Solver::addParameters(const GCS::SET_pD& theParams)
+{
+  GCS::SET_pD aParams(theParams);
+  // leave new parameters only
+  GCS::VEC_pD::iterator anIt = myParameters.begin();
+  for (; anIt != myParameters.end(); ++anIt)
+    if (aParams.find(*anIt) != aParams.end())
+      aParams.erase(*anIt);
+
+  myParameters.insert(myParameters.end(), aParams.begin(), aParams.end());
+  if (myConstraints.empty() && myDOF >=0)
+    myDOF += (int)aParams.size(); // calculate DoF by hand if and only if there is no constraints yet
+  else
+    myDiagnoseBeforeSolve = true;
+}
+
 void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams)
 {
   for (int i = (int)myParameters.size() - 1; i >= 0; --i)
@@ -70,6 +86,8 @@ void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams)
       myParameters.erase(myParameters.begin() + i);
       --myDOF;
     }
+  if (!myConstraints.empty())
+    myDiagnoseBeforeSolve = true;
 }
 
 void PlaneGCSSolver_Solver::initialize()
index cb195ada3b7ba2b7e1dd79e4d22c881fc3a2d8f5..19faa221b7571eb92d5306897b3d23f385fc9283 100644 (file)
@@ -39,6 +39,8 @@ public:
 
   /// \brief Initialize memory for new solver's parameter
   double* createParameter();
+  /// \brief Add parameters created elsewhere
+  void addParameters(const GCS::SET_pD& theParams);
   /// \brief Release memory occupied by parameters
   void removeParameters(const GCS::SET_pD& theParams);
 
index 64d9c7fb5512754b5c7391c83411aa31ec72e23a..e70ec733737bd116f37bcec2e15a2f5c43234498 100644 (file)
@@ -9,6 +9,7 @@
 #include <PlaneGCSSolver_ConstraintWrapper.h>
 #include <PlaneGCSSolver_EdgeWrapper.h>
 #include <PlaneGCSSolver_PointWrapper.h>
+#include <PlaneGCSSolver_Tools.h>
 
 #include <PlaneGCSSolver_AttributeBuilder.h>
 #include <PlaneGCSSolver_FeatureBuilder.h>
@@ -176,17 +177,7 @@ bool PlaneGCSSolver_Storage::update(FeaturePtr theFeature, bool theForce)
     // (do not want to add several copies of it while adding attributes)
     aRelated = createFeature(theFeature, &aBuilder);
     myFeatureMap[theFeature] = aRelated;
-
-    const std::list<GCSConstraintPtr>& aConstraints = aBuilder.constraints();
-    if (!aConstraints.empty()) { // the feature is arc
-      /// TODO: avoid this workaround
-      ConstraintWrapperPtr aWrapper(
-          new PlaneGCSSolver_ConstraintWrapper(aConstraints, CONSTRAINT_UNKNOWN));
-      aWrapper->setId(++myConstraintLastID);
-      constraintsToSolver(aWrapper, mySketchSolver);
-
-      myArcConstraintMap[myFeatureMap[theFeature]] = aWrapper;
-    }
+    createArcConstraints(aRelated);
     isUpdated = true;
   }
 
@@ -263,6 +254,72 @@ bool PlaneGCSSolver_Storage::update(AttributePtr theAttribute, bool theForce)
   return isUpdated;
 }
 
+void PlaneGCSSolver_Storage::makeExternal(const EntityWrapperPtr& theEntity)
+{
+  if (theEntity->isExternal())
+    return;
+
+  removeArcConstraints(theEntity);
+
+  GCS::SET_pD aParameters = PlaneGCSSolver_Tools::parameters(theEntity);
+  mySketchSolver->removeParameters(aParameters);
+  theEntity->setExternal(true);
+  myNeedToResolve = true;
+}
+
+void PlaneGCSSolver_Storage::makeNonExternal(const EntityWrapperPtr& theEntity)
+{
+  if (!theEntity->isExternal())
+    return;
+
+  GCS::SET_pD aParameters = PlaneGCSSolver_Tools::parameters(theEntity);
+  mySketchSolver->addParameters(aParameters);
+  theEntity->setExternal(false);
+
+  createArcConstraints(theEntity);
+
+  myNeedToResolve = true;
+}
+
+
+void PlaneGCSSolver_Storage::createArcConstraints(const EntityWrapperPtr& theArc)
+{
+  if (theArc->type() != ENTITY_ARC || theArc->isExternal())
+    return;
+
+  EdgeWrapperPtr anEdge = std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theArc);
+  std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEdge->entity());
+
+  // Additional constaints to fix arc's extra DoF (if the arc is not external):
+  std::list<GCSConstraintPtr> anArcConstraints;
+  // 1. distances from center till start and end points are equal to radius
+  anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
+      anArc->center, anArc->start, anArc->rad)));
+  anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
+      anArc->center, anArc->end, anArc->rad)));
+  // 2. angles of start and end points should be equal to the arc angles
+  anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
+      anArc->center, anArc->start, anArc->startAngle)));
+  anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
+      anArc->center, anArc->end, anArc->endAngle)));
+
+  ConstraintWrapperPtr aWrapper(
+      new PlaneGCSSolver_ConstraintWrapper(anArcConstraints, CONSTRAINT_UNKNOWN));
+  aWrapper->setId(++myConstraintLastID);
+  constraintsToSolver(aWrapper, mySketchSolver);
+
+  myArcConstraintMap[theArc] = aWrapper;
+}
+
+void PlaneGCSSolver_Storage::removeArcConstraints(const EntityWrapperPtr& theArc)
+{
+  std::map<EntityWrapperPtr, ConstraintWrapperPtr>::iterator
+      aFound = myArcConstraintMap.find(theArc);
+  if (aFound != myArcConstraintMap.end()) {
+    mySketchSolver->removeConstraint(aFound->second->id());
+    myArcConstraintMap.erase(aFound);
+  }
+}
 
 
 bool PlaneGCSSolver_Storage::removeConstraint(ConstraintPtr theConstraint)
@@ -321,12 +378,7 @@ void PlaneGCSSolver_Storage::removeInvalidEntities()
         aDestroyer.remove(aFIter->second);
 
       // remove invalid arc
-      std::map<EntityWrapperPtr, ConstraintWrapperPtr>::iterator
-          aFound = myArcConstraintMap.find(aFIter->second);
-      if (aFound != myArcConstraintMap.end()) {
-        mySketchSolver->removeConstraint(aFound->second->id());
-        myArcConstraintMap.erase(aFound);
-      }
+      removeArcConstraints(aFIter->second);
     }
   std::list<FeaturePtr>::const_iterator anInvFIt = anInvalidFeatures.begin();
   for (; anInvFIt != anInvalidFeatures.end(); ++anInvFIt)
index c7e1d1edaddfa79db572503617f31f45176036e1..6b8bc66e3e98e6f6e6908938744273ef78ee42a3 100644 (file)
@@ -48,6 +48,10 @@ public:
   /// \return \c true if the attribute has been created or updated
   virtual bool update(AttributePtr theAttribute, bool theForce = false);
 
+  /// \brief Make entity external
+  virtual void makeExternal(const EntityWrapperPtr& theEntity);
+  /// \brief Make entity non-external
+  virtual void makeNonExternal(const EntityWrapperPtr& theEntity);
 
   /// \brief Removes constraint from the storage
   /// \return \c true if the constraint and all its parameters are removed successfully
@@ -77,6 +81,9 @@ private:
   EntityWrapperPtr createAttribute(const AttributePtr&           theAttribute,
                                    PlaneGCSSolver_EntityBuilder* theBuilder);
 
+  void createArcConstraints(const EntityWrapperPtr& theArc);
+  void removeArcConstraints(const EntityWrapperPtr& theArc);
+
 private:
   ConstraintID myConstraintLastID;   ///< identifier of last added constraint
 
index 63813ba7555663d5512928142132a8b33008dead..35c3ed8607b79abc6bcbec3df2c1d9bb49832cb0 100644 (file)
@@ -88,6 +88,12 @@ static ConstraintWrapperPtr
   createConstraintMiddlePoint(std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint,
                               std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity);
 
+static GCS::SET_pD scalarParameters(const ScalarWrapperPtr& theScalar);
+static GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint);
+static GCS::SET_pD lineParameters(const EdgeWrapperPtr& theLine);
+static GCS::SET_pD circleParameters(const EdgeWrapperPtr& theCircle);
+static GCS::SET_pD arcParameters(const EdgeWrapperPtr& theArc);
+
 
 
 
@@ -242,6 +248,27 @@ std::shared_ptr<GeomAPI_Lin2d> PlaneGCSSolver_Tools::line(FeaturePtr theFeature)
 }
 
 
+GCS::SET_pD PlaneGCSSolver_Tools::parameters(const EntityWrapperPtr& theEntity)
+{
+  switch (theEntity->type()) {
+  case ENTITY_SCALAR:
+  case ENTITY_ANGLE:
+    return scalarParameters(GCS_SCALAR_WRAPPER(theEntity));
+  case ENTITY_POINT:
+    return pointParameters(GCS_POINT_WRAPPER(theEntity));
+  case ENTITY_LINE:
+    return lineParameters(GCS_EDGE_WRAPPER(theEntity));
+  case ENTITY_CIRCLE:
+    return circleParameters(GCS_EDGE_WRAPPER(theEntity));
+  case ENTITY_ARC:
+    return arcParameters(GCS_EDGE_WRAPPER(theEntity));
+  default: break;
+  }
+  return GCS::SET_pD();
+}
+
+
+
 
 
 
@@ -454,3 +481,55 @@ ConstraintWrapperPtr createConstraintEqual(
     aResult->setValueParameter(theIntermed);
   return aResult;
 }
+
+GCS::SET_pD scalarParameters(const ScalarWrapperPtr& theScalar)
+{
+  GCS::SET_pD aParams;
+  aParams.insert(theScalar->scalar());
+  return aParams;
+}
+
+GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint)
+{
+  GCS::SET_pD aParams;
+  aParams.insert(thePoint->point()->x);
+  aParams.insert(thePoint->point()->y);
+  return aParams;
+}
+
+GCS::SET_pD lineParameters(const EdgeWrapperPtr& theLine)
+{
+  GCS::SET_pD aParams;
+  std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(theLine->entity());
+  aParams.insert(aLine->p1.x);
+  aParams.insert(aLine->p1.y);
+  aParams.insert(aLine->p2.x);
+  aParams.insert(aLine->p2.y);
+  return aParams;
+}
+
+GCS::SET_pD circleParameters(const EdgeWrapperPtr& theCircle)
+{
+  GCS::SET_pD aParams;
+  std::shared_ptr<GCS::Circle> aCirc = std::dynamic_pointer_cast<GCS::Circle>(theCircle->entity());
+  aParams.insert(aCirc->center.x);
+  aParams.insert(aCirc->center.y);
+  aParams.insert(aCirc->rad);
+  return aParams;
+}
+
+GCS::SET_pD arcParameters(const EdgeWrapperPtr& theArc)
+{
+  GCS::SET_pD aParams;
+  std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(theArc->entity());
+  aParams.insert(anArc->center.x);
+  aParams.insert(anArc->center.y);
+  aParams.insert(anArc->start.x);
+  aParams.insert(anArc->start.y);
+  aParams.insert(anArc->end.x);
+  aParams.insert(anArc->end.y);
+  aParams.insert(anArc->startAngle);
+  aParams.insert(anArc->endAngle);
+  aParams.insert(anArc->rad);
+  return aParams;
+}
index 4e43206c177ce64032ca3680939eee913d8fe426..358ac8ae27adbce00cfa32b50fc3494a8df041b6 100644 (file)
@@ -56,6 +56,9 @@ namespace PlaneGCSSolver_Tools
   /// \brief Convert entity to line
   /// \return empty pointer if the entity is not a line
   std::shared_ptr<GeomAPI_Lin2d> line(FeaturePtr theFeature);
+
+  /// brief Return list of parameters for the given entity
+  GCS::SET_pD parameters(const EntityWrapperPtr& theEntity);
 };
 
 #endif
index 41289a7fb34bd5709e1e5beda660fb8f5a974c9d..c9b1a338bfba203ba0fc727ef1262103eb9f53e6 100644 (file)
 #include <SketchPlugin_Point.h>
 #include <SketchPlugin_IntersectionPoint.h>
 
+static void createCopiedEntity(const FeaturePtr& theFeature, const StoragePtr& theStorage)
+{
+  EntityWrapperPtr anEntity = theStorage->entity(theFeature);
+  if (anEntity) {
+    std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+        std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
+    if (!anEntity->isExternal() && aSketchFeature->isCopy())
+      theStorage->makeExternal(anEntity);
+  }
+}
+
 void SketchSolver_ConstraintMulti::getEntities(std::list<EntityWrapperPtr>& theEntities)
 {
   myAdjusted = false;
@@ -53,8 +64,10 @@ void SketchSolver_ConstraintMulti::getEntities(std::list<EntityWrapperPtr>& theE
     for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
       // just add copied features into the list of objects
       aFeature = ModelAPI_Feature::feature(*anObjIt);
-      if (aFeature)
+      if (aFeature) {
+        createCopiedEntity(aFeature, myStorage);
         myFeatures.insert(aFeature);
+      }
     }
   }
 }
@@ -63,6 +76,20 @@ bool SketchSolver_ConstraintMulti::remove()
 {
   myStorage->unsubscribeUpdates(this);
 
+  // "Multi" constraint has been removed, thus all copy features become non-copied,
+  // add them once again to be a common feature
+  std::set<FeaturePtr>::iterator anIt = myFeatures.begin();
+  for (; anIt != myFeatures.end(); ++anIt) {
+    EntityWrapperPtr anEntity = myStorage->entity(*anIt);
+    if (anEntity) {
+      std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+          std::dynamic_pointer_cast<SketchPlugin_Feature>(*anIt);
+      if (anEntity->isExternal() && !aSketchFeature->isExternal())
+        myStorage->makeNonExternal(anEntity);
+    } else
+      myStorage->update(*anIt, true);
+  }
+
   myFeatures.clear();
   return SketchSolver_Constraint::remove();
 }
index 6ef8d08b57ca9a464199bd836bc572b755be2258..e0b2923e46965805439b362a44ec32bf875b4b2c 100644 (file)
@@ -82,6 +82,11 @@ public:
   /// \brief Returns entity related to corresponding attribute
   const EntityWrapperPtr& entity(const AttributePtr& theAttribute) const;
 
+  /// \brief Make entity external
+  virtual void makeExternal(const EntityWrapperPtr& theEntity) = 0;
+  /// \brief Make entity non-external
+  virtual void makeNonExternal(const EntityWrapperPtr& theEntity) = 0;
+
   /// \brief Removes constraint from the storage
   /// \return \c true if the constraint and all its parameters are removed successfully
   virtual bool removeConstraint(ConstraintPtr theConstraint) = 0;