Salome HOME
Task #3230: Sketcher: create a curve passing through selected points or vertices...
[modules/shaper.git] / src / SketchSolver / SketchSolver_ConstraintMulti.cpp
index c9b1a338bfba203ba0fc727ef1262103eb9f53e6..7b8cbd68eee6adb4f12f00156d4c176a55ba0bb0 100644 (file)
@@ -1,4 +1,21 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+// Copyright (C) 2014-2019  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 <SketchSolver_ConstraintMulti.h>
 #include <SketchSolver_Error.h>
@@ -60,13 +77,13 @@ void SketchSolver_ConstraintMulti::getEntities(std::list<EntityWrapperPtr>& theE
     if (!myStorage->update(aFeature))
       myStorage->update(aFeature, true);
     theEntities.push_back(myStorage->entity(aFeature));
-    myFeatures.insert(aFeature);
+    myOriginalFeatures.insert(aFeature);
     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) {
         createCopiedEntity(aFeature, myStorage);
-        myFeatures.insert(aFeature);
+        myCopiedFeatures.insert(aFeature);
       }
     }
   }
@@ -78,19 +95,20 @@ bool SketchSolver_ConstraintMulti::remove()
 
   // "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) {
+  std::set<FeaturePtr>::iterator anIt = myCopiedFeatures.begin();
+  for (; anIt != myCopiedFeatures.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
+    } else if ((*anIt)->data() && (*anIt)->data()->isValid())
       myStorage->update(*anIt, true);
   }
 
-  myFeatures.clear();
+  myOriginalFeatures.clear();
+  myCopiedFeatures.clear();
   return SketchSolver_Constraint::remove();
 }
 
@@ -114,7 +132,8 @@ void SketchSolver_ConstraintMulti::update()
       std::list<ObjectPtr>::iterator anObjIt = anObjectList.begin();
       for (; anObjIt != anObjectList.end(); ++anObjIt) {
         aFeature = ModelAPI_Feature::feature(*anObjIt);
-        if (aFeature && myFeatures.find(aFeature) == myFeatures.end()) {
+        if (aFeature && myOriginalFeatures.find(aFeature) == myOriginalFeatures.end() &&
+            myCopiedFeatures.find(aFeature) == myCopiedFeatures.end()) {
           isUpdated = true;
           break;
         }
@@ -208,21 +227,35 @@ void SketchSolver_ConstraintMulti::adjustConstraint()
 void SketchSolver_ConstraintMulti::notify(const FeaturePtr& theFeature,
                                           PlaneGCSSolver_Update*)
 {
-  if (myFeatures.find(theFeature) == myFeatures.end())
+  if (myOriginalFeatures.find(theFeature) == myOriginalFeatures.end() &&
+      myCopiedFeatures.find(theFeature) == myCopiedFeatures.end())
     return; // the feature is not used by constraint => nothing to update
 
-  // update derivative object
-  updateLocal();
-  myAdjusted = false;
-  adjustConstraint();
+  if (myIsProcessingNotify)
+    return; // "notify" is already processing
+
+  // do not adjust "multi"-constraint if the number of objects is changed,
+  // wait until the constraint is updated (issue #2425: changing number of copies by parameter)
+  if (myNumberOfCopies + 1 == myBaseConstraint->integer(nameNbObjects())->value()) {
+    myIsProcessingNotify = true;
+
+    // update derivative object
+    updateLocal();
+    myAdjusted = false;
+    adjustConstraint();
+
+    myIsProcessingNotify = false;
+  }
 }
 
 void SketchSolver_ConstraintMulti::blockEvents(bool isBlocked)
 {
   myIsEventsBlocked = isBlocked;
 
-  std::set<FeaturePtr>::iterator anIt = myFeatures.begin();
-  for (; anIt != myFeatures.end(); ++anIt)
+  std::set<FeaturePtr>::iterator anIt = myOriginalFeatures.begin();
+  for (; anIt != myOriginalFeatures.end(); ++anIt)
+    (*anIt)->data()->blockSendAttributeUpdated(isBlocked);
+  for (anIt = myCopiedFeatures.begin(); anIt != myCopiedFeatures.end(); ++anIt)
     (*anIt)->data()->blockSendAttributeUpdated(isBlocked);
 
   SketchSolver_Constraint::blockEvents(isBlocked);