]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
PlaneGCS: Some incorrect conflicts fixed:
authorazv <azv@opencascade.com>
Wed, 8 Jun 2016 07:28:29 +0000 (10:28 +0300)
committerazv <azv@opencascade.com>
Wed, 8 Jun 2016 07:28:29 +0000 (10:28 +0300)
* Resolve system one again if there are redundant tangent constraints.
* Do not add redundant point-point coincidence constraint if multiple points are coincident.

src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp

index 4480b10261380ba67f5a465974d00a3cca4b11f6..97edb3194f29313472965934203bb0b9ea2d74bc 100644 (file)
@@ -33,22 +33,16 @@ void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint)
 void PlaneGCSSolver_Solver::removeConstraint(GCSConstraintPtr theConstraint)
 {
   GCS::Constraint* aConstraint = theConstraint.get();
-  if (myConstraints.find(aConstraint) == myConstraints.end())
-    return; // no constraint, no need to remove it
-
-  myEquationSystem.removeConstraint(aConstraint);
-  myConstraints.erase(aConstraint);
+  removeConstraint(aConstraint);
 }
 
-static void removeTangent(GCS::VEC_I& theRedundant, const GCS::SET_I& theTangent)
+void PlaneGCSSolver_Solver::removeConstraint(GCS::Constraint* theConstraint)
 {
-  int i = 0;
-  while (i < theRedundant.size()) {
-    if (theTangent.find(theRedundant[i]) == theTangent.end())
-      ++i;
-    else
-      theRedundant.erase(theRedundant.begin() + i);
-  }
+  if (myConstraints.find(theConstraint) == myConstraints.end())
+    return; // no constraint, no need to remove it
+
+  myEquationSystem.removeConstraint(theConstraint);
+  myConstraints.erase(theConstraint);
 }
 
 SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve()
@@ -87,10 +81,11 @@ SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve()
     // additionally check redundant constraints
     GCS::VEC_I aRedundantID;
     myEquationSystem.getRedundant(aRedundantID);
-    // remove redundant constraints relative to tangency
-    removeTangent(aRedundantID, myTangent);
+    // The system with tangent constraints may show redundant constraints if the entities are coupled smoothly.
+    // Sometimes tangent constraints are fall to both conflicting and redundant constraints.
+    // Need to check if there are redundant constraints without these tangencies.
     if (!aRedundantID.empty())
-      aResult = GCS::Failed;
+      aResult = myTangent.empty() ? GCS::Failed : (GCS::SolveStatus)solveWithoutTangent();
   }
   Events_LongOp::end(this);
 
@@ -104,6 +99,36 @@ SketchSolver_SolveStatus PlaneGCSSolver_Solver::solve()
   return aStatus;
 }
 
+SketchSolver_SolveStatus PlaneGCSSolver_Solver::solveWithoutTangent()
+{
+  // Remove tangency which leads to redundant or conflicting constraints
+  GCS::VEC_I aConflicting, aRedundant;
+  myEquationSystem.getRedundant(aRedundant);
+  size_t aNbRemove = aRedundant.size(); // number of tangent constraints which can be removed
+  myEquationSystem.getConflicting(aConflicting);
+  aRedundant.insert(aRedundant.end(), aConflicting.begin(), aConflicting.end());
+
+  GCS::SET_I aTangentToRemove;
+  GCS::VEC_I::iterator aCIt = aRedundant.begin();
+  for (; aCIt != aRedundant.end() && aNbRemove > 0; ++aCIt)
+    if (myTangent.find(*aCIt) != myTangent.end()) {
+      aTangentToRemove.insert(*aCIt);
+      --aNbRemove;
+    }
+
+  std::set<GCS::Constraint*>::const_iterator aConstrIt = myConstraints.begin();
+  while (aConstrIt != myConstraints.end()) {
+    GCS::Constraint* aConstraint = *aConstrIt;
+    int anID = aConstraint->getTag();
+    ++aConstrIt;
+    if (aTangentToRemove.find(anID) != aTangentToRemove.end())
+      removeConstraint(aConstraint);
+  }
+
+  myTangent.clear();
+  return solve();
+}
+
 void PlaneGCSSolver_Solver::undo()
 {
   myEquationSystem.undoSolution();
index a3c266346a19ea0a2d53775a8a834a84aad8f8df..b1dcd50f991c91a3dbcae21edc10baa6acc622f3 100644 (file)
@@ -62,6 +62,12 @@ public:
 private:
   void collectConflicting();
 
+  /// \brief Remove constraint from the system of equations
+  void removeConstraint(GCS::Constraint* theConstraint);
+
+  /// \brief Remove redundant tangent constraints and try to solve the system again
+  SketchSolver_SolveStatus solveWithoutTangent();
+
 private:
   GCS::VEC_pD                myParameters;     ///< list of unknowns
   std::set<GCS::Constraint*> myConstraints;    ///< list of constraints already processed by the system
index 35973564de988b05f8f16e1ef8e33ecacf9df07b..a21c6848b3ca60f6529a08d117f9e5dddf5237e9 100644 (file)
@@ -539,6 +539,16 @@ bool PlaneGCSSolver_Storage::isRedundant(
       return aLine->distance(aPoint) < tolerance;
     }
   }
+  else if (theParentConstraint->type() == CONSTRAINT_PT_PT_COINCIDENT) {
+    // Mark constraint redundant if the coincident points both are slaves in the list of stored coincidences
+    const std::list<EntityWrapperPtr>& aPoints = theParentConstraint->entities();
+    CoincidentPointsMap::const_iterator aCoincIt = myCoincidentPoints.begin();
+    for (; aCoincIt != myCoincidentPoints.end(); ++aCoincIt) {
+      if (aCoincIt->second.find(aPoints.front()) != aCoincIt->second.end() &&
+          aCoincIt->second.find(aPoints.back()) != aCoincIt->second.end())
+        return true;
+    }
+  }
 
   return false;
 }
@@ -570,12 +580,8 @@ void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver)
     }
     // store IDs of tangent constraints to avoid incorrect report of redundant constraints
     if (aCIt->first && aCIt->first->getKind() == SketchPlugin_ConstraintTangent::ID())
-      for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++ aCWIt) {
-        std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aGCS =
-            std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(*aCWIt);
-        if (aGCS->constraints().front()->getTypeId() == GCS::P2LDistance)
-          aTangentIDs.insert((int)(*aCWIt)->id());
-      }
+      for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++ aCWIt)
+        aTangentIDs.insert((int)(*aCWIt)->id());
   }
   // additional constraints for arcs
   std::map<EntityWrapperPtr, std::vector<GCSConstraintPtr> >::const_iterator