Salome HOME
Merge branch 'Dev_1.1.0' of newgeom:newgeom into Dev_1.1.0
[modules/shaper.git] / src / SketchSolver / SketchSolver_Constraint.cpp
index 6d4fdee3330506efff1dc38bb4618042a4428e81..e4af2a0643970b1518b35cd344566ccaffdce20a 100644 (file)
@@ -1,3 +1,5 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
 // File:    SketchSolver_Constraint.cpp
 // Created: 27 May 2014
 // Author:  Artem ZHIDKOV
 #include <SketchPlugin_Arc.h>
 #include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_ConstraintDistance.h>
+#include <SketchPlugin_ConstraintEqual.h>
+#include <SketchPlugin_ConstraintHorizontal.h>
 #include <SketchPlugin_ConstraintLength.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 <ModelAPI_AttributeRefAttr.h>
 #include <ModelAPI_Data.h>
@@ -40,17 +46,17 @@ enum AttrType
 };
 
 /// Calculate type of the attribute
-static AttrType typeOfAttribute(boost::shared_ptr<ModelAPI_Attribute> theAttribute);
+static AttrType typeOfAttribute(std::shared_ptr<ModelAPI_Attribute> theAttribute);
 
 SketchSolver_Constraint::SketchSolver_Constraint()
-    : myConstraint(boost::shared_ptr<SketchPlugin_Constraint>()),
+    : myConstraint(std::shared_ptr<SketchPlugin_Constraint>()),
       myType(SLVS_C_UNKNOWN),
       myAttributesList()
 {
 }
 
 SketchSolver_Constraint::SketchSolver_Constraint(
-    boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
+    std::shared_ptr<SketchPlugin_Constraint> theConstraint)
     : myConstraint(theConstraint),
       myAttributesList()
 {
@@ -58,7 +64,7 @@ SketchSolver_Constraint::SketchSolver_Constraint(
 }
 
 const int& SketchSolver_Constraint::getType(
-    boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
+    std::shared_ptr<SketchPlugin_Constraint> theConstraint)
 {
   myType = SLVS_C_UNKNOWN;
   if (!theConstraint)
@@ -81,7 +87,7 @@ const int& SketchSolver_Constraint::getType(
     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_Attribute> anAttr = 
+      std::shared_ptr<ModelAPI_Attribute> anAttr = 
           aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       if (!anAttr)
         continue;
@@ -112,7 +118,7 @@ const int& SketchSolver_Constraint::getType(
     int aNbPoints = 0;
     int aNbEntities = 0;
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
-      boost::shared_ptr<ModelAPI_Attribute> anAttr = 
+      std::shared_ptr<ModelAPI_Attribute> anAttr = 
           aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       switch (typeOfAttribute(anAttr)) {
         case POINT2D:
@@ -138,7 +144,7 @@ const int& SketchSolver_Constraint::getType(
   if (aConstraintKind.compare(SketchPlugin_ConstraintLength::ID()) == 0) {
     int aNbLines = 0;
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
-      boost::shared_ptr<ModelAPI_Attribute> anAttr = 
+      std::shared_ptr<ModelAPI_Attribute> anAttr = 
           aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       if (typeOfAttribute(anAttr) == LINE)
         myAttributesList[aNbLines++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
@@ -154,7 +160,7 @@ const int& SketchSolver_Constraint::getType(
   if (isParallel || isPerpendicular) {
     int aNbEntities = 2;  // lines in SolveSpace constraints should start from SketchPlugin_Constraint::ENTITY_C() attribute
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
-      boost::shared_ptr<ModelAPI_Attribute> anAttr = 
+      std::shared_ptr<ModelAPI_Attribute> anAttr = 
           aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       if (typeOfAttribute(anAttr) == LINE)
         myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
@@ -168,7 +174,7 @@ const int& SketchSolver_Constraint::getType(
   if (aConstraintKind.compare(SketchPlugin_ConstraintRadius::ID()) == 0) {
     int aNbEntities = 2;  // lines in SolveSpace constraints should started from SketchPlugin_Constraint::ENTITY_C() attribute
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
-      boost::shared_ptr<ModelAPI_Attribute> anAttr = 
+      std::shared_ptr<ModelAPI_Attribute> anAttr = 
           aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       AttrType aType = typeOfAttribute(anAttr);
       if (aType == CIRCLE || aType == ARC)
@@ -184,7 +190,7 @@ const int& SketchSolver_Constraint::getType(
     // Verify that only one entity is filled
     int aNbAttrs = 0;
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
-      boost::shared_ptr<ModelAPI_Attribute> anAttr = 
+      std::shared_ptr<ModelAPI_Attribute> anAttr = 
           aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
       AttrType aType = typeOfAttribute(anAttr);
       if (aType != UNKNOWN)
@@ -195,21 +201,82 @@ const int& SketchSolver_Constraint::getType(
     return getType();
   }
 
+  // Constraint for horizontal/vertical line
+  bool isHorizontal = (aConstraintKind.compare(SketchPlugin_ConstraintHorizontal::ID()) == 0);
+  bool isVertical = (aConstraintKind.compare(SketchPlugin_ConstraintVertical::ID()) == 0);
+  if (isHorizontal || isVertical) {
+    int aNbEntities = 2;  // lines in SolveSpace constraints should start from SketchPlugin_Constraint::ENTITY_C() attribute
+    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
+      std::shared_ptr<ModelAPI_Attribute> anAttr = 
+          aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      if (typeOfAttribute(anAttr) == LINE)
+        myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+    }
+    if (aNbEntities == 3)
+      myType = isHorizontal ? SLVS_C_HORIZONTAL : SLVS_C_VERTICAL;
+    return getType();
+  }
+
+  if (aConstraintKind.compare(SketchPlugin_ConstraintEqual::ID()) == 0)
+  {
+    static const int aConstrType[3] = {
+        SLVS_C_EQUAL_RADIUS,
+        SLVS_C_EQUAL_LINE_ARC_LEN,
+        SLVS_C_EQUAL_LENGTH_LINES
+    };
+    int aNbLines = 0;
+    int aNbEntities = 2;  // lines and circles in SolveSpace constraints should start from SketchPlugin_Constraint::ENTITY_C() attribute
+    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
+      std::shared_ptr<ModelAPI_Attribute> anAttr = 
+          aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      AttrType aType = typeOfAttribute(anAttr);
+      if (aType == LINE) {
+        myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+        aNbLines++;
+      }
+      else if (aType == CIRCLE || aType == ARC)
+        myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+    }
+    if (aNbEntities == 4)
+      myType = aConstrType[aNbLines];
+    return getType();
+  }
+
+  if (aConstraintKind.compare(SketchPlugin_ConstraintTangent::ID()) == 0)
+  {
+    static const int anArcPosDefault = 2;
+    static const int aLinePosDefault = 3;
+    int anArcPos = anArcPosDefault; // arc in tangency constraint should be placed before line
+    int aLinePos = aLinePosDefault;
+    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
+      std::shared_ptr<ModelAPI_Attribute> anAttr = 
+          aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      AttrType aType = typeOfAttribute(anAttr);
+      if (aType == LINE && aLinePos < CONSTRAINT_ATTR_SIZE)
+        myAttributesList[aLinePos++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+      else if (aType == ARC)
+        myAttributesList[anArcPos++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+    }
+    if (anArcPos - anArcPosDefault + aLinePos - aLinePosDefault == 2)
+      myType = aLinePos > 3 ? SLVS_C_ARC_LINE_TANGENT : SLVS_C_CURVE_CURVE_TANGENT;
+    return getType();
+  }
+
   /// \todo Implement other kind of constraints
 
   return getType();
 }
 
 // ================= Auxiliary functions ==============================
-AttrType typeOfAttribute(boost::shared_ptr<ModelAPI_Attribute> theAttribute)
+AttrType typeOfAttribute(std::shared_ptr<ModelAPI_Attribute> theAttribute)
 {
-  boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttrRef = boost::dynamic_pointer_cast<
+  std::shared_ptr<ModelAPI_AttributeRefAttr> anAttrRef = std::dynamic_pointer_cast<
       ModelAPI_AttributeRefAttr>(theAttribute);
   if (!anAttrRef)
     return UNKNOWN;
 
   if (anAttrRef->isObject()) {
-    ResultConstructionPtr aRC = boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
+    ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
         anAttrRef->object());
     if (!aRC || !aRC->shape())
       return UNKNOWN;
@@ -217,7 +284,7 @@ AttrType typeOfAttribute(boost::shared_ptr<ModelAPI_Attribute> theAttribute)
     if (aRC->shape()->isVertex())
       return POINT3D;
     else if (aRC->shape()->isEdge()) {
-      boost::shared_ptr<GeomAPI_Edge> anEdge = boost::dynamic_pointer_cast<GeomAPI_Edge>(
+      std::shared_ptr<GeomAPI_Edge> anEdge = std::dynamic_pointer_cast<GeomAPI_Edge>(
           aRC->shape());
       if (anEdge->isLine())
         return LINE;
@@ -227,11 +294,13 @@ AttrType typeOfAttribute(boost::shared_ptr<ModelAPI_Attribute> theAttribute)
         return ARC;
     }
   } else {
-    const std::string aType = anAttrRef->attr()->attributeType();
-    if (aType == GeomDataAPI_Point2D::type())
-      return POINT2D;
-    if (aType == GeomDataAPI_Point2D::type())
-      return POINT2D;
+    if (anAttrRef->attr().get() != NULL) {
+      const std::string aType = anAttrRef->attr()->attributeType();
+      if (aType == GeomDataAPI_Point2D::type())
+        return POINT2D;
+      if (aType == GeomDataAPI_Point2D::type())
+        return POINT2D;
+    }
   }
 
   return UNKNOWN;