Salome HOME
PlaneGCS: do not constrain fixed arc (issue #1692)
authorazv <azv@opencascade.com>
Mon, 29 Aug 2016 06:39:16 +0000 (09:39 +0300)
committerazv <azv@opencascade.com>
Tue, 30 Aug 2016 04:23:55 +0000 (07:23 +0300)
Correct calculating DoF for the fixed objects

src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp
src/SketchSolver/SketchSolver_Manager.cpp

index d20e4cdc63c0bcc2e4ca5eb6f24ed751c366b42a..b090c18d4bd57a2183028297a891541fd122ebdd 100644 (file)
@@ -443,15 +443,23 @@ void PlaneGCSSolver_Storage::processArc(const EntityWrapperPtr& theArc)
       std::dynamic_pointer_cast<PlaneGCSSolver_EntityWrapper>(theArc);
   std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anArcEnt->entity());
   // Distances from center till start and end points are equal to radius
-  anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
-      anArc->center, anArc->start, anArc->rad)));
-  anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
-      anArc->center, anArc->end, anArc->rad)));
+  GCSConstraintPtr aNew = GCSConstraintPtr(new GCS::ConstraintP2PDistance(
+      anArc->center, anArc->start, anArc->rad));
+//  aNew->setTag((int)(++myConstraintLastID));
+  anArcConstraints.push_back(aNew);
+  aNew = GCSConstraintPtr(new GCS::ConstraintP2PDistance(
+      anArc->center, anArc->end, anArc->rad));
+//  aNew->setTag((int)myConstraintLastID);
+  anArcConstraints.push_back(aNew);
   // Angles of start and end points should be equal to given angles
-  anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
-      anArc->center, anArc->start, anArc->startAngle)));
-  anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
-      anArc->center, anArc->end, anArc->endAngle)));
+  aNew = GCSConstraintPtr(new GCS::ConstraintP2PAngle(
+      anArc->center, anArc->start, anArc->startAngle));
+//  aNew->setTag((int)myConstraintLastID);
+  anArcConstraints.push_back(aNew);
+  aNew = GCSConstraintPtr(new GCS::ConstraintP2PAngle(
+      anArc->center, anArc->end, anArc->endAngle));
+//  aNew->setTag((int)myConstraintLastID);
+  anArcConstraints.push_back(aNew);
 
   myArcConstraintMap[theArc] = anArcConstraints;
 }
@@ -485,9 +493,11 @@ static void getParametersToMove(const EntityWrapperPtr& theEntity, std::set<doub
     // which will conflict with all parameters fixed:
     // 1. take center
     getParametersToMove(*aSIt++, theParamList);
-    // 2. take start point
-    getParametersToMove(*aSIt++, theParamList);
-    // 3. skip end point, radius and start angle, but take end angle parameter
+    // 2. skip start and end points
+    ++aSIt;
+    // 3. take radius, start angle and end angle parameters
+    getParametersToMove(*(++aSIt), theParamList);
+    getParametersToMove(*(++aSIt), theParamList);
     getParametersToMove(*(++aSIt), theParamList);
   } else {
     for (; aSIt != aSubs.end(); ++aSIt)
index 85d5c28ad9e7b895d9b39e2136fb194098f28c30..5867d6b94ed72ee786f611536ad14829f3363c8a 100644 (file)
@@ -8,6 +8,9 @@
 #include "SketchSolver_Error.h"
 
 #include <Events_Loop.h>
+
+#include <GeomDataAPI_Point2D.h>
+
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_Data.h>
@@ -614,6 +617,7 @@ void SketchSolver_Manager::degreesOfFreedom()
       continue;
 
     std::set<AttributePtr> aCoincidentPoints;
+    std::set<AttributePtr> aFixedPoints;
     std::map<AttributePtr, std::set<FeaturePtr> > aPointOnLine;
     std::list<std::set<AttributePtr> > aPointsInMultiConstraints;
     int aDoF = 0;
@@ -649,10 +653,13 @@ void SketchSolver_Manager::degreesOfFreedom()
           }
         }
         if (aCoincPoint[0] && aCoincPoint[1]) {
+          bool isDoFDecreased = false;
           // point-point coincidence
           if (aCoincidentPoints.find(aCoincPoint[0]) == aCoincidentPoints.end() ||
-              aCoincidentPoints.find(aCoincPoint[1]) == aCoincidentPoints.end())
+              aCoincidentPoints.find(aCoincPoint[1]) == aCoincidentPoints.end()) {
             aDoF -= 2;
+            isDoFDecreased = true;
+          }
           // check the coincident point is used in "multi" constraints
           std::list<std::set<AttributePtr> >::const_iterator
               aPtIt = aPointsInMultiConstraints.begin();
@@ -664,6 +671,15 @@ void SketchSolver_Manager::degreesOfFreedom()
             if (isFound[0] && isFound[1])
               break;
           }
+          // check both points are fixed => not need to decrease DoF
+          bool isFixed[2] = { aFixedPoints.find(aCoincPoint[0]) != aFixedPoints.end(),
+                              aFixedPoints.find(aCoincPoint[1]) != aFixedPoints.end() };
+          if (isFixed[0] && isFixed[1] && isDoFDecreased)
+            aDoF += 2; // revert decrease of DoF
+          else if (isFixed[0] && !isFixed[1])
+            aFixedPoints.insert(aCoincPoint[1]);
+          else if (!isFixed[0] && isFixed[1])
+            aFixedPoints.insert(aCoincPoint[0]);
         } else {
           aDoF -= 1;
           if (aCoincPoint[0] && aCoincLine) {
@@ -711,13 +727,49 @@ void SketchSolver_Manager::degreesOfFreedom()
         AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
             aFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
         assert(aRefAttr);
-        if (!aRefAttr->isObject())
+        std::set<AttributePtr> aPoints;
+        if (!aRefAttr->isObject()) {
           aDoF -= 2; // attribute is a point
-        else {
+          aPoints.insert(aRefAttr->attr());
+        } else {
           FeaturePtr anAttr = ModelAPI_Feature::feature(aRefAttr->object());
           if (anAttr)
             aDoF -= aDoFDelta[anAttr->getKind()];
+          std::list<AttributePtr> aPtAttrs = anAttr->data()->attributes(GeomDataAPI_Point2D::typeId());
+          aPoints.insert(aPtAttrs.begin(), aPtAttrs.end());
+        }
+
+        // Check whether feature's points are already coincident with fixed points.
+        // In this case we need to revert decrease of DoF for these points.
+        // If the coordinates of fixed points are different, it will be processed by solver.
+        for (int k = 0; k < i; ++k) {
+          FeaturePtr aFeature = aSketch->subFeature(k);
+          if (aFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
+            continue;
+          AttributePtr aCoincPoint[2] = {AttributePtr(), AttributePtr()};
+          for (int j = 0; j < 2; ++j) {
+            AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                aFeature->attribute(SketchPlugin_Constraint::ATTRIBUTE(j)));
+            if (!aRefAttr)
+              continue;
+            if (!aRefAttr->isObject())
+              aCoincPoint[j] = aRefAttr->attr();
+            else {
+              FeaturePtr anAttr = ModelAPI_Feature::feature(aRefAttr->object());
+              if (anAttr && anAttr->getKind() == SketchPlugin_Point::ID())
+                aCoincPoint[j] = anAttr->attribute(SketchPlugin_Point::COORD_ID());
+            }
+          }
+          if (aCoincPoint[0] && aCoincPoint[1]) {
+            if ((aFixedPoints.find(aCoincPoint[0]) != aFixedPoints.end() &&
+                 aPoints.find(aCoincPoint[1]) != aPoints.end()) ||
+                (aFixedPoints.find(aCoincPoint[1]) != aFixedPoints.end() &&
+                 aPoints.find(aCoincPoint[0]) != aPoints.end()))
+              aDoF += 2; // point already fixed
+          }
         }
+        // store fixed points
+        aFixedPoints.insert(aPoints.begin(), aPoints.end());
       }
       else if (aFeature->getKind() == SketchPlugin_ConstraintMirror::ID() ||
                aFeature->getKind() == SketchPlugin_MultiRotation::ID() ||