]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Degrees of freedom for a sketch (issue #796)
authorazv <azv@opencascade.com>
Tue, 19 Apr 2016 07:45:27 +0000 (10:45 +0300)
committerazv <azv@opencascade.com>
Tue, 19 Apr 2016 07:45:51 +0000 (10:45 +0300)
src/ModelAPI/ModelAPI_Events.cpp
src/ModelAPI/ModelAPI_Events.h
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.cpp
src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Solver.h
src/SketchSolver/SketchSolver_ISolver.h
src/SketchSolver/SketchSolver_Manager.cpp
src/SketchSolver/SketchSolver_Manager.h
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.cpp
src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Solver.h

index 7aac578b8209ac9d9f2cc42a7d9a67bc503ad746..45f321509798da7148d9fa5380d1abad96928c23 100644 (file)
@@ -230,7 +230,8 @@ void ModelAPI_ReplaceParameterMessage::setObject(ObjectPtr theObject)
 
 // =====   ModelAPI_SolverFailedMessage   =====
 ModelAPI_SolverFailedMessage::ModelAPI_SolverFailedMessage(const Events_ID theID, const void* theSender)
-  : Events_Message(theID, theSender)
+  : Events_Message(theID, theSender),
+    myDOF(-1)
 {
 }
 
index ff549a6f809590a2efb96752a37bfe167c43eee8..656ec109aeddf4735c8351b0d597ca0ec761cbbb 100644 (file)
@@ -320,8 +320,14 @@ public:
   /// Returns list of conflicting constraints
   MODELAPI_EXPORT const std::set<ObjectPtr>& objects() const;
 
+  /// Sets degrees of freedom
+  void dof(const int theDOF) { myDOF = theDOF; }
+  /// Returns degrees of freedom
+  const int& dof() const { return myDOF; }
+
 private:
   std::set<ObjectPtr> myObjects;
+  int myDOF;
 };
 
 #endif
index 3e18488eb8b54b8a5cfef96c77825b8ac5b64ef9..be98e05d9b2cb58e1e5d4193c5cbee9d4b78003b 100644 (file)
@@ -97,3 +97,7 @@ void PlaneGCSSolver_Solver::collectConflicting()
   myConfCollected = true;
 }
 
+int PlaneGCSSolver_Solver::dof() const
+{
+  return const_cast<PlaneGCSSolver_Solver*>(this)->myEquationSystem.dofsNumber();
+}
index c2c463c5d41a9fd4954fd749832a975ceffc0241..35920bca0627aa0ed44d510968a8034db622efa6 100644 (file)
@@ -49,6 +49,9 @@ public:
   /// \brief Check the constraint is conflicted with others
   virtual bool isConflicting(const ConstraintID& theConstraint) const;
 
+  /// \brief Degrees of freedom
+  virtual int dof() const;
+
 private:
   void collectConflicting();
 
index fd992971a6759831b69f45124f5969daaab4643f..cd525405737336e56b39985edd012189e9797934 100644 (file)
@@ -50,6 +50,9 @@ public:
   /// \brief Check the constraint is conflicted with others
   virtual bool isConflicting(const ConstraintID& theConstraint) const = 0;
 
+  /// \brief Degrees of freedom
+  virtual int dof() const = 0;
+
 protected:
   GroupID myGroup;       ///< ID of the group to be solved
   bool    myFindFaileds; ///< flag to find conflicting or inappropriate constraints
index 453fbf5fc15b4eb6e5d29bed13a888fcf3666a35..2422426e3d23212fd7a27c09b8f2896f8a91b59b 100644 (file)
 #include <ModelAPI_Object.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_Attribute.h>
+#include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeString.h>
 
 #include <SketchPlugin_Constraint.h>
+#include <SketchPlugin_ConstraintAngle.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
+#include <SketchPlugin_ConstraintCollinear.h>
+#include <SketchPlugin_ConstraintDistance.h>
+#include <SketchPlugin_ConstraintEqual.h>
+#include <SketchPlugin_ConstraintHorizontal.h>
+#include <SketchPlugin_ConstraintLength.h>
+#include <SketchPlugin_ConstraintMiddle.h>
+#include <SketchPlugin_ConstraintMirror.h>
+#include <SketchPlugin_ConstraintParallel.h>
+#include <SketchPlugin_ConstraintPerpendicular.h>
+#include <SketchPlugin_ConstraintRadius.h>
+#include <SketchPlugin_ConstraintRigid.h>
+#include <SketchPlugin_ConstraintTangent.h>
+#include <SketchPlugin_ConstraintVertical.h>
+#include <SketchPlugin_MultiRotation.h>
+#include <SketchPlugin_MultiTranslation.h>
 
 #include <SketchPlugin_Arc.h>
 #include <SketchPlugin_Circle.h>
@@ -26,6 +44,7 @@
 #include <SketchPlugin_Sketch.h>
 #include <SketchPlugin_Feature.h>
 
+#include <assert.h>
 #include <list>
 #include <set>
 #include <memory>
@@ -184,6 +203,7 @@ void SketchSolver_Manager::processEvent(
         resolveConstraints(aGroupsToResolve);
     }
   }
+  degreesOfFreedom();
   myIsComputed = false;
 }
 
@@ -425,6 +445,136 @@ bool SketchSolver_Manager::resolveConstraints(const std::list<SketchSolver_Group
   return needToUpdate;
 }
 
+// ============================================================================
+//  Function: degreesOfFreedom
+//  Purpose:  calculate DoFs for each sketch
+// ============================================================================
+void SketchSolver_Manager::degreesOfFreedom()
+{
+  static std::map<std::string, int> aDoFDelta; // indicates how many DoF adds or decreases a feature
+  static bool isNeedInit = true;
+  if (isNeedInit) {
+    aDoFDelta[SketchPlugin_Point::ID()] = 2;
+    aDoFDelta[SketchPlugin_Line::ID()] = 4;
+    aDoFDelta[SketchPlugin_Circle::ID()] = 3;
+    aDoFDelta[SketchPlugin_Arc::ID()] = 5;
+
+    aDoFDelta[SketchPlugin_ConstraintAngle::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintCollinear::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintDistance::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintEqual::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintHorizontal::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintLength::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintMiddle::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintParallel::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintPerpendicular::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintRadius::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintTangent::ID()] = -1;
+    aDoFDelta[SketchPlugin_ConstraintVertical::ID()] = -1;
+
+    isNeedInit = false;
+  }
+
+  std::map<CompositeFeaturePtr, int> aSketchDoF;
+
+  std::list<SketchSolver_Group*>::const_iterator aGroupIt = myGroups.begin();
+  for (; aGroupIt != myGroups.end(); ++aGroupIt) {
+    CompositeFeaturePtr aSketch = (*aGroupIt)->getWorkplane();
+
+    // check conflicting constraints in the group
+    if ((*aGroupIt)->isFailed())
+      aSketchDoF[aSketch] = -1;
+    // check the sketch is already processed
+    if (aSketchDoF.find(aSketch) != aSketchDoF.end() || aSketchDoF[aSketch] < 0)
+      continue;
+
+    int aDoF = 0;
+    int aNbSubs = aSketch->numberOfSubs();
+    for (int i = 0; i < aNbSubs; ++i) {
+      FeaturePtr aFeature = aSketch->subFeature(i);
+      // check DoF delta for invariant types
+      std::map<std::string, int>::const_iterator aFound = aDoFDelta.find(aFeature->getKind());
+      if (aFound != aDoFDelta.end()) {
+        aDoF += aFound->second;
+        continue;
+      }
+
+      // DoF delta in specific cases
+      if (aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+        for (int j = 0; j < 2; ++j) {
+          AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+              aFeature->attribute(SketchPlugin_Constraint::ATTRIBUTE(j)));
+          if (!aRefAttr)
+            continue;
+          bool isPoint = !aRefAttr->isObject();
+          if (!isPoint) {
+            FeaturePtr anAttr = ModelAPI_Feature::feature(aRefAttr->object());
+            isPoint = anAttr && anAttr->getKind() == SketchPlugin_Point::ID();
+          }
+          if (isPoint)
+            aDoF -= 1;
+        }
+      }
+      else if (aFeature->getKind() == SketchPlugin_ConstraintRigid::ID()) {
+        AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+            aFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
+        assert(aRefAttr);
+        if (!aRefAttr->isObject())
+          aDoF -= 2; // attribute is a point
+        else {
+          FeaturePtr anAttr = ModelAPI_Feature::feature(aRefAttr->object());
+          assert(anAttr);
+          aDoF -= aDoFDelta[anAttr->getKind()];
+        }
+      }
+      else if (aFeature->getKind() == SketchPlugin_ConstraintMirror::ID() ||
+               aFeature->getKind() == SketchPlugin_MultiRotation::ID() ||
+               aFeature->getKind() == SketchPlugin_MultiTranslation::ID()) {
+        int aNbCopies = 1;
+        std::string anAttrName;
+        if (aFeature->getKind() == SketchPlugin_ConstraintMirror::ID())
+          anAttrName = SketchPlugin_Constraint::ENTITY_B();
+        else {
+          if (aFeature->getKind() == SketchPlugin_MultiRotation::ID())
+            aNbCopies = aFeature->integer(SketchPlugin_MultiRotation::NUMBER_OF_OBJECTS_ID())->value() - 1;
+          else if (aFeature->getKind() == SketchPlugin_MultiTranslation::ID())
+            aNbCopies = aFeature->integer(SketchPlugin_MultiTranslation::NUMBER_OF_OBJECTS_ID())->value() - 1;
+          anAttrName = SketchPlugin_Constraint::ENTITY_A();
+        }
+
+        AttributeRefListPtr aRefListOfShapes = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+            aFeature->attribute(anAttrName));
+        std::list<ObjectPtr> anObjList = aRefListOfShapes->list();
+        std::list<ObjectPtr>::const_iterator anObjIt = anObjList.begin();
+        for (; anObjIt != anObjList.end(); ++anObjIt) {
+          FeaturePtr aSub = ModelAPI_Feature::feature(*anObjIt);
+          aDoF -= aDoFDelta[aSub->getKind()] * aNbCopies;
+        }
+      }
+    }
+
+    aSketchDoF[aSketch] = aDoF;
+  }
+
+  // Check the degrees of freedom are changed
+  std::map<CompositeFeaturePtr, int>::const_iterator aDoFIt = aSketchDoF.begin();
+  std::map<CompositeFeaturePtr, int>::iterator aFound;
+  for (; aDoFIt != aSketchDoF.end(); ++aDoFIt) {
+    if (aDoFIt->second < 0)
+      continue; // conflicting constraints on the current sketch
+    aFound = myDoF.find(aDoFIt->first);
+    if (aFound != myDoF.end() && aFound->second == aDoFIt->second)
+      continue; // nothing is changed
+    myDoF[aDoFIt->first] = aDoFIt->second;
+    // send a message
+    std::shared_ptr<ModelAPI_SolverFailedMessage> aMessage =
+        std::shared_ptr<ModelAPI_SolverFailedMessage>(
+        new ModelAPI_SolverFailedMessage(Events_Loop::eventByName(EVENT_SOLVER_REPAIRED)));
+    aMessage->dof(aDoFIt->second);
+    Events_Loop::loop()->send(aMessage);
+  }
+}
+
 bool SketchSolver_Manager::stopSendUpdate() const
 {
   // to avoid redisplay of each segment on update by solver one by one in the viewer
index 42ec9df676b4c8a07b80ae83f1566571a739430b..0781129c0f2c43cb1e0aae70299e4ef18115220c 100644 (file)
@@ -113,6 +113,9 @@ private:
   ///        find other groups on the same sketch, which have conflicts.
   void checkConflictingConstraints(const std::shared_ptr<Events_Message>& theMessage);
 
+  /// \brief Calculate DoF for each sketch and send messages if changed
+  void degreesOfFreedom();
+
 private:
   static SketchSolver_Manager*     mySelf;    ///< Self pointer to implement singleton functionality
   std::list<SketchSolver_Group*>   myGroups;  ///< Groups of constraints
@@ -120,6 +123,8 @@ private:
   /// true if computation is performed and all "updates" are generated by this algo
   /// and needs no recomputation
   bool myIsComputed;
+
+  std::map<CompositeFeaturePtr, int> myDoF; ///< Degree of freedom for corresponding sketch
 };
 
 #endif
index f1d72c8bac59a8de424a3c96f09464fa0f1f8600..2adb7dcd62fa79332c9d0737f716e5116ffc2c2b 100644 (file)
@@ -205,3 +205,8 @@ bool SolveSpaceSolver_Solver::isConflicting(const ConstraintID& theConstraint) c
       return true;
   return false;
 }
+
+int SolveSpaceSolver_Solver::dof() const
+{
+  return myEquationsSystem.dof;
+}
index cc78b95a6eb04061c2d9916fa221e892fb430406..b804217076fd3025c91ff38a7ec3737e6f81d087 100644 (file)
@@ -83,6 +83,9 @@ public:
   /// \brief Check the constraint is conflicted with others
   virtual bool isConflicting(const ConstraintID& theConstraint) const;
 
+  /// \brief Degrees of freedom
+  virtual int dof() const;
+
 private:
   /// \brief Check whether degenerated arcs exist
   bool hasDegeneratedArcs() const;