]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Update removing point-point coincidences.
authorazv <azv@opencascade.com>
Tue, 22 Dec 2015 05:41:40 +0000 (08:41 +0300)
committerazv <azv@opencascade.com>
Tue, 22 Dec 2015 05:48:09 +0000 (08:48 +0300)
Updated procedure of removing Fixed constraint.

src/SketchSolver/SketchSolver_ConstraintFixed.cpp
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Storage.cpp
src/SketchSolver/SketchSolver_Storage.h
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.h

index cddafdb1252b8605df55e0d496b9e7d6c9c76f63..36dfca58a964a5f2114ae9dcfee46cf5847917fe 100644 (file)
@@ -98,6 +98,8 @@ bool SketchSolver_ConstraintFixed::remove()
     aFeature = ModelAPI_Feature::feature(myFixedAttribute->object());
   if (aFeature)
     myStorage->update(aFeature, myGroupID);
+  else if (myFixedAttribute)
+    myStorage->update(myFixedAttribute, myGroupID);
 
   // Remove constraint or base feature
   if (myBaseConstraint) {
index bf64e49db39700fb46251603998f795586826270..b4856ba88bed9617998f8d9460240c926884897d 100644 (file)
@@ -524,36 +524,11 @@ void SketchSolver_Group::removeConstraint(ConstraintPtr theConstraint)
   ConstraintConstraintMap::iterator aCIter = myConstraints.begin();
   for (; aCIter != myConstraints.end(); aCIter++)
     if (aCIter->first == theConstraint) {
-      if (!aCIter->second->remove()) // the constraint is not fully removed
-        isFullyRemoved = false;
+      aCIter->second->remove(); // the constraint is not fully removed
       break;
     }
-  if (aCIter == myConstraints.end())
-    return;
-
-  if (isFullyRemoved)
+  if (aCIter != myConstraints.end())
     myConstraints.erase(aCIter);
-  else if (aCIter != myConstraints.end() &&
-           aCIter->first->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
-    // Update multicoincidence
-    std::list<ConstraintPtr> aMultiCoinc;
-    SolverConstraintPtr aCoincidence = aCIter->second;
-    while (aCIter != myConstraints.end()) {
-      if (aCIter->second != aCoincidence) {
-        ++aCIter;
-        continue;
-      }
-      if (aCIter->first != theConstraint)
-        aMultiCoinc.push_back(aCIter->first);
-      aCIter->second->remove();
-      ConstraintConstraintMap::iterator aRemoveIt = aCIter++;
-      myConstraints.erase(aRemoveIt);
-    }
-
-    std::list<ConstraintPtr>::iterator anIt = aMultiCoinc.begin();
-    for (; anIt != aMultiCoinc.end(); ++anIt)
-      changeConstraint(*anIt);
-  }
 }
 
 // ============================================================================
index e440a795b1f888227abdde6877564dc67aa5f024..67b346579ab8d7ef0fa051730da6909090c93981 100644 (file)
@@ -23,8 +23,11 @@ static bool isEqual(const std::list<ConstraintWrapperPtr>& theCVec1,
 void SketchSolver_Storage::addConstraint(ConstraintPtr        theConstraint,
                                          ConstraintWrapperPtr theSolverConstraint)
 {
-  std::list<ConstraintWrapperPtr> aConstrList(1, theSolverConstraint);
-  addConstraint(theConstraint, aConstrList);
+  if (theSolverConstraint) {
+    std::list<ConstraintWrapperPtr> aConstrList(1, theSolverConstraint);
+    addConstraint(theConstraint, aConstrList);
+  } else
+    addConstraint(theConstraint, std::list<ConstraintWrapperPtr>());
 }
 
 void SketchSolver_Storage::addConstraint(
@@ -36,10 +39,34 @@ void SketchSolver_Storage::addConstraint(
   if (aFound == myConstraintMap.end() || !isEqual(aFound->second, theSolverConstraints))
     setNeedToResolve(true);
 
-  // Do not add point-point coincidence, because it is already made by setting
-  // the same parameters for both points
-  if (!theSolverConstraints.empty() &&
-      theSolverConstraints.front()->type() != CONSTRAINT_PT_PT_COINCIDENT) {
+  if (theSolverConstraints.empty()) {
+    // constraint links to the empty list, add its attributes linked to the empty entities
+    std::list<AttributePtr> aRefAttrs =
+        theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+    std::list<AttributePtr>::const_iterator anAttrIt = aRefAttrs.begin();
+    for (; anAttrIt != aRefAttrs.end(); ++anAttrIt) {
+      AttributeRefAttrPtr aRef = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIt);
+      if (aRef->isObject()) {
+        FeaturePtr aFeature = ModelAPI_Feature::feature(aRef->object());
+        if (aFeature) addEntity(aFeature, EntityWrapperPtr());
+      } else
+        addEntity(aRef->attr(), EntityWrapperPtr());
+    }
+    std::list<AttributePtr> aRefLists =
+        theConstraint->data()->attributes(ModelAPI_AttributeRefList::typeId());
+    for (anAttrIt = aRefLists.begin(); anAttrIt != aRefLists.end(); ++anAttrIt) {
+      AttributeRefListPtr aRef = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anAttrIt);
+      std::list<ObjectPtr> anObj = aRef->list();
+      std::list<ObjectPtr>::iterator anIt = anObj.begin();
+      for (; anIt != anObj.end(); ++anIt) {
+        FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt);
+        if (aFeature) addEntity(aFeature, EntityWrapperPtr());
+      }
+    }
+  }
+  else if (theSolverConstraints.front()->type() != CONSTRAINT_PT_PT_COINCIDENT) {
+    // Do not add point-point coincidence, because it is already made by setting
+    // the same parameters for both points
     std::list<ConstraintWrapperPtr>::iterator aCIt = theSolverConstraints.begin();
     for (; aCIt != theSolverConstraints.end(); ++aCIt)
       update(*aCIt);
@@ -54,7 +81,8 @@ void SketchSolver_Storage::addEntity(FeaturePtr       theFeature,
                                      EntityWrapperPtr theSolverEntity)
 {
   std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFound = myFeatureMap.find(theFeature);
-  if (aFound == myFeatureMap.end() || !aFound->second || !aFound->second->isEqual(theSolverEntity))
+  if (aFound == myFeatureMap.end() || !aFound->second ||
+     (theSolverEntity && !aFound->second->isEqual(theSolverEntity)))
     setNeedToResolve(true); // the entity is new or modified
 
   myFeatureMap[theFeature] = theSolverEntity;
@@ -67,7 +95,8 @@ void SketchSolver_Storage::addEntity(AttributePtr     theAttribute,
                                      EntityWrapperPtr theSolverEntity)
 {
   std::map<AttributePtr, EntityWrapperPtr>::const_iterator aFound = myAttributeMap.find(theAttribute);
-  if (aFound == myAttributeMap.end() || !aFound->second || !aFound->second->isEqual(theSolverEntity))
+  if (aFound == myAttributeMap.end() || !aFound->second ||
+     (theSolverEntity && !aFound->second->isEqual(theSolverEntity)))
     setNeedToResolve(true); // the entity is new or modified
 
   myAttributeMap[theAttribute] = theSolverEntity;
@@ -224,10 +253,6 @@ bool SketchSolver_Storage::removeConstraint(ConstraintPtr theConstraint)
       ++anIt;
     }
   }
-  if (!isFullyRemoved) {
-    // revert removed constraint
-    addConstraint(theConstraint, aConstrList);
-  }
   return isFullyRemoved;
 }
 
@@ -307,13 +332,14 @@ bool SketchSolver_Storage::removeEntity(FeaturePtr theFeature)
   if (aFound == myFeatureMap.end())
     return false; // feature not found, nothing to delete
 
+  EntityWrapperPtr anEntity = aFound->second;
+  myFeatureMap.erase(aFound);
+
   // Check the feature is not used by constraints
   if (isUsed(theFeature))
     return false; // the feature is used, don't remove it
 
   // Remove feature
-  EntityWrapperPtr anEntity = aFound->second;
-  myFeatureMap.erase(aFound);
   if (remove(anEntity))
     return true;
   // feature is not removed, revert operation
@@ -328,6 +354,9 @@ bool SketchSolver_Storage::removeEntity(AttributePtr theAttribute)
   if (aFound == myAttributeMap.end())
     return false; // attribute not found, nothing to delete
 
+  EntityWrapperPtr anEntity = aFound->second;
+  myAttributeMap.erase(aFound);
+
   // Check the attribute is not used by constraints
   if (isUsed(theAttribute))
     return false; // the attribute is used, don't remove it
@@ -338,8 +367,6 @@ bool SketchSolver_Storage::removeEntity(AttributePtr theAttribute)
       return false;
 
   // Remove attribute
-  EntityWrapperPtr anEntity = aFound->second;
-  myAttributeMap.erase(aFound);
   if (remove(anEntity))
     return true;
   // attribute is not removed, revert operation
@@ -468,6 +495,21 @@ bool SketchSolver_Storage::isFixed(EntityWrapperPtr theEntity) const
         if ((*anEntIt)->group() != myGroupID)
           return true;
     }
+
+  std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator aCIt = myConstraintMap.begin();
+  std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
+  for (; aCIt != myConstraintMap.end(); ++aCIt) {
+    if (aCIt->second.empty())
+      continue;
+    aCWIt = aCIt->second.begin();
+    if ((*aCWIt)->type() != CONSTRAINT_FIXED)
+      continue;
+    for (; aCWIt != aCIt->second.end(); ++aCIt)
+      if ((theEntity->baseAttribute() && (*aCWIt)->isUsed(theEntity->baseAttribute())) ||
+          (theEntity->baseFeature() && (*aCWIt)->isUsed(theEntity->baseFeature())))
+        return true;
+  }
+
   return false;
 }
 
index 26ccd019af5e04a05a78d5f7c93192d5bfca3adf..e733421ff2730ddb363f80fd0b55630ef93bce5e 100644 (file)
@@ -123,7 +123,7 @@ public:
 
   /// \brief Check the entity is fixed.
   ///        If the point is under verification, all coincident points are checked too.
-  bool isFixed(EntityWrapperPtr theEntity) const;
+  SKETCHSOLVER_EXPORT bool isFixed(EntityWrapperPtr theEntity) const;
 
   /// \brief Shows the sketch should be resolved
   virtual bool isNeedToResolve()
index 96b7ec0779b90fb6845eb3803e6cb8de2bfa84d3..110354bfbcb6fd83007c893e27fee133bbdcc630 100644 (file)
@@ -19,7 +19,9 @@
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeRefAttr.h>
 #include <SketchPlugin_Arc.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
 
 /** \brief Search the entity/parameter with specified ID in the list of elements
  *  \param[in] theEntityID unique ID of the element
@@ -178,7 +180,7 @@ bool SolveSpaceSolver_Storage::update(EntityWrapperPtr& theEntity)
   if (aSlvsEnt.group == SLVS_G_UNKNOWN)
     aSlvsEnt.group = (Slvs_hGroup)myGroupID;
   Slvs_hEntity anEntID = updateEntity(aSlvsEnt);
-  if (aSlvsEnt.h == SLVS_E_UNKNOWN) {
+  if (aSlvsEnt.h == SLVS_E_UNKNOWN || isUpdated) {
     anEntity->changeEntity() = getEntity(anEntID);
     isUpdated = true;
 
@@ -1460,6 +1462,101 @@ bool SolveSpaceSolver_Storage::isUsedInEqual(
 }
 
 
+bool SolveSpaceSolver_Storage::removeCoincidence(ConstraintWrapperPtr theConstraint)
+{
+  std::list<EntityWrapperPtr> aPoints = theConstraint->entities();
+  std::list<EntityWrapperPtr>::const_iterator aPIt;
+
+  CoincidentPointsMap::iterator aPtPtIt = myCoincidentPoints.begin();
+  for (; aPtPtIt != myCoincidentPoints.end(); ++aPtPtIt) {
+    for (aPIt = aPoints.begin(); aPIt != aPoints.end(); ++aPIt)
+      if (aPtPtIt->first == *aPIt ||
+          aPtPtIt->second.find(*aPIt) != aPtPtIt->second.end())
+        break;
+    if (aPIt != aPoints.end())
+      break;
+  }
+
+  if (aPtPtIt == myCoincidentPoints.end())
+    return true; // already removed
+
+  // Create new copies of coincident points
+  BuilderPtr aBuilder = SolveSpaceSolver_Builder::getInstance();
+  std::list<EntityWrapperPtr> aNewPoints;
+  for (aPIt = aPoints.begin(); aPIt != aPoints.end(); ++aPIt)
+    aNewPoints.push_back(aBuilder->createAttribute(
+        (*aPIt)->baseAttribute(), myGroupID, myWorkplaneID));
+
+  // Find all points fallen out of group of coincident points
+  std::map<EntityWrapperPtr, EntityWrapperPtr> aNotCoinc;
+  aNotCoinc[aPtPtIt->first] = EntityWrapperPtr();
+  std::set<EntityWrapperPtr>::const_iterator aTempIt = aPtPtIt->second.begin();
+  for (; aTempIt != aPtPtIt->second.end(); ++aTempIt)
+    aNotCoinc[*aTempIt] = EntityWrapperPtr();
+  std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::iterator
+      aConstrIt = myConstraintMap.begin();
+  for (; aConstrIt != myConstraintMap.end(); ++aConstrIt)
+    if (aConstrIt->first->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+      AttributeRefAttrPtr aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_A()));
+      AttributeRefAttrPtr aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_B()));
+      if (!aRefAttrA || !aRefAttrB || aRefAttrA->isObject() || aRefAttrB->isObject())
+        continue;
+      std::map<AttributePtr, EntityWrapperPtr>::iterator
+          aFound = myAttributeMap.find(aRefAttrA->attr());
+      if (aFound != myAttributeMap.end())
+        aNotCoinc.erase(aFound->second);
+      aFound = myAttributeMap.find(aRefAttrB->attr());
+      if (aFound != myAttributeMap.end())
+        aNotCoinc.erase(aFound->second);
+    }
+  if (aNotCoinc.empty())
+    return false;
+  std::list<EntityWrapperPtr>::const_iterator aNewPIt;
+  for (aPIt = aPoints.begin(), aNewPIt = aNewPoints.begin();
+       aPIt != aPoints.end(); ++aPIt, ++aNewPIt) {
+    if (aNotCoinc.find(*aPIt) != aNotCoinc.end())
+      aNotCoinc[*aPIt] = *aNewPIt;
+  }
+
+  // Find all features and constraints uses coincident points
+  std::map<EntityWrapperPtr, EntityWrapperPtr>::iterator aNotCIt;
+  std::set<EntityWrapperPtr> anUpdFeatures;
+  std::map<FeaturePtr, EntityWrapperPtr>::iterator aFIt = myFeatureMap.begin();
+  for (; aFIt != myFeatureMap.end(); ++aFIt) {
+    for (aNotCIt = aNotCoinc.begin(); aNotCIt != aNotCoinc.end(); ++aNotCIt) {
+      if (!aFIt->second->isUsed(aNotCIt->first->baseAttribute()))
+        continue;
+      std::list<EntityWrapperPtr> aSubs = aFIt->second->subEntities();
+      std::list<EntityWrapperPtr>::iterator aSIt = aSubs.begin();
+      for (; aSIt != aSubs.end(); ++aSIt)
+        if (*aSIt == aNotCIt->first)
+          *aSIt = aNotCIt->second;
+      aFIt->second->setSubEntities(aSubs);
+      anUpdFeatures.insert(aFIt->second);
+    }
+  }
+  // update features
+  std::set<EntityWrapperPtr>::iterator anUpdIt = anUpdFeatures.begin();
+  for (; anUpdIt != anUpdFeatures.end(); ++anUpdIt)
+    update(EntityWrapperPtr(*anUpdIt));
+
+  // remove not coincident points
+  for (aNotCIt = aNotCoinc.begin(); aNotCIt != aNotCoinc.end(); ++aNotCIt) {
+    if (aPtPtIt->first == aNotCIt->first) {
+      std::set<EntityWrapperPtr> aSlaves = aPtPtIt->second;
+      EntityWrapperPtr aNewMaster = *aSlaves.begin();
+      aSlaves.erase(aSlaves.begin());
+      myCoincidentPoints[aNewMaster] = aSlaves;
+      myCoincidentPoints.erase(aPtPtIt);
+      aPtPtIt = myCoincidentPoints.find(aNewMaster);
+    } else
+      aPtPtIt->second.erase(aNotCIt->first);
+  }
+  return true;
+}
+
 bool SolveSpaceSolver_Storage::remove(ConstraintWrapperPtr theConstraint)
 {
   std::shared_ptr<SolveSpaceSolver_ConstraintWrapper> aConstraint =
@@ -1476,6 +1573,11 @@ bool SolveSpaceSolver_Storage::remove(ConstraintWrapperPtr theConstraint)
     return true;
 
   bool isFullyRemoved = removeConstraint((Slvs_hConstraint)aConstraint->id());
+
+  // remove point-point coincidence
+  if (aConstraint->type() == CONSTRAINT_PT_PT_COINCIDENT)
+    isFullyRemoved = removeCoincidence(theConstraint);
+
   return SketchSolver_Storage::remove(theConstraint) && isFullyRemoved;
 }
 
@@ -1504,6 +1606,8 @@ void SolveSpaceSolver_Storage::refresh(bool theFixedOnly) const
   std::list<ParameterWrapperPtr> aParams;
   std::list<ParameterWrapperPtr>::const_iterator aParIt;
   for (; anIt != myAttributeMap.end(); ++anIt) {
+    if (!anIt->second)
+      continue;
     // the external feature always should keep the up to date values, so, 
     // refresh from the solver is never needed
     if (anIt->first.get()) {
@@ -1576,6 +1680,8 @@ void SolveSpaceSolver_Storage::verifyFixed()
 {
   std::map<AttributePtr, EntityWrapperPtr>::iterator anAttrIt = myAttributeMap.begin();
   for (; anAttrIt != myAttributeMap.end(); ++anAttrIt) {
+    if (!anAttrIt->second)
+      continue;
     const std::list<ParameterWrapperPtr>& aParameters = anAttrIt->second->parameters();
     std::list<ParameterWrapperPtr>::const_iterator aParIt = aParameters.begin();
     for (; aParIt != aParameters.end(); ++aParIt)
index 38efa4c132378e3d8d8af3226bef87ed2c73ff26..12af9dc0c4454e48af6f3b7a7ca15af76016dd17 100644 (file)
@@ -75,6 +75,9 @@ protected:
   /// \return \c true if the parameter has been removed
   virtual bool remove(ParameterWrapperPtr theParameter);
 
+  /// \brief Remove point-point coincidence
+  bool removeCoincidence(ConstraintWrapperPtr theConstraint);
+
   /// \brief Update the group for the given entity, its sub-entities and parameters
   virtual void changeGroup(EntityWrapperPtr theEntity, const GroupID& theGroup);
   /// \brief Update the group for the given parameter