Salome HOME
Merge remote-tracking branch 'remotes/origin/master' into SolveSpace
authorazv <azv@opencascade.com>
Fri, 23 May 2014 11:44:12 +0000 (15:44 +0400)
committerazv <azv@opencascade.com>
Fri, 23 May 2014 11:44:12 +0000 (15:44 +0400)
src/SketchSolver/SketchSolver_ConstraintManager.cpp
src/SketchSolver/SketchSolver_ConstraintManager.h

index d7023712fe57b03353572680b416529fd3670fff..7edc1da33916837a0db8b89b4b5f1d4b01bcf661 100644 (file)
@@ -22,8 +22,6 @@
 #include <math.h>
 #include <assert.h>
 
-#include <set>
-
 /// Tolerance for value of parameters
 const double tolerance = 1.e-10;
 
@@ -176,7 +174,7 @@ bool SketchSolver_ConstraintManager::changeConstraint(
               boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
 {
   // Search the groups which this constraint touchs
-  std::vector<Slvs_hGroup> aGroups;
+  std::set<Slvs_hGroup> aGroups;
   findGroups(theConstraint, aGroups);
 
   // Process the groups list
@@ -203,7 +201,39 @@ bool SketchSolver_ConstraintManager::changeConstraint(
   }
   else if (aGroups.size() > 1)
   { // Several groups applicable for this constraint => need to merge them
-    /// \todo Implement merging of groups
+    std::set<Slvs_hGroup>::const_iterator aGroupsIter = aGroups.begin();
+
+    // Search first group
+    std::vector<SketchSolver_ConstraintGroup*>::iterator aFirstGroupIter;
+    for (aFirstGroupIter = myGroups.begin(); aFirstGroupIter != myGroups.end(); aFirstGroupIter++)
+      if ((*aFirstGroupIter)->getId() == *aGroupsIter)
+        break;
+    if (aFirstGroupIter == myGroups.end())
+      return false;
+
+    // Append other groups to the first one
+    std::vector<SketchSolver_ConstraintGroup*>::iterator anOtherGroupIter = aFirstGroupIter + 1;
+    for (aGroupsIter++; aGroupsIter != aGroups.end(); aGroupsIter++)
+    {
+      for ( ; anOtherGroupIter != myGroups.end(); anOtherGroupIter++)
+        if ((*anOtherGroupIter)->getId() == *aGroupsIter)
+          break;
+      if (anOtherGroupIter == myGroups.end())
+      { // Group disappears
+        anOtherGroupIter = aFirstGroupIter + 1;
+        continue;
+      }
+
+      (*aFirstGroupIter)->mergeGroups(**anOtherGroupIter);
+      int aShiftFirst = aFirstGroupIter - myGroups.begin();
+      int aShiftOther = anOtherGroupIter - myGroups.begin();
+      delete *anOtherGroupIter;
+      myGroups.erase(anOtherGroupIter);
+      aFirstGroupIter  = myGroups.begin() + aShiftFirst;
+      anOtherGroupIter = myGroups.begin() + aShiftOther;
+    }
+
+    return (*aFirstGroupIter)->changeConstraint(theConstraint);
   }
 
   // Something goes wrong
@@ -243,14 +273,14 @@ void SketchSolver_ConstraintManager::updateEntity(boost::shared_ptr<SketchPlugin
 
 void SketchSolver_ConstraintManager::findGroups(
               boost::shared_ptr<SketchPlugin_Constraint> theConstraint,
-              std::vector<Slvs_hGroup>&                  theGroupIDs) const
+              std::set<Slvs_hGroup>&                     theGroupIDs) const
 {
   boost::shared_ptr<SketchPlugin_Feature> aWP = findWorkplaneForConstraint(theConstraint);
 
   std::vector<SketchSolver_ConstraintGroup*>::const_iterator aGroupIter;
   for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
     if (aWP == (*aGroupIter)->getWorkplane() && (*aGroupIter)->isInteract(theConstraint))
-      theGroupIDs.push_back((*aGroupIter)->getId());
+      theGroupIDs.insert((*aGroupIter)->getId());
 }
 
 boost::shared_ptr<SketchPlugin_Feature> SketchSolver_ConstraintManager::findWorkplaneForConstraint(
@@ -671,6 +701,88 @@ void SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::resolveConstr
   myNeedToSolve = false;
 }
 
+void SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::mergeGroups(
+                const SketchSolver_ConstraintGroup& theGroup)
+{
+  // NOTE: The possibility, that some elements are placed into both groups, is around 0, 
+  // so the objects should be copied with changing the indexes
+
+  // Maps between old and new indexes of SolveSpace elements:
+  std::map<Slvs_hParam, Slvs_hParam>           aParamMap;
+  std::map<Slvs_hEntity, Slvs_hEntity>         anEntityMap;
+  std::map<Slvs_hConstraint, Slvs_hConstraint> aConstrMap;
+
+  // Go through copying constraints
+  std::vector<Slvs_Constraint>::const_iterator aConstrIter = theGroup.myConstraints.begin();
+  for ( ; aConstrIter != theGroup.myConstraints.end(); aConstrIter++)
+  {
+    Slvs_Constraint aConstraintCopy = *aConstrIter;
+    // Go through constraint entities
+    Slvs_hEntity* anEntities[CONSTRAINT_ATTR_SIZE] = {
+      &(aConstraintCopy.ptA), &(aConstraintCopy.ptB), 
+      &(aConstraintCopy.entityA), &(aConstraintCopy.entityB)
+    };
+    for (int indEnt = 0; indEnt < CONSTRAINT_ATTR_SIZE; indEnt++)
+    {
+      if (*(anEntities[indEnt]) == 0)
+        continue;
+      if (anEntityMap.find(*(anEntities[indEnt])) != anEntityMap.end())
+      { // entity is already copied
+        *(anEntities[indEnt]) = anEntityMap[*(anEntities[indEnt])];
+        continue;
+      }
+
+      // Copy entity
+      Slvs_Entity anEntityCopy = theGroup.myEntities[Search(*(anEntities[indEnt]), theGroup.myEntities)];
+      // Go through entity parameters
+      const int aNbEntParams = 4; // maximal number of entity parameters
+      for (int indPrm = 0; indPrm < aNbEntParams; indPrm++)
+      {
+        if (anEntityCopy.param[indPrm] == 0)
+          continue;
+        if (aParamMap.find(anEntityCopy.param[indPrm]) != aParamMap.end())
+        {
+          anEntityCopy.param[indPrm] = aParamMap[anEntityCopy.param[indPrm]];
+          continue;
+        }
+
+        Slvs_Param aParamCopy = theGroup.myParams[Search(anEntityCopy.param[indPrm], theGroup.myParams)];
+        aParamMap[aParamCopy.h] = ++myParamMaxID;
+        aParamCopy.h = myParamMaxID;
+        myParams.push_back(aParamCopy);
+      }
+
+      anEntityMap[anEntityCopy.h] = ++myEntityMaxID;
+      anEntityCopy.h = myEntityMaxID;
+      myEntities.push_back(anEntityCopy);
+      *(anEntities[indEnt]) = anEntityCopy.h;
+    }
+
+    aConstraintCopy.h = ++myConstrMaxID;
+    myConstraints.push_back(aConstraintCopy);
+    aConstrMap[aConstrIter->h] = aConstraintCopy.h;
+  }
+
+  // Append maps of SketchPlugin to SolveSpace parameters
+  std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_hConstraint>::const_iterator
+    aSPConstrMapIter = theGroup.myConstraintMap.begin();
+  for ( ; aSPConstrMapIter!= theGroup.myConstraintMap.end(); aSPConstrMapIter++)
+    myConstraintMap[aSPConstrMapIter->first] = aConstrMap.find(aSPConstrMapIter->second)->second;
+
+  std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
+    aSPEntMapIter = theGroup.myEntityMap.begin();
+  for ( ; aSPEntMapIter != theGroup.myEntityMap.end(); aSPEntMapIter++)
+    myEntityMap[aSPEntMapIter->first] = anEntityMap.find(aSPEntMapIter->second)->second;
+
+  // Add temporary constraints
+  std::list<Slvs_hConstraint>::const_iterator aTempConstrIter = theGroup.myTempConstraints.begin();
+  for ( ; aTempConstrIter != theGroup.myTempConstraints.end(); aTempConstrIter++)
+    myTempConstraints.push_back(aConstrMap.find(*aTempConstrIter)->second);
+  myTempConstraints.sort();
+
+  myNeedToSolve = myNeedToSolve || theGroup.myNeedToSolve;
+}
+
 bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateGroup()
 {
   // Check for valid sketch
index 9cbb23bab85a60b03f8b6758f3e2e070ca1d06a1..d49eb6ecffb76e7897b135330ccebb67dbbd6a66 100644 (file)
@@ -17,6 +17,7 @@
 #include <list>
 #include <map>
 #include <vector>
+#include <set>
 
 
 // Unknown constraint (for error reporting)
@@ -95,7 +96,7 @@ private:
    *  \param[out] theGroups     list of group indexes interacted with constraint
    */
   void findGroups(boost::shared_ptr<SketchPlugin_Constraint> theConstraint,
-                  std::vector<Slvs_hGroup>&                  theGroupIDs) const;
+                  std::set<Slvs_hGroup>&                     theGroupIDs) const;
 
   /** \brief Searches in the list of groups the workplane which constains specified constraint
    *  \param[in] theConstraint constraint to be found
@@ -165,6 +166,11 @@ public:
    */
   bool updateGroup();
 
+  /** \brief Add specified group to this one
+   *  \param[in] theGroup group of constraint to be added
+   */
+  void mergeGroups(const SketchSolver_ConstraintGroup& theGroup);
+
   /** \brief Start solution procedure if necessary and update attributes of features
    */
   void resolveConstraints();