]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Process redundant constraints reported by PlaneGCS as conflicting.
authorazv <azv@opencascade.com>
Mon, 6 Mar 2017 07:14:48 +0000 (10:14 +0300)
committerazv <azv@opencascade.com>
Mon, 6 Mar 2017 07:17:12 +0000 (10:17 +0300)
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.cpp
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Storage.cpp

index 3e77208aa756a42efb354a0389efb733083a2ea7..fb64ef10a3c0752a1fcfaddcd0d8d52b9973a9ed 100644 (file)
@@ -29,16 +29,23 @@ void PlaneGCSSolver_Solver::clear()
   myDOF = 0;
 }
 
-void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint)
+void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint,
+                                          const SketchSolver_ConstraintType theType)
 {
   myEquationSystem->addConstraint(theConstraint.get());
   myConstraints[theConstraint->getTag()].insert(theConstraint);
   myDOF = -1;
+
+  // Workaround: avoid tangent constraint in the list of redundant
+  if (theType == CONSTRAINT_TANGENT_CIRCLE_LINE ||
+      theType == CONSTRAINT_TANGENT_CIRCLE_CIRCLE)
+    myTangentIDs.insert(theConstraint->getTag());
 }
 
 void PlaneGCSSolver_Solver::removeConstraint(ConstraintID theID)
 {
   myConstraints.erase(theID);
+  myTangentIDs.erase(theID);
   if (myConstraints.empty()) {
     myEquationSystem->clear();
     myDOF = (int)myParameters.size();
@@ -82,6 +89,11 @@ PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve()
   GCS::SolveStatus aResult = (GCS::SolveStatus)myEquationSystem->solve(myParameters);
   Events_LongOp::end(this);
 
+  GCS::VEC_I aRedundant;
+  myEquationSystem->getRedundant(aRedundant);
+  if (!aRedundant.empty())
+    aResult = GCS::Failed;
+
   SolveStatus aStatus;
   if (aResult == GCS::Success) {
     myEquationSystem->applySolution();
@@ -113,6 +125,12 @@ void PlaneGCSSolver_Solver::collectConflicting()
   myConflictingIDs.insert(aConflict.begin(), aConflict.end());
 
   myEquationSystem->getRedundant(aConflict);
+  // Workaround: avoid conflicting tangent constraints
+  GCS::VEC_I aTemp = aConflict;
+  aConflict.clear();
+  for (GCS::VEC_I::iterator anIt = aTemp.begin(); anIt != aTemp.end(); ++anIt)
+    if (myTangentIDs.find(*anIt) == myTangentIDs.end())
+      aConflict.push_back(*anIt);
   myConflictingIDs.insert(aConflict.begin(), aConflict.end());
 
   myConfCollected = true;
index 0465924cb01987fe0b15e508156b25618302557b..810b5fab54a72d63a14f32de02dbc5f9ed81d25d 100644 (file)
@@ -32,7 +32,7 @@ public:
   void clear();
 
   /// \brief Add constraint to the system of equations
-  void addConstraint(GCSConstraintPtr theConstraint);
+  void addConstraint(GCSConstraintPtr theConstraint, const SketchSolver_ConstraintType theType);
 
   /// \brief Remove constraint from the system of equations
   void removeConstraint(ConstraintID theID);
@@ -63,6 +63,7 @@ private:
 
   GCS::VEC_pD                  myParameters;     ///< list of unknowns
   ConstraintMap                myConstraints;    ///< list of constraints
+  GCS::SET_I                   myTangentIDs;     ///< IDs of tangent constraints
 
   std::shared_ptr<GCS::System> myEquationSystem; ///< set of equations for solving in FreeGCS
 
index 62451f130256de7505785c56be1e466df49943b3..0735867197a867dcca9b13ecdd2e7e4d73bcd476 100644 (file)
 static void constraintsToSolver(const ConstraintWrapperPtr& theConstraint,
                                 const SolverPtr& theSolver)
 {
-  std::shared_ptr<PlaneGCSSolver_Solver> aSolver =
-      std::dynamic_pointer_cast<PlaneGCSSolver_Solver>(theSolver);
-  if (!aSolver)
-    return;
-
   const std::list<GCSConstraintPtr>& aConstraints =
       std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(theConstraint)->constraints();
   std::list<GCSConstraintPtr>::const_iterator anIt = aConstraints.begin();
   for (; anIt != aConstraints.end(); ++anIt)
-    aSolver->addConstraint(*anIt);
+    theSolver->addConstraint(*anIt, theConstraint->type());
 }
 
 
@@ -270,6 +265,9 @@ bool PlaneGCSSolver_Storage::removeConstraint(ConstraintPtr theConstraint)
     // Remove constraint
     myConstraintMap.erase(aFound);
 
+    if (anID != CID_MOVEMENT)
+      myNeedToResolve = true;
+
     // notify subscibers
     notify(theConstraint);
   }
index bc79c7c3e1e7d4fe3194491bb3b37b35be8e1ff5..01f30a4bf0f8411d254eeae05b13393cdfc5a6ba 100644 (file)
@@ -39,6 +39,15 @@ void PlaneGCSSolver_UpdateCoincidence::update(const FeaturePtr& theFeature)
     myNext->update(theFeature);
 }
 
+static bool hasExternalPoint(const std::set<EntityWrapperPtr>& theCoincidences)
+{
+  std::set<EntityWrapperPtr>::const_iterator anIt = theCoincidences.begin();
+  for (; anIt != theCoincidences.end(); ++anIt)
+    if ((*anIt)->type() == ENTITY_POINT && (*anIt)->isExternal())
+      return true;
+  return false;
+}
+
 bool PlaneGCSSolver_UpdateCoincidence::checkCoincidence(
     const EntityWrapperPtr& theEntity1,
     const EntityWrapperPtr& theEntity2)
@@ -65,13 +74,23 @@ bool PlaneGCSSolver_UpdateCoincidence::checkCoincidence(
     myCoincident.push_back(aNewCoinc);
   } else if (aFound1 == aFound2) // same group => already coincident
     isAccepted = false;
-  else if (aFound1 == myCoincident.end())
-    aFound2->insert(theEntity1);
-  else if (aFound2 == myCoincident.end())
-    aFound1->insert(theEntity2);
-  else { // merge two groups
-    aFound1->insert(aFound2->begin(), aFound2->end());
-    myCoincident.erase(aFound2);
+  else {
+    if (theEntity1->type() == ENTITY_POINT && theEntity2->type() == ENTITY_POINT &&
+       (theEntity1->isExternal() || theEntity2->isExternal())) {
+      bool hasExternal = aFound1 != myCoincident.end() && hasExternalPoint(*aFound1);
+      hasExternal = hasExternal || (aFound2 != myCoincident.end() && hasExternalPoint(*aFound2));
+      if (hasExternal)
+        isAccepted = false;
+    }
+
+    if (aFound1 == myCoincident.end())
+      aFound2->insert(theEntity1);
+    else if (aFound2 == myCoincident.end())
+      aFound1->insert(theEntity2);
+    else { // merge two groups
+      aFound1->insert(aFound2->begin(), aFound2->end());
+      myCoincident.erase(aFound2);
+    }
   }
 
   return isAccepted;
index 1360e1b6a71929fbed479c1fe2cbef9f14dfe4bd..7e01d45f97902516bfaf9e99fb53f81e087c2524 100644 (file)
@@ -257,8 +257,7 @@ void SketchSolver_Group::repairConsistency()
 void SketchSolver_Group::removeTemporaryConstraints()
 {
   if (!myTempConstraints.empty()) {
-    std::dynamic_pointer_cast<PlaneGCSSolver_Solver>(
-        mySketchSolver)->removeConstraint(CID_MOVEMENT);
+    mySketchSolver->removeConstraint(CID_MOVEMENT);
 
     std::set<SolverConstraintPtr>::iterator aTmpIt = myTempConstraints.begin();
     for (; aTmpIt != myTempConstraints.end(); ++aTmpIt)
index 7c6f87be0f06df201a153eb7c9bb7b1d4757a125..61694df946786d635621b5e299a9efa96421edaa 100644 (file)
@@ -238,10 +238,8 @@ std::set<ObjectPtr> SketchSolver_Storage::getConflictingConstraints(SolverPtr th
   std::map<ConstraintPtr, ConstraintWrapperPtr>::const_iterator
       aConstrIt = myConstraintMap.begin();
   for (; aConstrIt != myConstraintMap.end(); ++aConstrIt) {
-    if (theSolver->isConflicting(aConstrIt->second->id())) {
+    if (theSolver->isConflicting(aConstrIt->second->id()))
       aConflicting.insert(aConstrIt->first);
-      break;
-    }
   }
   return aConflicting;
 }