]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
PlaneGCSSolver: Update processing coincident points. Test cases correction.
authorazv <azv@opencascade.com>
Wed, 8 Jun 2016 11:29:15 +0000 (14:29 +0300)
committerazv <azv@opencascade.com>
Wed, 8 Jun 2016 11:29:15 +0000 (14:29 +0300)
src/PythonAPI/examples/Platine.py
src/SketchPlugin/Test/TestConstraintMirror.py
src/SketchPlugin/Test/TestConstraintTangent.py
src/SketchPlugin/Test/TestSketchArcCircle.py
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Builder.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h

index bb22d28821444f91420f15882a085424f3794123..05f985b546329a3bbbcc364e5c1d19fba2488fdd 100644 (file)
@@ -125,7 +125,7 @@ def body_3():
     geom_points = [geom.Pnt2d(*p) for p in points]
     left, top_left, top_middle, top_right, right, bottom, = sketch.addPolygon(*geom_points)
 
-    points = [(l + r, H), (l, H), (l + 2 * r, H)]
+    points = [(l + r, H), (l + 2 * r, H), (l, H)]
     points = [(p[0], -p[1]) for p in points]  # as we look to back of the face
     center, start, end = [geom.Pnt2d(*p) for p in points]
     arc = sketch.addArc(center, start, end)
index 319a725d6cf4c2112bebc2685985de69488aa9c8..bbf74982a86484fac94d9c9d0f80eca931c719e5 100644 (file)
@@ -21,14 +21,20 @@ __updated__ = "2015-03-17"
 #=========================================================================
 # Auxiliary functions
 #=========================================================================
+def normalize(theDir):
+    aLen = math.hypot(theDir[0], theDir[1])
+    if aLen < 1.e-10:
+        aLen = 1.0
+    return [theDir[0] / aLen, theDir[1] / aLen]
+
 def checkMirror(theListInit, theListMirr, theMirrorLine):
-    TOL = 1.e-8
+    TOL = 5.e-5
     aListSize = theListInit.size()
     
     aLineStartPoint = geomDataAPI_Point2D(theMirrorLine.attribute("StartPoint"))
     aLineEndPoint = geomDataAPI_Point2D(theMirrorLine.attribute("EndPoint"))
-    aLineDirX = aLineEndPoint.x() - aLineStartPoint.x()
-    aLineDirY = aLineEndPoint.y() - aLineStartPoint.y()
+    aLineDir = [aLineEndPoint.x() - aLineStartPoint.x(), aLineEndPoint.y() - aLineStartPoint.y()]
+    aLineDir = normalize(aLineDir)
 
     for ind in range(0, aListSize):
         aFeatureB = ModelAPI_Feature.feature(theListInit.object(ind))
@@ -46,13 +52,13 @@ def checkMirror(theListInit, theListMirr, theMirrorLine):
         for key in anAttributes:
             aPointB = geomDataAPI_Point2D(aFeatureB.attribute(key))
             aPointC = geomDataAPI_Point2D(aFeatureC.attribute(anAttributes[key]))
-            aDirX = aPointC.x() - aPointB.x()
-            aDirY = aPointC.y() - aPointB.y()
-            aDot = aLineDirX * aDirX + aLineDirY * aDirY
+            aDir = [aPointC.x() - aPointB.x(), aPointC.y() - aPointB.y()]
+            aDir = normalize(aDir)
+            aDot = aLineDir[0] * aDir[0] + aLineDir[1] * aDir[1]
             assert math.fabs(aDot) < TOL, "aDot = {0}".format(aDot)
             aDirX = aLineEndPoint.x() - 0.5 * (aPointB.x() + aPointC.x())
             aDirY = aLineEndPoint.y() - 0.5 * (aPointB.y() + aPointC.y())
-            aCross = aLineDirX * aDirY - aLineDirY * aDirX
+            aCross = aLineDir[0] * aDir[0] - aLineDir[1] * aDir[1]
             assert math.fabs(aCross) < TOL, "aCross = {0}".format(aCross)
 
 
index 48ed166d71ea7483baa738cab02ab2e3affde54e..df3cd3115ac72f8c589ee84217a87d730eb9d098 100644 (file)
@@ -301,7 +301,7 @@ aRefObjectB.setObject(anObjectB)
 aTangency.execute()
 aSession.finishOperation()
 
-assert(math.fabs(distancePointLine(aCircleCenter, aLine) - aCircleRadius.value()) < 1.e-10)
+assert(math.fabs(distancePointLine(aCircleCenter, aLine) - round(aCircleRadius.value(), 5)) < 1.e-10)
 #=========================================================================
 # End of test
 #=========================================================================
index e15964a1be155c845b494128d02da898d26f6157..8d8c4c82043cfe51a01da07904e9716b08986605 100644 (file)
@@ -53,6 +53,19 @@ def distancePointPoint(thePointA, thePointB):
     ydiff = math.pow((thePointA.y() - thePointB.y()), 2)
     return round(math.sqrt(xdiff + ydiff), 5)
 
+def dot(thePoint11, thePoint12, thePoint21, thePoint22):
+    """
+    subroutine to calculate dit product between lines given by their points
+    """
+    aDirX1 = thePoint12.x() - thePoint11.x()
+    aDirY1 = thePoint12.y() - thePoint11.y()
+    aLen1 = math.hypot(aDirX1, aDirY1)
+    aDirX2 = thePoint22.x() - thePoint21.x()
+    aDirY2 = thePoint22.y() - thePoint21.y()
+    aLen2 = math.hypot(aDirX2, aDirY2)
+    aDot = aDirX1 * aDirX2 + aDirY1 * aDirY2
+    return aDot / aLen1 / aLen2
+
 
 aSession = ModelAPI_Session.get()
 aDocument = aSession.moduleDocument()
@@ -217,7 +230,8 @@ aSession.startOperation()
 anArcEndPoint.setValue(100., 25.)
 aSession.finishOperation()
 anArcCenter = geomDataAPI_Point2D(aSketchArcTangent.attribute("ArcCenter"))
-assert(anArcCenter.x() == 50.)
+aDot = dot(anArcCenter, aLineEnd, aLineStart, aLineEnd)
+assert math.fabs(aDot) <= 2.e-4, "Observed dot product: {0}".format(aDot)
 #=========================================================================
 # Create an arc, tangent to the previous arc
 #=========================================================================
index 0213cceaa76bf3ed1534564c16104362afd3c18a..5e101d2401e376e45e682b762ee37f6cb7dff7cb 100644 (file)
@@ -1077,6 +1077,11 @@ ConstraintWrapperPtr createConstraintEqual(
         new GCS::ConstraintP2PDistance(aLine1->p1, aLine1->p2, theIntermed->parameter())));
     aConstrList.push_back(GCSConstraintPtr(
         new GCS::ConstraintP2PDistance(aLine2->p1, aLine2->p2, theIntermed->parameter())));
+    // update value of intermediate parameter
+    double x = *aLine1->p1.x - *aLine1->p2.x;
+    double y = *aLine1->p1.y - *aLine1->p2.y;
+    double aLen = sqrt(x*x + y*y);
+    theIntermed->setValue(aLen);
   } else {
     std::shared_ptr<GCS::Circle> aCirc1 =
         std::dynamic_pointer_cast<GCS::Circle>(theEntity1->entity());
index a21c6848b3ca60f6529a08d117f9e5dddf5237e9..2fc9185d289eca0e14d39633326e72f58620b502 100644 (file)
@@ -527,7 +527,8 @@ void PlaneGCSSolver_Storage::updateCoincident(const EntityWrapperPtr& thePoint)
 
 bool PlaneGCSSolver_Storage::isRedundant(
     GCSConstraintPtr theCheckedConstraint,
-    ConstraintWrapperPtr theParentConstraint) const
+    ConstraintWrapperPtr theParentConstraint,
+    std::list<std::set<double*> >& theCoincidentPoints) const
 {
   if (theParentConstraint->type() == CONSTRAINT_SYMMETRIC) {
     if (theCheckedConstraint->getTypeId() == GCS::Perpendicular) {
@@ -540,13 +541,36 @@ bool PlaneGCSSolver_Storage::isRedundant(
     }
   }
   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())
+    // Verify that the coincidence between points is already added
+    GCS::VEC_pD aParams = theCheckedConstraint->params();
+
+    std::list<std::set<double*> >::iterator aCoincIt, aFound1, aFound2;
+    aFound1 = aFound2 = theCoincidentPoints.end();
+    for (aCoincIt = theCoincidentPoints.begin(); aCoincIt != theCoincidentPoints.end(); ++aCoincIt) {
+      if (aFound1 == theCoincidentPoints.end() && aCoincIt->find(aParams[0]) != aCoincIt->end())
+        aFound1 = aCoincIt;
+      if (aFound2 == theCoincidentPoints.end() && aCoincIt->find(aParams[1]) != aCoincIt->end())
+        aFound2 = aCoincIt;
+      if (aFound1 != theCoincidentPoints.end() && aFound2 != theCoincidentPoints.end())
+        break;
+    }
+    if (aCoincIt != theCoincidentPoints.end()) { // both point are found
+      if (aFound1 == aFound2)
         return true;
+      // merge two groups of coincidence
+      aFound1->insert(aFound2->begin(), aFound2->end());
+      theCoincidentPoints.erase(aFound2);
+    } else {
+      if (aFound1 != theCoincidentPoints.end())
+        aFound1->insert(aParams[1]);
+      else if (aFound2 != theCoincidentPoints.end())
+        aFound2->insert(aParams[0]);
+      else {
+        std::set<double*> aNewCoincidence;
+        aNewCoincidence.insert(aParams[0]);
+        aNewCoincidence.insert(aParams[1]);
+        theCoincidentPoints.push_back(aNewCoincidence);
+      }
     }
   }
 
@@ -568,6 +592,7 @@ void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver)
   std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
       aCIt = myConstraintMap.begin();
   GCS::SET_I aTangentIDs;
+  std::list<std::set<double*> > aCoincidentPoints;
   for (; aCIt != myConstraintMap.end(); ++aCIt) {
     std::list<ConstraintWrapperPtr>::const_iterator aCWIt = aCIt->second.begin();
     for (; aCWIt != aCIt->second.end(); ++ aCWIt) {
@@ -575,7 +600,7 @@ void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver)
           std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(*aCWIt);
       std::list<GCSConstraintPtr>::const_iterator anIt = aGCS->constraints().begin();
       for (; anIt != aGCS->constraints().end(); ++anIt)
-        if (!isRedundant(*anIt, aGCS))
+        if (!isRedundant(*anIt, aGCS, aCoincidentPoints))
           aSolver->addConstraint(*anIt);
     }
     // store IDs of tangent constraints to avoid incorrect report of redundant constraints
index dd71f9eedbc3a4449dcbde3ca4eb9c34988ddeb4..643a6df6fe0fe0d66fa0b9c425d1a1ad62313b43 100644 (file)
@@ -107,7 +107,9 @@ private:
   ///
   /// This is a workaround method to avoid some kinds of conflicting constraints:
   ///   * symmetric of two points placed on the mirror line (do not add perpendicular constraint)
-  bool isRedundant(GCSConstraintPtr theCheckedConstraint, ConstraintWrapperPtr theParentConstraint) const;
+  bool isRedundant(GCSConstraintPtr theCheckedConstraint,
+                   ConstraintWrapperPtr theParentConstraint,
+                   std::list<std::set<double*> >& theCoincidentPoints = std::list<std::set<double*> >() ) const;
 
 private:
   GCS::VEC_pD                      myParameters;         ///< list of parameters