Salome HOME
Adjust processing of Coincidence constraint by PlaneGCSSolver
authorazv <azv@opencascade.com>
Mon, 6 Mar 2017 14:34:09 +0000 (17:34 +0300)
committerazv <azv@opencascade.com>
Mon, 6 Mar 2017 15:17:38 +0000 (18:17 +0300)
Fix misprint in Test1673.py

src/SketchPlugin/Test/Test1673.py
src/SketchPlugin/Test/TestFillet.py
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_UpdateCoincidence.cpp

index 550515673408f2d0383e9578592aa3cebb1c2e32..6bb2d8b02c2a8d4248ca48197308d0d5d1031fae 100644 (file)
@@ -260,13 +260,12 @@ for ang in range(0, 50):
     aEndPoint.setValue(X, Y)
     model.do()
     movementTime = timer() - movementTime
-    print movementTime
     assert movementTime < expectedTime, "Time to move point {0} is greater than expected {1}".format(movementTime, expectedTime)
     assert math.fabs(aEndPoint.x() - X) < TOLERANCE and math.fabs(aEndPoint.y() - Y) < TOLERANCE, "({0}, {1}) != ({2}, {3})".format(aEndPoint.x(), aEndPoint.y(), X, Y)
     averageTime += movementTime
     nbMoves += 1
     aDeltaX = aEndPoint.x() - aCenter.x()
-    aDeltaY - aEndPoint.y() - aCenter.y()
+    aDeltaY = aEndPoint.y() - aCenter.y()
 print "Movement average time: {0}".format(averageTime / nbMoves)
 
 model.end()
index e58e27ba8e9af3040c76258fa86e67acf88f1452..45d0d09d59c8f1db9b5dfb308920f9efb7fbfcfa 100644 (file)
@@ -225,7 +225,7 @@ aRadius.setValue(FILLET_RADIUS2)
 aFillet.execute()
 aSession.finishOperation()
 checkFillet(aResObjects, FILLET_RADIUS2)
-assert model.dof(aSketchFeature) == 14, "PlaneGCS limitation: if you see this message, then PlaneGCS has solved DoF for sketch with fillet correctly (expected DoF = 10, observed = {0}".format(model.dof(aSketchFeature))
+assert model.dof(aSketchFeature) == 8, "PlaneGCS limitation: if you see this message, then PlaneGCS has solved DoF for sketch with fillet correctly (expected DoF = 10, observed = {0}".format(model.dof(aSketchFeature))
 
 #=========================================================================
 # Create another sketch
index fb64ef10a3c0752a1fcfaddcd0d8d52b9973a9ed..5b34fd59a0f5abcd3b2b0baf3e97d3e661bf4d15 100644 (file)
@@ -38,14 +38,17 @@ void PlaneGCSSolver_Solver::addConstraint(GCSConstraintPtr theConstraint,
 
   // Workaround: avoid tangent constraint in the list of redundant
   if (theType == CONSTRAINT_TANGENT_CIRCLE_LINE ||
-      theType == CONSTRAINT_TANGENT_CIRCLE_CIRCLE)
-    myTangentIDs.insert(theConstraint->getTag());
+      theType == CONSTRAINT_TANGENT_CIRCLE_CIRCLE ||
+      theType == CONSTRAINT_PT_PT_COINCIDENT ||
+      theType == CONSTRAINT_PT_ON_CIRCLE ||
+      theType == CONSTRAINT_PT_ON_LINE)
+    myConstraintIDsNotRedundant.insert(theConstraint->getTag());
 }
 
 void PlaneGCSSolver_Solver::removeConstraint(ConstraintID theID)
 {
   myConstraints.erase(theID);
-  myTangentIDs.erase(theID);
+  myConstraintIDsNotRedundant.erase(theID);
   if (myConstraints.empty()) {
     myEquationSystem->clear();
     myDOF = (int)myParameters.size();
@@ -91,8 +94,11 @@ PlaneGCSSolver_Solver::SolveStatus PlaneGCSSolver_Solver::solve()
 
   GCS::VEC_I aRedundant;
   myEquationSystem->getRedundant(aRedundant);
-  if (!aRedundant.empty())
-    aResult = GCS::Failed;
+  if (!aRedundant.empty()) {
+    collectConflicting();
+    if (!myConflictingIDs.empty())
+      aResult = GCS::Failed;
+  }
 
   SolveStatus aStatus;
   if (aResult == GCS::Success) {
@@ -129,7 +135,7 @@ void PlaneGCSSolver_Solver::collectConflicting()
   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())
+    if (myConstraintIDsNotRedundant.find(*anIt) == myConstraintIDsNotRedundant.end())
       aConflict.push_back(*anIt);
   myConflictingIDs.insert(aConflict.begin(), aConflict.end());
 
index 810b5fab54a72d63a14f32de02dbc5f9ed81d25d..b019a314c0c16327afb1e738cd3cf3d3c5355013 100644 (file)
@@ -63,7 +63,10 @@ private:
 
   GCS::VEC_pD                  myParameters;     ///< list of unknowns
   ConstraintMap                myConstraints;    ///< list of constraints
-  GCS::SET_I                   myTangentIDs;     ///< IDs of tangent constraints
+
+  /// IDs of constraints (coincidence, tangency) which will not be treated as conflicting
+  /// if they are reported as redundant
+  GCS::SET_I                   myConstraintIDsNotRedundant;
 
   std::shared_ptr<GCS::System> myEquationSystem; ///< set of equations for solving in FreeGCS
 
index 01f30a4bf0f8411d254eeae05b13393cdfc5a6ba..1ac316855a6df221b2c2ed07e6bd43ce4cb27e94 100644 (file)
@@ -39,11 +39,12 @@ void PlaneGCSSolver_UpdateCoincidence::update(const FeaturePtr& theFeature)
     myNext->update(theFeature);
 }
 
-static bool hasExternalPoint(const std::set<EntityWrapperPtr>& theCoincidences)
+static bool hasAnotherExternalPoint(const std::set<EntityWrapperPtr>& theCoincidences,
+                                    const EntityWrapperPtr& thePoint)
 {
   std::set<EntityWrapperPtr>::const_iterator anIt = theCoincidences.begin();
   for (; anIt != theCoincidences.end(); ++anIt)
-    if ((*anIt)->type() == ENTITY_POINT && (*anIt)->isExternal())
+    if ((*anIt)->type() == ENTITY_POINT && (*anIt)->isExternal() && *anIt != thePoint)
       return true;
   return false;
 }
@@ -55,41 +56,49 @@ bool PlaneGCSSolver_UpdateCoincidence::checkCoincidence(
   bool isAccepted = true;
 
   std::list<std::set<EntityWrapperPtr> >::iterator anIt = myCoincident.begin();
-  std::list<std::set<EntityWrapperPtr> >::iterator aFound1 = myCoincident.end();
-  std::list<std::set<EntityWrapperPtr> >::iterator aFound2 = myCoincident.end();
+  std::list<std::set<EntityWrapperPtr> >::iterator
+      aFound[2] = {myCoincident.end(), myCoincident.end()};
+
   for (; anIt != myCoincident.end(); ++anIt) {
-    if (aFound1 == myCoincident.end() && anIt->find(theEntity1) != anIt->end())
-      aFound1 = anIt;
-    if (aFound2 == myCoincident.end() && anIt->find(theEntity2) != anIt->end())
-      aFound2 = anIt;
-    if (aFound1 != myCoincident.end() && aFound2 != myCoincident.end())
+    if (aFound[0] == myCoincident.end() && anIt->find(theEntity1) != anIt->end())
+      aFound[0] = anIt;
+    if (aFound[1] == myCoincident.end() && anIt->find(theEntity2) != anIt->end())
+      aFound[1] = anIt;
+    if (aFound[0] != myCoincident.end() && aFound[1] != myCoincident.end())
       break;
   }
 
-  if (aFound1 == myCoincident.end() && aFound2 == myCoincident.end()) {
+  if (aFound[0] == myCoincident.end() && aFound[1] == myCoincident.end()) {
     // new group of coincidence
     std::set<EntityWrapperPtr> aNewCoinc;
     aNewCoinc.insert(theEntity1);
     aNewCoinc.insert(theEntity2);
     myCoincident.push_back(aNewCoinc);
-  } else if (aFound1 == aFound2) // same group => already coincident
+  } else if (aFound[0] == aFound[1]) // same group => already coincident
     isAccepted = false;
   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));
+      bool hasExternal = false;
+      for (int i = 0; i < 2 && !hasExternal; ++i) {
+        if (aFound[i] != myCoincident.end()) {
+          if (theEntity1->isExternal())
+            hasExternal = hasAnotherExternalPoint(*aFound[i], theEntity1);
+          if (!hasExternal && theEntity2->isExternal())
+            hasExternal = hasAnotherExternalPoint(*aFound[i], theEntity2);
+        }
+      }
       if (hasExternal)
         isAccepted = false;
     }
 
-    if (aFound1 == myCoincident.end())
-      aFound2->insert(theEntity1);
-    else if (aFound2 == myCoincident.end())
-      aFound1->insert(theEntity2);
+    if (aFound[0] == myCoincident.end())
+      aFound[1]->insert(theEntity1);
+    else if (aFound[1] == myCoincident.end())
+      aFound[0]->insert(theEntity2);
     else { // merge two groups
-      aFound1->insert(aFound2->begin(), aFound2->end());
-      myCoincident.erase(aFound2);
+      aFound[0]->insert(aFound[1]->begin(), aFound[1]->end());
+      myCoincident.erase(aFound[1]);
     }
   }