]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Check multi coincidence and remove fixing of copied entities in MultiRotation/MultiTr...
authorazv <azv@opencascade.com>
Thu, 17 Sep 2015 06:41:17 +0000 (09:41 +0300)
committerazv <azv@opencascade.com>
Thu, 17 Sep 2015 06:42:23 +0000 (09:42 +0300)
src/SketchSolver/SketchSolver_ConstraintMulti.cpp
src/SketchSolver/SketchSolver_ConstraintMulti.h
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Group.h
src/SketchSolver/SketchSolver_Storage.cpp
src/SketchSolver/SketchSolver_Storage.h

index e68a881be5b246c69e731d8dba9914e1746280d2..0980dab4e5c460be9784fd595d22d727b414cd4a 100644 (file)
@@ -237,3 +237,70 @@ void SketchSolver_ConstraintMulti::adjustConstraint()
   myPointsJustUpdated.clear();
   myAdjusted = true;
 }
+
+void SketchSolver_ConstraintMulti::checkCoincidence()
+{
+  std::vector< std::vector<Slvs_hEntity> > aFilteredPoints; // points are filtered by their positions
+
+  std::vector< std::vector<Slvs_hEntity> >::const_iterator aPCIt = myPointsAndCopies.begin();
+  std::vector<Slvs_hEntity>::const_iterator aCIt;
+  for (; aPCIt != myPointsAndCopies.end(); ++aPCIt) {
+    aCIt = aPCIt->begin();
+    // Skip first element, focus the copies only
+    for (++aCIt; aCIt != aPCIt->end(); ++aCIt) {
+      std::vector< std::vector<Slvs_hEntity> >::iterator aFilterIt = aFilteredPoints.begin();
+      for (; aFilterIt != aFilteredPoints.end(); ++aFilterIt)
+        if (myStorage->isEqual(*aCIt, aFilterIt->front())) {
+          aFilterIt->push_back(*aCIt);
+          break;
+        }
+      if (aFilterIt == aFilteredPoints.end()) {
+        std::vector<Slvs_hEntity> aNewFilter(1, *aCIt);
+        aFilteredPoints.push_back(aNewFilter);
+      }
+    }
+  }
+
+  // Check the coicidence of filtered points and remove extra fixation.
+  // Also check separated points which are not fixed.
+  std::vector< std::vector<Slvs_hEntity> >::iterator aFPIt = aFilteredPoints.begin();
+  for (; aFPIt != aFilteredPoints.end(); ++aFPIt) {
+    if (aFPIt->size() <= 1)
+      continue;
+    std::vector<Slvs_hEntity>::iterator anIt1, anIt2;
+    for (anIt1 = aFPIt->begin(); anIt1 != aFPIt->end(); ++anIt1) {
+      for (anIt2 = anIt1 + 1; anIt2 != aFPIt->end(); ++anIt2) {
+        Slvs_hConstraint aFixed1, aFixed2;
+        bool isFixed1 = myStorage->isPointFixed(*anIt1, aFixed1);
+        bool isFixed2 = myStorage->isPointFixed(*anIt2, aFixed2);
+        if (myStorage->isCoincident(*anIt1, *anIt2)) {
+          if (!isFixed1 && isFixed2) {
+            Slvs_hEntity aTmp = *anIt1;
+            *anIt1 = *anIt2;
+            *anIt2 = aTmp;
+          } else if (isFixed1 && isFixed2) {
+            // remove fixing of the second point
+            myStorage->removeConstraint(aFixed2);
+            std::vector<Slvs_hConstraint>::iterator aRemoveIt = mySlvsConstraints.begin();
+            for (; aRemoveIt != mySlvsConstraints.end(); ++aRemoveIt)
+              if (*aRemoveIt == aFixed2) {
+                mySlvsConstraints.erase(aRemoveIt);
+                break;
+              }
+          }
+        } else {
+          bool isFixed[2] = {isFixed1, isFixed2};
+          Slvs_hEntity aPoint[2] = {*anIt1, *anIt2};
+          for (int i = 0; i < 2; i++)
+            if (!isFixed[i]) {
+              Slvs_Constraint aConstraint = Slvs_MakeConstraint(SLVS_C_UNKNOWN, myGroup->getId(),
+                  SLVS_C_WHERE_DRAGGED, myGroup->getWorkplaneId(), 0.0,
+                  aPoint[i], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
+              aConstraint.h = myStorage->addConstraint(aConstraint);
+              mySlvsConstraints.push_back(aConstraint.h);
+            }
+        }
+      }
+    }
+  }
+}
index bbc4992be5e72193360b6648280e4b72133264e6..2d76cee2b21f1d97d44e6c048c8eb69bac1fa8ec 100644 (file)
@@ -46,6 +46,9 @@ public:
     SketchSolver_Constraint::refresh();
   }
 
+  /// \brief Verifies, the coincidence between points of copied entities appears or disappears,
+  ///        and removes or adds fixing of corresponding points.
+  void checkCoincidence();
 
 protected:
   /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints
index 35f90dc7464da1d81e8f74aa9d4a26a4113556e8..560550f6ec0a99103cef32da62fe291ee0f6e924 100644 (file)
@@ -9,6 +9,7 @@
 #include <SketchSolver_Builder.h>
 #include <SketchSolver_Constraint.h>
 #include <SketchSolver_ConstraintCoincidence.h>
+#include <SketchSolver_ConstraintMulti.h>
 #include <SketchSolver_Error.h>
 
 #include <Events_Error.h>
@@ -235,8 +236,9 @@ bool SketchSolver_Group::changeConstraint(
 
     // Additional verification of coincidence of several points
     if (theConstraint->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+      bool hasMultiCoincidence = false;
       ConstraintConstraintMap::iterator aCIter = myConstraints.begin();
-      for (; aCIter != myConstraints.end(); aCIter++) {
+      for (; aCIter != myConstraints.end(); ++aCIter) {
         std::shared_ptr<SketchSolver_ConstraintCoincidence> aCoincidence =
           std::dynamic_pointer_cast<SketchSolver_ConstraintCoincidence>(aCIter->second);
         if (!aCoincidence)
@@ -251,8 +253,12 @@ bool SketchSolver_Group::changeConstraint(
             if (anIt->second == aCIter->second)
               anIt->second = aCoinc2;
           aCIter->second = aCoinc2;
+          hasMultiCoincidence = true;
         }
       }
+
+      if (hasMultiCoincidence)
+        notifyMultiConstraints();
     }
     myConstraints[theConstraint] = aConstraint;
   }
@@ -784,6 +790,8 @@ void SketchSolver_Group::removeConstraint(ConstraintPtr theConstraint)
     std::list<ConstraintPtr>::iterator anIt = aMultiCoinc.begin();
     for (; anIt != aMultiCoinc.end(); ++anIt)
       changeConstraint(*anIt);
+
+    notifyMultiConstraints();
   }
 }
 
@@ -826,6 +834,23 @@ bool SketchSolver_Group::checkFeatureValidity(FeaturePtr theFeature)
   return aFactory->validate(theFeature);
 }
 
+// ============================================================================
+//  Function: notifyMultiConstraints
+//  Class:    SketchSolver_Group
+//  Purpose:  Update Multi-Translation/-Rotation constraints due to multi coincidence appears/disappears
+// ============================================================================
+void SketchSolver_Group::notifyMultiConstraints()
+{
+  ConstraintConstraintMap::iterator aCIter = myConstraints.begin();
+  for (; aCIter != myConstraints.end(); ++aCIter) {
+    if (aCIter->first->getKind() == SketchPlugin_MultiRotation::ID() ||
+        aCIter->first->getKind() == SketchPlugin_MultiTranslation::ID()) {
+      std::shared_ptr<SketchSolver_ConstraintMulti> aMulti = 
+          std::dynamic_pointer_cast<SketchSolver_ConstraintMulti>(aCIter->second);
+      aMulti->checkCoincidence();
+    }
+  }
+}
 
 
 
index 6c842caef88abe089d656a351e7f30c0b03c8529..6a5f02b03b7a2b314a4961e5286085ad304a67b8 100644 (file)
@@ -169,6 +169,9 @@ private:
   /// \brief Update just changed constraints
   void updateConstraints();
 
+  /// \brief Update Multi-Translation/-Rotation constraints due to multi coincidence appears/disappears
+  void notifyMultiConstraints();
+
 private:
   Slvs_hGroup myID; ///< Index of the group
   Slvs_hEntity myWorkplaneID; ///< Index of workplane, the group is based on
index 485b81565d8b36e2a9be596183def9c678c0c357..1e77557874dd157795e9a38d423918948d90815a 100644 (file)
@@ -372,13 +372,17 @@ bool SketchSolver_Storage::isPointFixed(
     }
 
   // Search the Rigid constraint
+  theFixed = SLVS_C_UNKNOWN;
   std::vector<Slvs_Constraint>::const_iterator aConstrIter = myConstraints.begin();
   for (; aConstrIter != myConstraints.end(); aConstrIter++)
     if (aConstrIter->type == SLVS_C_WHERE_DRAGGED &&
         aCoincident.find(aConstrIter->ptA) != aCoincident.end()) {
       theFixed = aConstrIter->h;
-      return true;
+      if (aConstrIter->ptA == thePointID)
+        return true;
     }
+  if (theFixed != SLVS_C_UNKNOWN)
+    return true;
 
   if (theAccurate) {
     // Try to find the fixed entity which uses such point or its coincidence
@@ -580,6 +584,9 @@ bool SketchSolver_Storage::removeConstraint(const Slvs_hConstraint& theConstrain
     myConstrMaxID = myConstraints.empty() ? SLVS_E_UNKNOWN : myConstraints.back().h;
     myNeedToResolve = true;
     myRemovedConstraints.insert(theConstraintID);
+    if (aConstraint.type == SLVS_C_POINTS_COINCIDENT)
+      removeCoincidence(aConstraint);
+
     // Remove all entities
     Slvs_hEntity anEntities[6] = {aConstraint.ptA, aConstraint.ptB,
         aConstraint.entityA, aConstraint.entityB,
@@ -773,6 +780,35 @@ void SketchSolver_Storage::removeCoincidentPoint(const Slvs_hEntity& thePoint)
     }
 }
 
+void SketchSolver_Storage::removeCoincidence(const Slvs_Constraint& theCoincidence)
+{
+  // Find set of coincident points
+  std::vector< std::set<Slvs_hEntity> >::iterator aCIt = myCoincidentPoints.begin();
+  for (; aCIt != myCoincidentPoints.end(); ++aCIt)
+    if (aCIt->find(theCoincidence.ptA) != aCIt->end() ||
+        aCIt->find(theCoincidence.ptB) != aCIt->end())
+      break;
+  if (aCIt == myCoincidentPoints.end())
+    return;
+
+  // Leave only the points which are still coincident
+  std::set<Slvs_hEntity> aRemainCoincidence;
+  std::vector<Slvs_Constraint>::const_iterator aConstrIt = myConstraints.begin();
+  for (; aConstrIt != myConstraints.end(); ++aConstrIt) {
+    if (aConstrIt->type != SLVS_C_POINTS_COINCIDENT)
+      continue;
+    if (aCIt->find(aConstrIt->ptA) != aCIt->end() ||
+        aCIt->find(aConstrIt->ptB) != aCIt->end()) {
+      aRemainCoincidence.insert(aConstrIt->ptA);
+      aRemainCoincidence.insert(aConstrIt->ptB);
+    }
+  }
+  if (aRemainCoincidence.size() <= 1)
+    myCoincidentPoints.erase(aCIt);
+  else
+    aCIt->swap(aRemainCoincidence);
+}
+
 bool SketchSolver_Storage::isCoincident(
     const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2) const
 {
index 8e808e52b64594c0e4e4da512b16a9e807dfb8e7..fb8e79eb211113771ec8148587115df88a2b8223 100644 (file)
@@ -146,6 +146,8 @@ private:
   void addCoincidentPoints(const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2);
   /// \brief Remove point from lists of coincidence
   void removeCoincidentPoint(const Slvs_hEntity& thePoint);
+  /// \brief Remove point-point coincidence
+  void removeCoincidence(const Slvs_Constraint& theCoincidence);
 
 public:
   /// \brief Check two points are coincident