]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Small refactoring of SketchSolver.
authorazv <azv@opencascade.com>
Tue, 27 May 2014 06:19:56 +0000 (10:19 +0400)
committerazv <azv@opencascade.com>
Tue, 27 May 2014 06:19:56 +0000 (10:19 +0400)
Added SketchSolver_Constraint class to obtain information about constraints

src/SketchSolver/CMakeLists.txt
src/SketchSolver/SketchSolver_Constraint.cpp [new file with mode: 0644]
src/SketchSolver/SketchSolver_Constraint.h [new file with mode: 0644]
src/SketchSolver/SketchSolver_ConstraintManager.cpp
src/SketchSolver/SketchSolver_ConstraintManager.h
src/SketchSolver/SketchSolver_Solver.h

index 4656f25d530a1f00f4ed054757ab26a3d4c36f63..7c60c7f2e591d32df93df39d61167a2abdeb92ab 100644 (file)
@@ -4,11 +4,13 @@ INCLUDE(FindSolveSpace)
 SET(PROJECT_HEADERS
     SketchSolver.h
     SketchSolver_Solver.h
+    SketchSolver_Constraint.h
     SketchSolver_ConstraintManager.h
 )
 
 SET(PROJECT_SOURCES
     SketchSolver_Solver.cpp
+    SketchSolver_Constraint.cpp
     SketchSolver_ConstraintManager.cpp
 )
 
diff --git a/src/SketchSolver/SketchSolver_Constraint.cpp b/src/SketchSolver/SketchSolver_Constraint.cpp
new file mode 100644 (file)
index 0000000..2bfd8e6
--- /dev/null
@@ -0,0 +1,192 @@
+// File:    SketchSolver_Constraint.cpp
+// Created: 27 May 2014
+// Author:  Artem ZHIDKOV
+
+#include "SketchSolver_Constraint.h"
+#include <SketchSolver_Solver.h>
+
+#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_Data.h>
+
+#include <GeomDataAPI_Point.h>
+#include <GeomDataAPI_Point2D.h>
+
+
+SketchSolver_Constraint::SketchSolver_Constraint()
+  : myConstraint(boost::shared_ptr<SketchPlugin_Constraint>()),
+    myType(SLVS_C_UNKNOWN),
+    myAttributesList()
+{
+}
+
+SketchSolver_Constraint::SketchSolver_Constraint(
+                boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
+  : myConstraint(theConstraint),
+    myAttributesList()
+{
+  myType = getType(myConstraint);
+}
+
+const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
+{
+  myType = SLVS_C_UNKNOWN;
+  if (!theConstraint)
+    return getType();
+
+  // Assign empty names of attributes
+  myAttributesList.clear();
+  for (int i = 0; i < CONSTRAINT_ATTR_SIZE; i++)
+    myAttributesList.push_back(std::string());
+
+  const std::string& aConstraintKind = theConstraint->getKind();
+  // Constraint for coincidence of two points
+  if (aConstraintKind.compare("SketchConstraintCoincidence") == 0)
+  {
+    int anAttrPos = 0;
+    // Verify the constraint has only two attributes and they are points
+    int aPt2d = 0; // bit-mapped field, each bit indicates whether the attribute is 2D point
+    int aPt3d = 0; // bit-mapped field, the same information for 3D points
+    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
+    {
+      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
+        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
+        );
+      if (!anAttr) continue;
+      // Verify the attribute is a 2D point
+      boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
+        boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
+      if (aPoint2D)
+      {
+        aPt2d |= (1 << indAttr);
+        myAttributesList[anAttrPos++] = CONSTRAINT_ATTRIBUTES[indAttr];
+        continue;
+      }
+      // Verify the attribute is a 3D point
+      boost::shared_ptr<GeomDataAPI_Point> aPoint3D =
+        boost::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->attr());
+      if (aPoint3D)
+      {
+        aPt3d |= (1 << indAttr);
+        myAttributesList[anAttrPos++] = CONSTRAINT_ATTRIBUTES[indAttr];
+        continue;
+      }
+      // Attribute neither 2D nor 3D point is not supported by this type of constraint
+      return getType();
+    }
+    // The constrained points should be in first and second positions,
+    // so the expected value of aPt2d or aPt3d is 3
+    if ((aPt2d == 3 && aPt3d == 0) || (aPt2d == 0 && aPt3d == 3))
+      myType = SLVS_C_POINTS_COINCIDENT;
+    // Constraint parameters are wrong
+    return getType();
+  }
+
+  // Constraint for distance between point and another entity
+  if (aConstraintKind.compare("SketchConstraintDistance") == 0)
+  {
+    int aNbPoints = 0;
+    int aNbEntities = 0;
+    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
+    {
+      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
+        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
+        );
+      if (!anAttr) continue;
+      if (anAttr->isFeature())
+      { // verify posiible entities
+        const std::string& aKind = anAttr->feature()->getKind();
+        if (aKind.compare("SketchPoint") == 0)
+        {
+          myAttributesList[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
+          continue;
+        }
+        else if(aKind.compare("SketchLine") == 0)
+        {
+          // entities are placed starting from CONSTRAINT_ATTR_ENTITY_C attribute
+          myAttributesList[2 + aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
+          myType = SLVS_C_PT_LINE_DISTANCE;
+          continue;
+        }
+      }
+      else
+      { // verify points
+        // Verify the attribute is a 2D point
+        boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
+          boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
+        if (aPoint2D)
+        {
+          myAttributesList[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
+          continue;
+        }
+        // Verify the attribute is a 3D point
+        boost::shared_ptr<GeomDataAPI_Point> aPoint3D =
+          boost::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->attr());
+        if (aPoint3D)
+        {
+          myAttributesList[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
+          continue;
+        }
+      }
+    }
+    // Verify the correctness of constraint arguments
+    if (aNbPoints == 2 && aNbEntities ==0)
+      myType = SLVS_C_PT_PT_DISTANCE;
+    else if (aNbPoints == 1 && aNbEntities == 1)
+      myType = SLVS_C_UNKNOWN;
+    return getType();
+  }
+
+  // Constraint for two parallel/perpendicular lines
+  bool isParallel = (aConstraintKind.compare("SketchConstraintParallel") == 0);
+  bool isPerpendicular = (aConstraintKind.compare("SketchConstraintPerpendicular") == 0);
+  if (isParallel || isPerpendicular)
+  {
+    int aNbEntities = 2; // lines in SolveSpace constraints should started from CONSTRAINT_ATTR_ENTITY_C attribute
+    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
+    {
+      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
+        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
+        );
+      if (!anAttr || !anAttr->isFeature()) continue;
+      const std::string& aKind = anAttr->feature()->getKind();
+      if (aKind.compare("SketchLine") == 0)
+      {
+        myAttributesList[aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
+        continue;
+      }
+    }
+    if (aNbEntities == 4)
+      myType = isParallel ? SLVS_C_PARALLEL : SLVS_C_PERPENDICULAR;
+    return getType();
+  }
+
+  // Constraint for diameter of a circle
+  if (aConstraintKind.compare("SketchConstraintDiameter") == 0)
+  {
+    int aNbEntities = 2; // lines in SolveSpace constraints should started from CONSTRAINT_ATTR_ENTITY_C attribute
+    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
+    {
+      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
+        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
+        );
+      if (!anAttr || !anAttr->isFeature()) continue;
+      const std::string& aKind = anAttr->feature()->getKind();
+      if (aKind.compare("SketchCircle") == 0)
+      {
+        myAttributesList[aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
+        continue;
+      }
+    }
+    if (aNbEntities == 3)
+      myType = SLVS_C_DIAMETER;
+    return getType();
+  }
+
+  /// \todo Implement other kind of constrtaints
+
+  return getType();
+}
diff --git a/src/SketchSolver/SketchSolver_Constraint.h b/src/SketchSolver/SketchSolver_Constraint.h
new file mode 100644 (file)
index 0000000..934415b
--- /dev/null
@@ -0,0 +1,45 @@
+// File:    SketchSolver_Constraint.h
+// Created: 27 May 2014
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchSolver_Constraint_Headerfile
+#define SketchSolver_Constraint_Headerfile
+
+#include "SketchSolver.h"
+
+#include <SketchPlugin_Constraint.h>
+
+#include <string>
+#include <vector>
+
+/** \class   SketchSolver_Constraint
+ *  \ingroup DataModel
+ *  \brief   Obtain information about SketchPlugin's constraint
+ */
+class SketchSolver_Constraint
+{
+public:
+  SketchSolver_Constraint();
+  SketchSolver_Constraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+
+  /** \brief Compute constraint type according to SolveSpace identifiers
+   *         and verify that constraint parameters are correct
+   *  \param[in]  theConstraint constraint which type should be determined
+   *  \return identifier of constraint type or SLVS_C_UNKNOWN if the type is wrong
+   */
+  const int& getType(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+  /// \brief Returns the type of myConstraint member
+  inline const int& getType() const
+  { return myType; }
+
+  /// \brief Returns list of attributes names in the correct order required by SolveSpace
+  inline const std::vector<std::string>& getAttributes() const
+  { return myAttributesList; }
+
+private:
+  boost::shared_ptr<SketchPlugin_Constraint> myConstraint;
+  int                                        myType;
+  std::vector<std::string>                   myAttributesList;
+};
+
+#endif
index c02da61a72e40f22fa93311535dede7c3492d306..4fd5b4f07b44ebda60e1867fadd695e5952dc589 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "SketchSolver_ConstraintManager.h"
 
+#include <SketchSolver_Constraint.h>
+
 #include <Events_Loop.h>
 #include <GeomDataAPI_Dir.h>
 #include <GeomDataAPI_Point.h>
@@ -483,11 +485,12 @@ bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeConstra
   }
 
   // Get constraint type and verify the constraint parameters are correct
-  std::vector<std::string> aConstraintAttributes;
-  int aConstrType = getConstraintType(theConstraint, aConstraintAttributes);
+  SketchSolver_Constraint aConstraint(theConstraint);
+  int aConstrType = aConstraint.getType();
   if (aConstrType == SLVS_C_UNKNOWN ||
      (aConstrMapIter != myConstraintMap.end() && aConstrIter->type != aConstrType))
     return false;
+  const std::vector<std::string>& aConstraintAttributes = aConstraint.getAttributes();
 
   // Create constraint parameters
   double aDistance = 0.0; // scalar value of the constraint
@@ -812,173 +815,6 @@ Slvs_hParam SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::change
   return aParam.h;
 }
 
-// ============================================================================
-//  Function: getConstraintType
-//  Class:    SketchSolver_ConstraintGroup
-//  Purpose:  calculate the type of constraint using its parameters
-// ============================================================================
-int SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::getConstraintType(
-                const boost::shared_ptr<SketchPlugin_Constraint>& theConstraint,
-                std::vector<std::string>&                         theAttrNames) const
-{
-  // Assign empty names of attributes
-  for (int i = 0; i < CONSTRAINT_ATTR_SIZE; i++)
-    theAttrNames.push_back(std::string());
-
-  const std::string& aConstraintKind = theConstraint->getKind();
-  // Constraint for coincidence of two points
-  if (aConstraintKind.compare("SketchConstraintCoincidence") == 0)
-  {
-    int anAttrPos = 0;
-    // Verify the constraint has only two attributes and they are points
-    int aPt2d = 0; // bit-mapped field, each bit indicates whether the attribute is 2D point
-    int aPt3d = 0; // bit-mapped field, the same information for 3D points
-    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
-    {
-      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
-        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-          theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
-        );
-      if (!anAttr) continue;
-      // Verify the attribute is a 2D point
-      boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
-        boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
-      if (aPoint2D)
-      {
-        aPt2d |= (1 << indAttr);
-        theAttrNames[anAttrPos++] = CONSTRAINT_ATTRIBUTES[indAttr];
-        continue;
-      }
-      // Verify the attribute is a 3D point
-      boost::shared_ptr<GeomDataAPI_Point> aPoint3D =
-        boost::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->attr());
-      if (aPoint3D)
-      {
-        aPt3d |= (1 << indAttr);
-        theAttrNames[anAttrPos++] = CONSTRAINT_ATTRIBUTES[indAttr];
-        continue;
-      }
-      // Attribute neither 2D nor 3D point is not supported by this type of constraint
-      return SLVS_C_UNKNOWN;
-    }
-    // The constrained points should be in first and second positions,
-    // so the expected value of aPt2d or aPt3d is 3
-    if ((aPt2d == 3 && aPt3d == 0) || (aPt2d == 0 && aPt3d == 3))
-      return SLVS_C_POINTS_COINCIDENT;
-    // Constraint parameters are wrong
-    return SLVS_C_UNKNOWN;
-  }
-
-  // Constraint for distance between point and another entity
-  if (aConstraintKind.compare("SketchConstraintDistance") == 0)
-  {
-    int aResult = SLVS_C_UNKNOWN; // possible constraint type
-    int aNbPoints = 0;
-    int aNbEntities = 0;
-    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
-    {
-      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
-        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-          theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
-        );
-      if (!anAttr) continue;
-      if (anAttr->isFeature())
-      { // verify posiible entities
-        const std::string& aKind = anAttr->feature()->getKind();
-        if (aKind.compare("SketchPoint") == 0)
-        {
-          theAttrNames[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
-          continue;
-        }
-        else if(aKind.compare("SketchLine") == 0)
-        {
-          // entities are placed starting from CONSTRAINT_ATTR_ENTITY_C attribute
-          theAttrNames[2 + aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
-          aResult = SLVS_C_PT_LINE_DISTANCE;
-          continue;
-        }
-      }
-      else
-      { // verify points
-        // Verify the attribute is a 2D point
-        boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
-          boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
-        if (aPoint2D)
-        {
-          theAttrNames[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
-          continue;
-        }
-        // Verify the attribute is a 3D point
-        boost::shared_ptr<GeomDataAPI_Point> aPoint3D =
-          boost::dynamic_pointer_cast<GeomDataAPI_Point>(anAttr->attr());
-        if (aPoint3D)
-        {
-          theAttrNames[aNbPoints++] = CONSTRAINT_ATTRIBUTES[indAttr];
-          continue;
-        }
-      }
-    }
-    // Verify the correctness of constraint arguments
-    if (aNbPoints == 2 && aNbEntities ==0)
-      aResult = SLVS_C_PT_PT_DISTANCE;
-    else if (aNbPoints == 1 && aNbEntities == 1)
-      aResult = SLVS_C_UNKNOWN;
-    return aResult;
-  }
-
-  // Constraint for two parallel/perpendicular lines
-  bool isParallel = (aConstraintKind.compare("SketchConstraintParallel") == 0);
-  bool isPerpendicular = (aConstraintKind.compare("SketchConstraintPerpendicular") == 0);
-  if (isParallel || isPerpendicular)
-  {
-    int aNbEntities = 2; // lines in SolveSpace constraints should started from CONSTRAINT_ATTR_ENTITY_C attribute
-    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
-    {
-      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
-        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-          theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
-        );
-      if (!anAttr || !anAttr->isFeature()) continue;
-      const std::string& aKind = anAttr->feature()->getKind();
-      if (aKind.compare("SketchLine") == 0)
-      {
-        theAttrNames[aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
-        continue;
-      }
-    }
-    if (aNbEntities == 4)
-      return isParallel ? SLVS_C_PARALLEL : SLVS_C_PERPENDICULAR;
-    return SLVS_C_UNKNOWN;
-  }
-
-  // Constraint for diameter of a circle
-  if (aConstraintKind.compare("SketchConstraintDiameter") == 0)
-  {
-    int aNbEntities = 2; // lines in SolveSpace constraints should started from CONSTRAINT_ATTR_ENTITY_C attribute
-    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
-    {
-      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
-        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-          theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
-        );
-      if (!anAttr || !anAttr->isFeature()) continue;
-      const std::string& aKind = anAttr->feature()->getKind();
-      if (aKind.compare("SketchCircle") == 0)
-      {
-        theAttrNames[aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
-        continue;
-      }
-    }
-    if (aNbEntities == 3)
-      return SLVS_C_DIAMETER;
-    return SLVS_C_UNKNOWN;
-  }
-
-  /// \todo Implement other kind of constrtaints
-
-  return SLVS_C_UNKNOWN;
-}
-
 // ============================================================================
 //  Function: resolveConstraints
 //  Class:    SketchSolver_ConstraintGroup
index 5bbfe2f69501eb23e46e85cdd8770d1a6514eaae..548d20f100076bb2bb1088ee6d3168e455efa087 100644 (file)
 #include <set>
 
 
-// Unknown constraint (for error reporting)
-#define SLVS_C_UNKNOWN 0
-// Unknown entity
-#define SLVS_E_UNKNOWN 0
-
 /** \class   SketchSolver_ConstraintManager
  *  \ingroup DataModel
  *  \brief   Listens the changes of SketchPlugin features and transforms the Constraint
@@ -216,15 +211,6 @@ protected:
   Slvs_hParam changeParameter(const double& theParam,
                               std::vector<Slvs_Param>::const_iterator& thePrmIter);
 
-  /** \brief Compute constraint type according to SolveSpace identifiers
-   *         and verify that constraint parameters are correct
-   *  \param[in]  theConstraint constraint which type should be determined
-   *  \param[out] theAttrNames  names of attributes in order required by SolveSpace (unused attributes have empty names)
-   *  \return identifier of constraint type or SLVS_C_UNKNOWN if the type is wrong
-   */
-  int getConstraintType(const boost::shared_ptr<SketchPlugin_Constraint>& theConstraint, 
-                        std::vector<std::string>& theAttrNames) const;
-
   /** \brief Change values of attribute by parameters received from SolveSpace solver
    *  \param[in,out] theAttribute pointer to the attribute to be changed
    *  \param[in]     theEntityID  identifier of SolveSpace entity, which contains updated data
index 944a58e69354102e1d694b7c6efbb314ea175a5f..19408410a35415e49fc297d9db20873e5efb035a 100644 (file)
@@ -21,6 +21,11 @@ typedef unsigned int UINT32;
 
 #define SLVS_RESULT_EMPTY_SET -1
 
+// Unknown constraint (for error reporting)
+#define SLVS_C_UNKNOWN 0
+// Unknown entity
+#define SLVS_E_UNKNOWN 0
+
 
 class SketchSolver_Solver
 {