]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Crash on constraint creation due to new structure of the Model library
authorazv <azv@opencascade.com>
Thu, 24 Jul 2014 12:23:32 +0000 (16:23 +0400)
committerazv <azv@opencascade.com>
Thu, 24 Jul 2014 12:23:32 +0000 (16:23 +0400)
src/GeomAPI/CMakeLists.txt
src/GeomAPI/GeomAPI_Edge.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_Edge.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_Shape.cpp
src/GeomAPI/GeomAPI_Shape.h
src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp
src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.h
src/SketchSolver/CMakeLists.txt
src/SketchSolver/SketchSolver_Constraint.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.cpp

index e13d4b27048c5da6b489893bffb70c124f77cad3..0b2eb97638ccd07f2e16601243f3e76c9c373da6 100644 (file)
@@ -18,8 +18,9 @@ SET(PROJECT_HEADERS
     GeomAPI_Dir2d.h
     GeomAPI_Pln.h
     GeomAPI_Shape.h
+    GeomAPI_Edge.h
     GeomAPI_AISObject.h
-       GeomAPI_IPresentable.h
+    GeomAPI_IPresentable.h
 )
 
 SET(PROJECT_SOURCES
@@ -36,6 +37,7 @@ SET(PROJECT_SOURCES
     GeomAPI_Dir2d.cpp
     GeomAPI_Pln.cpp
     GeomAPI_Shape.cpp
+    GeomAPI_Edge.cpp
     GeomAPI_AISObject.cpp
 )
 
diff --git a/src/GeomAPI/GeomAPI_Edge.cpp b/src/GeomAPI/GeomAPI_Edge.cpp
new file mode 100644 (file)
index 0000000..8d8bf02
--- /dev/null
@@ -0,0 +1,52 @@
+// File:        GeomAPI_Edge.cpp
+// Created:     24 Jul 2014
+// Author:      Artem ZHIDKOV
+
+#include<GeomAPI_Edge.h>
+
+#include <TopoDS_Shape.hxx>
+#include <BRep_TEdge.hxx>
+#include <BRep_CurveRepresentation.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Circle.hxx>
+
+GeomAPI_Edge::GeomAPI_Edge()
+  : GeomAPI_Shape()
+{}
+
+bool GeomAPI_Edge::isLine() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+  Handle(BRep_TEdge) anEdge = Handle(BRep_TEdge)::DownCast(aShape.TShape());
+  if (anEdge->Curves().Extent() != 1)
+    return false; // too many curves in the edge
+  Handle(Geom_Curve) aCurve = anEdge->Curves().First()->Curve3D();
+  if (aCurve->IsKind(STANDARD_TYPE(Geom_Line)))
+    return true;
+  return false;
+}
+
+bool GeomAPI_Edge::isCircle() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+  Handle(BRep_TEdge) anEdge = Handle(BRep_TEdge)::DownCast(aShape.TShape());
+  if (anEdge->Curves().Extent() != 1)
+    return false; // too many curves in the edge
+  Handle(Geom_Curve) aCurve = anEdge->Curves().First()->Curve3D();
+  if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle)) && aCurve->IsClosed())
+    return true;
+  return false;
+}
+
+bool GeomAPI_Edge::isArc() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+  Handle(BRep_TEdge) anEdge = Handle(BRep_TEdge)::DownCast(aShape.TShape());
+  if (anEdge->Curves().Extent() != 1)
+    return false; // too many curves in the edge
+  Handle(Geom_Curve) aCurve = anEdge->Curves().First()->Curve3D();
+  if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle)) && !aCurve->IsClosed())
+    return true;
+  return false;
+}
diff --git a/src/GeomAPI/GeomAPI_Edge.h b/src/GeomAPI/GeomAPI_Edge.h
new file mode 100644 (file)
index 0000000..584e475
--- /dev/null
@@ -0,0 +1,40 @@
+// File:        GeomAPI_Edge.hxx
+// Created:     24 Jul 2014
+// Author:      Artem ZHIDKOV
+
+#ifndef GeomAPI_Edge_HeaderFile
+#define GeomAPI_Edge_HeaderFile
+
+#include <GeomAPI_Shape.h>
+
+/**\class GeomAPI_Edge
+ * \ingroup DataModel
+ * \brief Interface to the edge object
+ */
+
+class GEOMAPI_EXPORT GeomAPI_Edge: public GeomAPI_Shape
+{
+public:
+  /// Creation of empty (null) shape
+  GeomAPI_Edge();
+
+  /// Returns whether the shape is a vertex
+  virtual bool isVertex() const
+  { return false; }
+
+  /// Returns whether the shape is an edge
+  virtual bool isEdge() const
+  { return true; }
+
+  /// Verifies that the edge is a line
+  bool isLine() const;
+
+  /// Verifies that the edge is a circle
+  bool isCircle() const;
+
+  /// Verifies that the edge is an arc of circle
+  bool isArc() const;
+};
+
+#endif
+
index e662ea2548c0c26cb72e81cd89b65684cb874a0c..f7f05846a114a12466e5333e16b7f02e4f839448 100644 (file)
@@ -4,10 +4,22 @@
 
 #include<GeomAPI_Shape.h>
 
-#include<TopoDS_Shape.hxx>
+#include <TopoDS_Shape.hxx>
 
 #define MY_PNT static_cast<gp_Pnt*>(myImpl)
 
 GeomAPI_Shape::GeomAPI_Shape()
   : GeomAPI_Interface(new TopoDS_Shape())
 {}
+
+bool GeomAPI_Shape::isVertex() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+  return aShape.TShape()->ShapeType() == TopAbs_VERTEX;
+}
+
+bool GeomAPI_Shape::isEdge() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Shape*>(this)->impl<TopoDS_Shape>();
+  return aShape.TShape()->ShapeType() == TopAbs_EDGE;
+}
index 8a9d3b26c9a1b81076ec086b292bb0f328ec0318..7394bee05c088fc8ef10b60185e4f85b9ac5b5ea 100644 (file)
@@ -17,6 +17,12 @@ class GEOMAPI_EXPORT GeomAPI_Shape: public GeomAPI_Interface
 public:
   /// Creation of empty (null) shape
   GeomAPI_Shape();
+
+  /// Returns whether the shape is a vertex
+  virtual bool isVertex() const;
+
+  /// Returns whether the shape is an edge
+  virtual bool isEdge() const;
 };
 
 #endif
index 6b8ebd9463d5cdba2b43bbf16e3177729148ee5f..0e622ba36958ba6581158c8babd8b1d65c87ee25 100644 (file)
 #include <gp_Ax2.hxx>
 #include <gp_Circ.hxx>
 
-boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_EdgeBuilder::line(
+boost::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::line(
   boost::shared_ptr<GeomAPI_Pnt> theStart, boost::shared_ptr<GeomAPI_Pnt> theEnd)
 {
   const gp_Pnt& aStart = theStart->impl<gp_Pnt>();
   const gp_Pnt& anEnd = theEnd->impl<gp_Pnt>();
 
   if (aStart.IsEqual(anEnd, Precision::Confusion()))
-    return boost::shared_ptr<GeomAPI_Shape>();
+    return boost::shared_ptr<GeomAPI_Edge>();
   if (Abs(aStart.SquareDistance(anEnd)) > 1.e+100)
-    return boost::shared_ptr<GeomAPI_Shape>();
+    return boost::shared_ptr<GeomAPI_Edge>();
   BRepBuilderAPI_MakeEdge anEdgeBuilder(aStart, anEnd);
-  boost::shared_ptr<GeomAPI_Shape> aRes(new GeomAPI_Shape);
+  boost::shared_ptr<GeomAPI_Edge> aRes(new GeomAPI_Edge);
   TopoDS_Edge anEdge = anEdgeBuilder.Edge();
   aRes->setImpl(new TopoDS_Shape(anEdge));
   return aRes;
 }
 
-boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_EdgeBuilder::lineCircle(
+boost::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::lineCircle(
     boost::shared_ptr<GeomAPI_Pnt> theCenter,
     boost::shared_ptr<GeomAPI_Dir> theNormal, double theRadius)
 {
@@ -40,13 +40,13 @@ boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_EdgeBuilder::lineCircle(
   gp_Circ aCircle(gp_Ax2(aCenter, aDir), theRadius);
 
   BRepBuilderAPI_MakeEdge anEdgeBuilder(aCircle);
-  boost::shared_ptr<GeomAPI_Shape> aRes(new GeomAPI_Shape);
+  boost::shared_ptr<GeomAPI_Edge> aRes(new GeomAPI_Edge);
   TopoDS_Edge anEdge = anEdgeBuilder.Edge();
   aRes->setImpl(new TopoDS_Shape(anEdge));
   return aRes;
 }
 
-boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_EdgeBuilder::lineCircleArc(
+boost::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::lineCircleArc(
     boost::shared_ptr<GeomAPI_Pnt> theCenter,
     boost::shared_ptr<GeomAPI_Pnt> theStartPoint,
     boost::shared_ptr<GeomAPI_Pnt> theEndPoint,
@@ -68,12 +68,12 @@ boost::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_EdgeBuilder::lineCircleArc(
   else
     anEdgeBuilder = BRepBuilderAPI_MakeEdge(aCircle, aStart, anEnd);
 
-  boost::shared_ptr<GeomAPI_Shape> aRes(new GeomAPI_Shape);
+  boost::shared_ptr<GeomAPI_Edge> aRes(new GeomAPI_Edge);
   anEdgeBuilder.Build();
 
   if (anEdgeBuilder.IsDone())
     aRes->setImpl(new TopoDS_Shape(anEdgeBuilder.Edge()));
   else
-    aRes = boost::shared_ptr<GeomAPI_Shape>();
+    aRes = boost::shared_ptr<GeomAPI_Edge>();
   return aRes;
 }
index de532ea563fa18fce180685c69441865107cdb53..bb01b7bf52d96a912bfe33a1ef8ed72bfb7ad8c8 100644 (file)
@@ -6,7 +6,7 @@
 #define GeomAlgoAPI_EdgeBuilder_HeaderFile
 
 #include <GeomAlgoAPI.h>
-#include <GeomAPI_Shape.h>
+#include <GeomAPI_Edge.h>
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_Dir.h>
 #include <boost/shared_ptr.hpp>
@@ -20,16 +20,16 @@ class GEOMALGOAPI_EXPORT GeomAlgoAPI_EdgeBuilder
 {
 public:
   /// Creates linear edge by two points
-  static boost::shared_ptr<GeomAPI_Shape> line(
+  static boost::shared_ptr<GeomAPI_Edge> line(
     boost::shared_ptr<GeomAPI_Pnt> theStart, boost::shared_ptr<GeomAPI_Pnt> theEnd);
 
   /// Creates linear edge in a form of a circle by a point and a circle radius
-  static boost::shared_ptr<GeomAPI_Shape> lineCircle(
+  static boost::shared_ptr<GeomAPI_Edge> lineCircle(
     boost::shared_ptr<GeomAPI_Pnt> theCenter,
     boost::shared_ptr<GeomAPI_Dir> theNormal, double theRadius);
 
   /// Creates linear edge in a form of a circle arc by a three points
-  static boost::shared_ptr<GeomAPI_Shape> lineCircleArc(
+  static boost::shared_ptr<GeomAPI_Edge> lineCircleArc(
     boost::shared_ptr<GeomAPI_Pnt> theCenter,
     boost::shared_ptr<GeomAPI_Pnt> theStartPoint,
     boost::shared_ptr<GeomAPI_Pnt> theEndPoint,
index 8964c31f8c012b4a22a45141a3a98ef22ff7a18f..a8525ee70e2db7d9e705981f7e1d97b5c9306470 100644 (file)
@@ -20,6 +20,7 @@ SET(PROJECT_LIBRARIES
     ${SLVS_LIBRARIES}
     Events
     ModelAPI
+    GeomAPI
 )
 
 INCLUDE_DIRECTORIES(
index 05f261a69f11f1033e8773ceb0b81b496260f8cd..f831c170b530197631577a77e3955334bff83615 100644 (file)
@@ -9,6 +9,7 @@
 #include <SketchPlugin_Point.h>
 #include <SketchPlugin_Circle.h>
 #include <SketchPlugin_Arc.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_ConstraintDistance.h>
 #include <SketchPlugin_ConstraintLength.h>
 #include <SketchPlugin_ConstraintParallel.h>
 
 #include <ModelAPI_AttributeRefAttr.h>
 #include <ModelAPI_Data.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Object.h>
+#include <ModelAPI_ResultConstruction.h>
 
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Point2D.h>
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Shape.h>
+
+/// Possible types of attributes (used to determine constraint type)
+enum AttrType
+{
+  UNKNOWN, // Something wrong during type determination
+  POINT2D,
+  POINT3D,
+  LINE,
+  CIRCLE,
+  ARC
+};
+
+/// Calculate type of the attribute
+static AttrType typeOfAttribute(boost::shared_ptr<ModelAPI_Attribute> theAttribute);
+
 
 
 SketchSolver_Constraint::SketchSolver_Constraint()
@@ -50,7 +71,7 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Const
 
   const std::string& aConstraintKind = theConstraint->getKind();
   // Constraint for coincidence of two points
-  if (aConstraintKind.compare("SketchConstraintCoincidence") == 0)
+  if (aConstraintKind.compare(SketchPlugin_ConstraintCoincidence::ID()) == 0)
   {
     int anAttrPos = 0;
     // Verify the constraint has only two attributes and they are points
@@ -58,31 +79,22 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Const
     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(SketchPlugin_Constraint::ATTRIBUTE(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)
+      boost::shared_ptr<ModelAPI_Attribute> anAttr =
+        theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      switch (typeOfAttribute(anAttr))
       {
+      case POINT2D: // the attribute is a 2D point
         aPt2d |= (1 << indAttr);
         myAttributesList[anAttrPos++] = SketchPlugin_Constraint::ATTRIBUTE(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)
-      {
+        break;
+      case POINT3D: // the attribute is a 3D point
         aPt3d |= (1 << indAttr);
         myAttributesList[anAttrPos++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
-        continue;
+        break;
+      default:
+        // Attribute neither 2D nor 3D point is not supported by this type of constraint
+        return getType();
       }
-      // 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
@@ -99,52 +111,25 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Const
     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(SketchPlugin_Constraint::ATTRIBUTE(indAttr))
-        );
-      if (!anAttr) continue;
-      if (anAttr->isObject() && anAttr->object())
-      { // verify posiible entities
-        const std::string& aKind = boost::dynamic_pointer_cast<ModelAPI_Feature>
-          (anAttr->object())->getKind();
-        if (aKind.compare(SketchPlugin_Point::ID()) == 0)
-        {
+      boost::shared_ptr<ModelAPI_Attribute> anAttr =
+        theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      switch (typeOfAttribute(anAttr))
+      {
+      case POINT2D:
+      case POINT3D:
           myAttributesList[aNbPoints++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
-          continue;
-        }
-        else if(aKind.compare(SketchPlugin_Line::ID()) == 0)
-        {
+          break;
+      case LINE:
           // entities are placed starting from SketchPlugin_Constraint::ENTITY_C() attribute
           myAttributesList[2 + aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(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++] = SketchPlugin_Constraint::ATTRIBUTE(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++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
-          continue;
-        }
+          break;
       }
     }
     // Verify the correctness of constraint arguments
     if (aNbPoints == 2 && aNbEntities ==0)
       myType = SLVS_C_PT_PT_DISTANCE;
-    else if (aNbPoints == 1 && aNbEntities == 1)
+    else if (aNbPoints != 1 || aNbEntities != 1)
       myType = SLVS_C_UNKNOWN;
     return getType();
   }
@@ -155,18 +140,10 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Const
     int aNbLines = 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(SketchPlugin_Constraint::ATTRIBUTE(indAttr))
-        );
-      if (!anAttr) continue;
-      if (anAttr->isObject() && anAttr->object() &&
-        boost::dynamic_pointer_cast<ModelAPI_Feature>(anAttr->object())->getKind().
-        compare(SketchPlugin_Line::ID()) == 0)
-      {
+      boost::shared_ptr<ModelAPI_Attribute> anAttr =
+        theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      if (typeOfAttribute(anAttr) == LINE)
         myAttributesList[aNbLines++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
-        break;
-      }
     }
     if (aNbLines == 1)
       myType = SLVS_C_PT_PT_DISTANCE;
@@ -178,21 +155,13 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Const
   bool isPerpendicular = (aConstraintKind.compare(SketchPlugin_ConstraintPerpendicular::ID()) == 0);
   if (isParallel || isPerpendicular)
   {
-    int aNbEntities = 2; // lines in SolveSpace constraints should started from SketchPlugin_Constraint::ENTITY_C() attribute
+    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_AttributeRefAttr> anAttr =
-        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-          theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr))
-        );
-      if (!anAttr || !anAttr->isObject() || !anAttr->object()) continue;
-      const std::string& aKind = boost::dynamic_pointer_cast<ModelAPI_Feature>
-        (anAttr->object())->getKind();
-      if (aKind.compare(SketchPlugin_Line::ID()) == 0)
-      {
+      boost::shared_ptr<ModelAPI_Attribute> anAttr =
+        theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      if (typeOfAttribute(anAttr) == LINE)
         myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
-        continue;
-      }
     }
     if (aNbEntities == 4)
       myType = isParallel ? SLVS_C_PARALLEL : SLVS_C_PERPENDICULAR;
@@ -205,25 +174,59 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Const
     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_AttributeRefAttr> anAttr =
-        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-          theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr))
-        );
-      if (!anAttr || !anAttr->isObject() || !anAttr->object()) continue;
-      const std::string& aKind = boost::dynamic_pointer_cast<ModelAPI_Feature>
-        (anAttr->object())->getKind();
-      if (aKind.compare(SketchPlugin_Circle::ID()) == 0 || aKind.compare(SketchPlugin_Arc::ID()) == 0)
-      {
+      boost::shared_ptr<ModelAPI_Attribute> anAttr =
+        theConstraint->data()->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+      AttrType aType = typeOfAttribute(anAttr);
+      if (aType == CIRCLE || aType == ARC)
         myAttributesList[aNbEntities++] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
-        continue;
-      }
     }
     if (aNbEntities == 3)
       myType = SLVS_C_DIAMETER;
     return getType();
   }
 
-  /// \todo Implement other kind of constrtaints
+  /// \todo Implement other kind of constraints
 
   return getType();
 }
+
+
+// ================= Auxiliary functions ==============================
+AttrType typeOfAttribute(boost::shared_ptr<ModelAPI_Attribute> theAttribute)
+{
+  boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttrRef =
+    boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+  if (!anAttrRef) return UNKNOWN;
+
+  if (anAttrRef->isObject())
+  {
+    ResultConstructionPtr aRC = 
+      boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(anAttrRef->object());
+    if (!aRC) return UNKNOWN;
+
+    if (aRC->shape()->isVertex())
+      return POINT3D;
+    else if (aRC->shape()->isEdge())
+    {
+      boost::shared_ptr<GeomAPI_Edge> anEdge = 
+        boost::dynamic_pointer_cast<GeomAPI_Edge>(aRC->shape());
+      if (anEdge->isLine())
+        return LINE;
+      else if (anEdge->isCircle())
+        return CIRCLE;
+      else if (anEdge->isArc())
+        return ARC;
+    }
+  }
+  else
+  {
+    const std::string aType = anAttrRef->attr()->attributeType();
+    if (aType == GeomDataAPI_Point2D::type())
+      return POINT2D;
+    if (aType == GeomDataAPI_Point2D::type())
+      return POINT2D;
+  }
+
+  return UNKNOWN;
+}
+
index 7a06355f46a8675171b9cfe72d6652bf602b2cb4..2640da058de85bb23f55476aec8b0eaaf48f44f6 100644 (file)
@@ -13,7 +13,9 @@
 #include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_Document.h>
 #include <ModelAPI_Events.h>
+#include <ModelAPI_ResultConstruction.h>
 
 #include <SketchPlugin_Constraint.h>
 #include <SketchPlugin_ConstraintLength.h>
@@ -137,10 +139,16 @@ bool SketchSolver_ConstraintGroup::isInteract(
     if (!aCAttrRef->isObject() && 
         myEntityAttrMap.find(aCAttrRef->attr()) != myEntityAttrMap.end())
       return true;
-    if (aCAttrRef->isObject() && 
-        myEntityFeatMap.find(boost::dynamic_pointer_cast<ModelAPI_Feature>(aCAttrRef->object())) 
-        != myEntityFeatMap.end())
-      return true;
+    if (aCAttrRef->isObject())
+    { // Obtain a base feature for the object
+      ResultConstructionPtr aRC = 
+        boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aCAttrRef->object());
+      if (!aRC) continue;
+      boost::shared_ptr<ModelAPI_Document> aDoc = aRC->document();
+      FeaturePtr aFeature = aDoc->feature(aRC);
+      if (myEntityFeatMap.find(aFeature) != myEntityFeatMap.end())
+        return true;
+    }
   }
 
   // Entities did not found
@@ -204,18 +212,29 @@ bool SketchSolver_ConstraintGroup::changeConstraint(
       );
     if (!aConstrAttr) continue;
 
+    // Convert the object of the attribute to the feature
+    FeaturePtr aFeature;
+    if (aConstrAttr->isObject() && aConstrAttr->object())
+    {
+      ResultConstructionPtr aRC = 
+        boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aConstrAttr->object());
+      if (!aRC) continue;
+      boost::shared_ptr<ModelAPI_Document> aDoc = aRC->document();
+      aFeature = aDoc->feature(aRC);
+    }
+
     // For the length constraint the start and end points of the line should be added to the entities list instead of line
     if (aConstrType == SLVS_C_PT_PT_DISTANCE && theConstraint->getKind().compare(SketchPlugin_ConstraintLength::ID()) == 0)
     {
-      boost::shared_ptr<ModelAPI_Data> aData = aConstrAttr->object()->data();
+      boost::shared_ptr<ModelAPI_Data> aData = aFeature->data();
       aConstrEnt[indAttr]   = changeEntity(aData->attribute(SketchPlugin_Line::START_ID()));
       aConstrEnt[indAttr+1] = changeEntity(aData->attribute(SketchPlugin_Line::END_ID()));
-       // measured object is added into the map of objects to avoid problems with interaction betwee constraint and group
-      myEntityFeatMap[boost::dynamic_pointer_cast<ModelAPI_Feature>(aConstrAttr->object())] = 0;
+      // measured object is added into the map of objects to avoid problems with interaction between constraint and group
+      myEntityFeatMap[aFeature] = 0;
       break; // there should be no other entities
     }
     else if (aConstrAttr->isObject())
-      aConstrEnt[indAttr] = changeEntity(boost::dynamic_pointer_cast<ModelAPI_Feature>(aConstrAttr->object()));
+      aConstrEnt[indAttr] = changeEntity(aFeature);
     else
       aConstrEnt[indAttr] = changeEntity(aConstrAttr->attr());
   }
@@ -227,9 +246,7 @@ bool SketchSolver_ConstraintGroup::changeConstraint(
     if (aConstrType == SLVS_C_POINTS_COINCIDENT)
     {
       if (aConstrEnt[0] == aConstrEnt[1]) // no need to add self coincidence
-      {
         return false;
-      }
       if (!addCoincidentPoints(aConstrEnt[0], aConstrEnt[1]))
       {
         myExtraCoincidence.insert(theConstraint); // the constraint is stored for further purposes