]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #154: Crash on Undo-Redo operations
authorazv <azv@opencascade.com>
Fri, 26 Sep 2014 05:47:35 +0000 (09:47 +0400)
committerazv <azv@opencascade.com>
Fri, 26 Sep 2014 05:47:35 +0000 (09:47 +0400)
Implemented removing multiple constraints
Added verification of the data validity

src/SketchSolver/SketchSolver_Constraint.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.h

index 19af99788872f7da8b4c0583d3a2845ca01fe208..8360d0af506e3b6bba29f32b9ce5daf3c42e187b 100644 (file)
@@ -63,6 +63,10 @@ const int& SketchSolver_Constraint::getType(
   if (!theConstraint)
     return getType();
 
+  DataPtr aConstrData = theConstraint->data();
+  if (!aConstrData || !aConstrData->isValid())
+    return getType();
+
   // Assign empty names of attributes
   myAttributesList.clear();
   for (int i = 0; i < CONSTRAINT_ATTR_SIZE; i++)
@@ -76,8 +80,8 @@ const int& SketchSolver_Constraint::getType(
     int aPt2d = 0;  // bit-mapped field, each bit indicates whether the attribute is 2D point
     int aPt3d = 0;  // bit-mapped field, the same information for 3D points
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
-      boost::shared_ptr<ModelAPI_Attribute> anAttr = theConstraint->data()->attribute(
-          SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      boost::shared_ptr<ModelAPI_Attribute> anAttr = 
+          aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       if (!anAttr)
         continue;
       switch (typeOfAttribute(anAttr)) {
@@ -107,8 +111,8 @@ const int& SketchSolver_Constraint::getType(
     int aNbPoints = 0;
     int aNbEntities = 0;
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
-      boost::shared_ptr<ModelAPI_Attribute> anAttr = theConstraint->data()->attribute(
-          SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      boost::shared_ptr<ModelAPI_Attribute> anAttr = 
+          aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       switch (typeOfAttribute(anAttr)) {
         case POINT2D:
         case POINT3D:
@@ -133,8 +137,8 @@ const int& SketchSolver_Constraint::getType(
   if (aConstraintKind.compare(SketchPlugin_ConstraintLength::ID()) == 0) {
     int aNbLines = 0;
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
-      boost::shared_ptr<ModelAPI_Attribute> anAttr = theConstraint->data()->attribute(
-          SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      boost::shared_ptr<ModelAPI_Attribute> anAttr = 
+          aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       if (typeOfAttribute(anAttr) == LINE)
         myAttributesList[aNbLines++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
     }
@@ -149,8 +153,8 @@ const int& SketchSolver_Constraint::getType(
   if (isParallel || isPerpendicular) {
     int aNbEntities = 2;  // lines in SolveSpace constraints should start from SketchPlugin_Constraint::ENTITY_C() attribute
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
-      boost::shared_ptr<ModelAPI_Attribute> anAttr = theConstraint->data()->attribute(
-          SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      boost::shared_ptr<ModelAPI_Attribute> anAttr = 
+          aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       if (typeOfAttribute(anAttr) == LINE)
         myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
     }
@@ -163,8 +167,8 @@ const int& SketchSolver_Constraint::getType(
   if (aConstraintKind.compare(SketchPlugin_ConstraintRadius::ID()) == 0) {
     int aNbEntities = 2;  // lines in SolveSpace constraints should started from SketchPlugin_Constraint::ENTITY_C() attribute
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
-      boost::shared_ptr<ModelAPI_Attribute> anAttr = theConstraint->data()->attribute(
-          SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      boost::shared_ptr<ModelAPI_Attribute> anAttr = 
+          aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       AttrType aType = typeOfAttribute(anAttr);
       if (aType == CIRCLE || aType == ARC)
         myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
index bfdc890603e37e5075faa34dd4d5e456020c81cc..6426544079878b02817246975218a6cdeaeb3021 100644 (file)
@@ -730,8 +730,14 @@ void SketchSolver_ConstraintGroup::splitGroup(std::vector<SketchSolver_Constrain
     for (aGrEntIter = aGroupsEntities.begin(); aGrEntIter != aGroupsEntities.end(); aGrEntIter++) {
       bool isFound = false;
       for (int i = 0; i < 4 && !isFound; i++)
-        if (aConstrEnt[i] != 0)
+        if (aConstrEnt[i] != 0) {
           isFound = (aGrEntIter->find(aConstrEnt[i]) != aGrEntIter->end());
+          // Also we need to check sub-entities
+          int aEntPos = Search(aConstrEnt[i], myEntities);
+          Slvs_hEntity* aSub = myEntities[aEntPos].point;
+          for (int j = 0; *aSub != 0 && j < 4 && !isFound; aSub++)
+            isFound = (aGrEntIter->find(*aSub) != aGrEntIter->end());
+        }
       if (isFound)
         anIndexes.push_back(aGrEntIter - aGroupsEntities.begin());
     }
@@ -825,17 +831,50 @@ bool SketchSolver_ConstraintGroup::updateGroup()
       myConstraintMap.rbegin();
   bool isAllValid = true;
   bool isCCRemoved = false;  // indicates that at least one of coincidence constraints was removed
-  while (isAllValid && aConstrIter != myConstraintMap.rend()) {
+  int aConstrIndex = 0;
+  while (/*isAllValid && */aConstrIter != myConstraintMap.rend()) {
     if (!aConstrIter->first->data() || !aConstrIter->first->data()->isValid()) {
       if (aConstrIter->first->getKind().compare(SketchPlugin_ConstraintCoincidence::ID()) == 0)
         isCCRemoved = true;
-      std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_hConstraint>::reverse_iterator aCopyIter =
-          aConstrIter++;
-      removeConstraint(aCopyIter->first);
+      removeConstraint(aConstrIter->first);
       isAllValid = false;
-    } else
+      // Get back the correct position of iterator after the "remove" operation
+      aConstrIter = myConstraintMap.rbegin();
+      for (int i = 0; i < aConstrIndex && aConstrIter != myConstraintMap.rend(); i++)
+        aConstrIter++;
+    } else {
       aConstrIter++;
+      aConstrIndex++;
+    }
+  }
+
+  // Check if some entities are invalid too
+  std::set<Slvs_hEntity> anEntToRemove;
+  std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator
+      anAttrIter = myEntityAttrMap.begin();
+  while (anAttrIter != myEntityAttrMap.end()) {
+    if (!anAttrIter->first->owner() || !anAttrIter->first->owner()->data() ||
+        !anAttrIter->first->owner()->data()->isValid()) {
+      anEntToRemove.insert(anAttrIter->second);
+      std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator
+          aRemovedIter = anAttrIter;
+      anAttrIter++;
+      myEntityAttrMap.erase(aRemovedIter);
+    } else
+      anAttrIter++;
+  }
+  std::map<FeaturePtr, Slvs_hEntity>::iterator aFeatIter = myEntityFeatMap.begin();
+  while (aFeatIter != myEntityFeatMap.end()) {
+    if (!aFeatIter->first || !aFeatIter->first->data() ||
+        !aFeatIter->first->data()->isValid()) {
+      anEntToRemove.insert(aFeatIter->second);
+      std::map<FeaturePtr, Slvs_hEntity>::iterator aRemovedIter = aFeatIter;
+      aFeatIter++;
+      myEntityFeatMap.erase(aRemovedIter);
+    } else
+      aFeatIter++;
   }
+  removeEntitiesById(anEntToRemove);
 
   // Probably, need to update coincidence constraints
   if (isCCRemoved && !myExtraCoincidence.empty()) {
@@ -1103,8 +1142,22 @@ void SketchSolver_ConstraintGroup::removeConstraint(
     } else
       anEntFeatIter++;
   }
-  std::set<Slvs_hEntity>::const_reverse_iterator aRemIter = anEntToRemove.rbegin();
-  for (; aRemIter != anEntToRemove.rend(); aRemIter++) {
+
+  removeEntitiesById(anEntToRemove);
+
+  if (myCoincidentPoints.size() == 1 && myCoincidentPoints.front().empty())
+    myCoincidentPoints.clear();
+}
+
+// ============================================================================
+//  Function: removeEntitiesById
+//  Class:    SketchSolver_ConstraintGroup
+//  Purpose:  Removes specified entities and their parameters
+// ============================================================================
+void SketchSolver_ConstraintGroup::removeEntitiesById(const std::set<Slvs_hEntity>& theEntities)
+{
+  std::set<Slvs_hEntity>::const_reverse_iterator aRemIter = theEntities.rbegin();
+  for (; aRemIter != theEntities.rend(); aRemIter++) {
     unsigned int anEntPos = Search(*aRemIter, myEntities);
     if (anEntPos >= myEntities.size())
       continue;
@@ -1129,8 +1182,6 @@ void SketchSolver_ConstraintGroup::removeConstraint(
     for (; aCoPtIter != myCoincidentPoints.end(); aCoPtIter++)
       aCoPtIter->erase(*aRemIter);
   }
-  if (myCoincidentPoints.size() == 1 && myCoincidentPoints.front().empty())
-    myCoincidentPoints.clear();
 }
 
 // ============================================================================
index 8c5a72e369b534004082c783e765bd79750da53e..6024f8caecab8cebac7dd567d8d2ccb312531838 100644 (file)
@@ -146,6 +146,11 @@ protected:
   Slvs_hParam changeParameter(const double& theParam,
                               std::vector<Slvs_Param>::const_iterator& thePrmIter);
 
+  /** \brief Removes specified entities and their parameters
+   *  \param[in] theEntities  list of IDs of the entities to be removed
+   */
+  void removeEntitiesById(const std::set<Slvs_hEntity>& theEntities);
+
   /** \brief Removes constraints from the group
    *  \param[in] theConstraint constraint to be removed
    */