Salome HOME
Issue #2024: Redesign of circle and arc of circle
[modules/shaper.git] / src / PartSet / PartSet_Tools.cpp
index 27921bf5e60b2a5dcac162d4259caacdf234a315..37cee3d6771e9b9e6eea108280de8353a0fd1a13 100755 (executable)
@@ -15,6 +15,9 @@
 #include <ModelAPI_Session.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_Events.h>
+#include <ModelAPI_Validator.h>
+
+#include <ModelGeomAlgo_Point2D.h>
 
 #include <Events_Loop.h>
 
@@ -53,6 +56,7 @@
 
 #include <ModuleBase_IWorkshop.h>
 #include <ModuleBase_ViewerPrs.h>
+#include <ModuleBase_Tools.h>
 
 #include <V3d_View.hxx>
 #include <gp_Pln.hxx>
 #endif
 
 const double PRECISION_TOLERANCE = 0.000001;
+const int AIS_DEFAULT_WIDTH = 2;
+
+int PartSet_Tools::getAISDefaultWidth()
+{
+  return AIS_DEFAULT_WIDTH;
+}
 
 gp_Pnt PartSet_Tools::convertClickToPoint(QPoint thePoint, Handle(V3d_View) theView)
 {
@@ -148,7 +158,7 @@ Handle(V3d_View) theView,
   theY = aVec.X() * anY->x() + aVec.Y() * anY->y() + aVec.Z() * anY->z();
 }
 
-std::shared_ptr<GeomAPI_Pnt2d> PartSet_Tools::convertTo2D(FeaturePtr theSketch, 
+std::shared_ptr<GeomAPI_Pnt2d> PartSet_Tools::convertTo2D(FeaturePtr theSketch,
                                                     const std::shared_ptr<GeomAPI_Pnt>& thePnt)
 {
   std::shared_ptr<GeomAPI_Pnt2d> aRes;
@@ -165,7 +175,8 @@ std::shared_ptr<GeomAPI_Pnt2d> PartSet_Tools::convertTo2D(FeaturePtr theSketch,
 }
 
 
-std::shared_ptr<GeomAPI_Pnt> PartSet_Tools::convertTo3D(const double theX, const double theY, FeaturePtr theSketch)
+std::shared_ptr<GeomAPI_Pnt> PartSet_Tools::convertTo3D(const double theX, const double theY,
+                                                        FeaturePtr theSketch)
 {
   std::shared_ptr<ModelAPI_Data> aData = theSketch->data();
 
@@ -177,7 +188,7 @@ std::shared_ptr<GeomAPI_Pnt> PartSet_Tools::convertTo3D(const double theX, const
       aData->attribute(SketchPlugin_Sketch::NORM_ID()));
   std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
 
-  std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = 
+  std::shared_ptr<GeomAPI_Pnt2d> aPnt2d =
     std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(theX, theY));
 
   return aPnt2d->to3D(aC->pnt(), aX->dir(), aY);
@@ -262,151 +273,19 @@ void PartSet_Tools::createConstraint(CompositeFeaturePtr theSketch,
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
 }
 
-/*std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::
-  findAttributePoint(CompositeFeaturePtr theSketch, double theX, double theY,
-  double theTolerance, const QList<FeaturePtr>& theIgnore)
-{
-  std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = std::shared_ptr<GeomAPI_Pnt2d>(
-      new GeomAPI_Pnt2d(theX, theY));
-
-  std::list<std::shared_ptr<ModelAPI_Attribute> > anAttiributes;
-  for (int i = 0; i < theSketch->numberOfSubs(); i++) {
-    FeaturePtr aFeature = theSketch->subFeature(i);
-    if (!theIgnore.contains(aFeature)) {
-      anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
-
-      std::list<std::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt;
-      for (anIt = anAttiributes.cbegin(); anIt != anAttiributes.cend(); ++anIt) {
-        std::shared_ptr<GeomDataAPI_Point2D> aCurPoint = 
-          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
-        double x = aCurPoint->x();
-        double y = aCurPoint->y();
-        if (aCurPoint && (aCurPoint->pnt()->distance(aClickedPoint) < theTolerance)) {
-          return aCurPoint;
-        }
-      }
-    }
-  }
-  return std::shared_ptr<GeomDataAPI_Point2D>();
-}*/
-
-
-std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::findFirstEqualPointInArgumentFeatures(
-                  const FeaturePtr& theFeature, const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
-{
-  std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
-
-  // may be feature is not updated yet, execute is not performed and references features
-  // are not created. Case: rectangle macro feature
-  ModuleBase_ModelWidget::updateObject(theFeature);
-
-  std::list<AttributePtr> anAttributes = theFeature->data()->attributes(
-                                          ModelAPI_AttributeRefList::typeId());
-  std::list<AttributePtr>::const_iterator anIt = anAttributes.begin(), aLast = anAttributes.end();
-  for (; anIt != aLast && !aFeaturePoint.get(); anIt++) {
-    std::shared_ptr<ModelAPI_AttributeRefList> aCurSelList =
-                                      std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anIt);
-    for (int i = 0, aNb = aCurSelList->size(); i < aNb && !aFeaturePoint.get(); i++) {
-      ObjectPtr anObject = aCurSelList->object(i);
-      FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
-      if (aFeature.get())
-        aFeaturePoint = PartSet_Tools::findFirstEqualPoint(aFeature, thePoint);
-    }
-  }
-  return aFeaturePoint;
-}
-
-std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::findFirstEqualPoint(const FeaturePtr& theFeature,
-                                                      const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
-{
-  std::shared_ptr<GeomDataAPI_Point2D> aFPoint;
-
-  // find the given point in the feature attributes
-  std::list<std::shared_ptr<ModelAPI_Attribute> > anAttiributes =
-                                    theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
-  std::list<std::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
-      aLast = anAttiributes.end();
-  for (; anIt != aLast && !aFPoint; anIt++) {
-    std::shared_ptr<GeomDataAPI_Point2D> aCurPoint = 
-      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
-    if (aCurPoint && (aCurPoint->pnt()->distance(thePoint) < Precision::Confusion())) {
-      aFPoint = aCurPoint;
-      break;
-    }
-  }
-  return aFPoint;
-}
-
-void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature,
-                                   const std::string& theAttribute, double theClickedX,
-                                   double theClickedY)
-{
-  if (!theFeature.get())
-    return;
-
-  std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = std::shared_ptr<GeomAPI_Pnt2d>(
-      new GeomAPI_Pnt2d(theClickedX, theClickedY));
-
-  // find a feature point by the selection mode
-  std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
-  if (theFeature->isMacro()) {
-    // the macro feature will be removed after the operation is stopped, so we need to build
-    // coicidence to possible sub-features
-    aFeaturePoint = PartSet_Tools::findFirstEqualPointInArgumentFeatures(theFeature, aClickedPoint);
-  }
-  else {
-    aFeaturePoint = std::dynamic_pointer_cast<
-        GeomDataAPI_Point2D>(theFeature->data()->attribute(theAttribute));
-  }
-  if (!aFeaturePoint)
-    return;
-
-  // get all sketch features. If the point with the given coordinates belong to any sketch feature,
-  // the constraint is created between the feature point and the found sketch point
-  std::shared_ptr<ModelAPI_Data> aData = theSketch->data();
-  std::shared_ptr<ModelAPI_AttributeRefList> aRefList = std::dynamic_pointer_cast<
-      ModelAPI_AttributeRefList>(aData->attribute(SketchPlugin_Sketch::FEATURES_ID()));
-
-  std::list<ObjectPtr> aFeatures = aRefList->list();
-  std::list<ObjectPtr>::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end();
-  std::list<std::shared_ptr<ModelAPI_Attribute> > anAttiributes;
-  for (; anIt != aLast; anIt++) {
-    FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
-    if (!aFeature.get() || theFeature == aFeature)
-      continue;
-    std::shared_ptr<GeomDataAPI_Point2D> aFPoint = PartSet_Tools::findFirstEqualPoint(aFeature,
-                                                                                aClickedPoint);
-    if (aFPoint)
-      PartSet_Tools::createConstraint(theSketch, aFPoint, aFeaturePoint);
-  }
-}
-
 std::shared_ptr<GeomAPI_Pln> PartSet_Tools::sketchPlane(CompositeFeaturePtr theSketch)
 {
   std::shared_ptr<GeomAPI_Pln> aPlane;
 
-  std::shared_ptr<ModelAPI_Data> aData = theSketch->data();
-  if (aData) {
-    std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
-        aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
-    std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-        aData->attribute(SketchPlugin_Sketch::NORM_ID()));
-    if (aNormal && anOrigin) {
-      double adX = aNormal->x();
-      double adY = aNormal->y();
-      double adZ = aNormal->z();
-
-      if ( (adX != 0) || (adY != 0) || (adZ != 0) ) { // Plane is valid
-        double aX = anOrigin->x();
-        double aY = anOrigin->y();
-        double aZ = anOrigin->z();
-        gp_Pln aPln(gp_Pnt(aX, aY, aZ), gp_Dir(adX, adY, adZ));
-        double aA, aB, aC, aD;
-        aPln.Coefficients(aA, aB, aC, aD);
-        aPlane = std::shared_ptr<GeomAPI_Pln>(new GeomAPI_Pln(aA, aB, aC, aD));
-      }
-    }
-  }
+  std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+      theSketch->data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
+  std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+      theSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
+
+  if (aNormal.get() && aNormal->isInitialized() &&
+      anOrigin.get() && anOrigin->isInitialized())
+    aPlane = std::shared_ptr<GeomAPI_Pln>(new GeomAPI_Pln(anOrigin->pnt(), aNormal->dir()));
+
   return aPlane;
 }
 
@@ -448,8 +327,8 @@ ResultPtr PartSet_Tools::findFixedObjectByExternal(const TopoDS_Shape& theShape,
   return aResult;
 }
 
-ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShape, 
-                                                     const ObjectPtr& theObject, 
+ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShape,
+                                                     const ObjectPtr& theObject,
                                                      CompositeFeaturePtr theSketch,
                                                      const bool theTemporary)
 {
@@ -473,10 +352,12 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
         std::shared_ptr<GeomAPI_Pnt2d> aPnt2d2 = convertTo2D(theSketch, aPnt2);
 
         std::shared_ptr<ModelAPI_Data> aData = aMyFeature->data();
-        std::shared_ptr<GeomDataAPI_Point2D> aPoint1 = 
-          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Line::START_ID()));
-        std::shared_ptr<GeomDataAPI_Point2D> aPoint2 = 
-          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Line::END_ID()));
+        std::shared_ptr<GeomDataAPI_Point2D> aPoint1 =
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+          aData->attribute(SketchPlugin_Line::START_ID()));
+        std::shared_ptr<GeomDataAPI_Point2D> aPoint2 =
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+          aData->attribute(SketchPlugin_Line::END_ID()));
 
         aPoint1->setValue(aPnt2d1);
         aPoint2->setValue(aPnt2d2);
@@ -501,6 +382,8 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
       if (anEdge->isArc()) {
         // Create arc
         aMyFeature = theSketch->addFeature(SketchPlugin_Arc::ID());
+        if (theShape.Orientation() == TopAbs_REVERSED)
+          aMyFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(true);
       }
       else {
         // Create circle
@@ -509,11 +392,21 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
     }
     if (aMyFeature) {
       DataPtr aData = aMyFeature->data();
-      AttributeSelectionPtr anAttr = 
+      AttributeSelectionPtr anAttr =
         std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
         (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
 
       ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+      // selection shape has no result owner => the trihedron axis
+      // TODO: make reference to the real axes when
+      // they are implemented in the initialization plugin
+      if (!aRes.get()) {
+        ObjectPtr aPointObj = ModelAPI_Session::get()->moduleDocument()->objectByName(
+          ModelAPI_ResultConstruction::group(), "Origin");
+        if (aPointObj.get()) { // if initialization plugin performed well
+          aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aPointObj);
+        }
+      }
       if (!aRes.get()) {
         aRes = aMyFeature->firstResult();
       }
@@ -525,10 +418,12 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
         //if (!theTemporary) {
           aMyFeature->execute();
 
-          // fix this edge
-          FeaturePtr aFix = theSketch->addFeature(SketchPlugin_ConstraintRigid::ID());
-          aFix->data()->refattr(SketchPlugin_Constraint::ENTITY_A())->
-            setObject(aMyFeature->lastResult());
+        //  // fix this edge
+        //  FeaturePtr aFix = theSketch->addFeature(SketchPlugin_ConstraintRigid::ID());
+        //  aFix->data()->refattr(SketchPlugin_Constraint::ENTITY_A())->
+        //    setObject(aMyFeature->lastResult());
+        //  // we need to flush created signal in order to fixed constraint is processed by solver
+        //  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
         //}
         return aMyFeature->lastResult();
       }
@@ -539,26 +434,37 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
 
     if (aMyFeature) {
       DataPtr aData = aMyFeature->data();
-      AttributeSelectionPtr anAttr = 
+      AttributeSelectionPtr anAttr =
         std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
         (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
 
       ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+      // if there is no object,
+      // it means that this is the origin point: search it in the module document
+      if (!aRes.get()) {
+        ObjectPtr aPointObj = ModelAPI_Session::get()->moduleDocument()->objectByName(
+          ModelAPI_ResultConstruction::group(), "Origin");
+        if (aPointObj.get()) { // if initialization plugin performed well
+          aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aPointObj);
+        }
+      }
+      // reference to itself with name "Origin" (but this may cause the infinitive cycling)
       if (!aRes.get()) {
         // If the point is selected not from Result object
-        std::shared_ptr<GeomAPI_Shape> aShape = 
+        std::shared_ptr<GeomAPI_Shape> aShape =
           std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
         aShape->setImpl(new TopoDS_Shape(theShape));
 
-        std::shared_ptr<GeomAPI_Vertex> aVertex = 
+        std::shared_ptr<GeomAPI_Vertex> aVertex =
           std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(aShape));
         std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
 
         std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = convertTo2D(theSketch, aPnt);
-        std::shared_ptr<GeomDataAPI_Point2D> aPoint = 
-          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Point::COORD_ID()));
+        std::shared_ptr<GeomDataAPI_Point2D> aPoint =
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+          aData->attribute(SketchPlugin_Point::COORD_ID()));
         aPoint->setValue(aPnt2d);
-        if ((aPnt->x() < Precision::Confusion()) && 
+        if ((aPnt->x() < Precision::Confusion()) &&
             (aPnt->y() < Precision::Confusion()) &&
             (aPnt->z() < Precision::Confusion()))
           aData->setName("Origin");
@@ -574,10 +480,12 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
         //if (theTemporary) {
           aMyFeature->execute();
 
-          // fix this edge
-          FeaturePtr aFix = theSketch->addFeature(SketchPlugin_ConstraintRigid::ID());
-          aFix->data()->refattr(SketchPlugin_Constraint::ENTITY_A())->
-            setObject(aMyFeature->lastResult());
+        //  // fix this edge
+        //  FeaturePtr aFix = theSketch->addFeature(SketchPlugin_ConstraintRigid::ID());
+        //  aFix->data()->refattr(SketchPlugin_Constraint::ENTITY_A())->
+        //    setObject(aMyFeature->lastResult());
+        //  // we need to flush created signal in order to fixed constraint is processed by solver
+        //  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
         //}
         return aMyFeature->lastResult();
       }
@@ -586,28 +494,30 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
   return ResultPtr();
 }
 
-bool PartSet_Tools::isContainPresentation(const QList<ModuleBase_ViewerPrs>& theSelected,
-                                          const ModuleBase_ViewerPrs& thePrs)
+bool PartSet_Tools::isContainPresentation(const QList<ModuleBase_ViewerPrsPtr>& theSelected,
+                                          const ModuleBase_ViewerPrsPtr& thePrs)
 {
-  foreach (ModuleBase_ViewerPrs aPrs, theSelected) {
-    if (aPrs.object() == thePrs.object())
+  foreach (ModuleBase_ViewerPrsPtr aPrs, theSelected) {
+    if (aPrs->object() == thePrs->object())
       return true;
   }
   return false;
 }
 
-ResultPtr PartSet_Tools::findExternalEdge(CompositeFeaturePtr theSketch, std::shared_ptr<GeomAPI_Edge> theEdge)
+ResultPtr PartSet_Tools::findExternalEdge(CompositeFeaturePtr theSketch,
+                                          std::shared_ptr<GeomAPI_Edge> theEdge)
 {
   for (int i = 0; i < theSketch->numberOfSubs(); i++) {
     FeaturePtr aFeature = theSketch->subFeature(i);
-    std::shared_ptr<SketchPlugin_Feature> aSketchFea = 
+    std::shared_ptr<SketchPlugin_Feature> aSketchFea =
       std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
-    if (aSketchFea) {
+    // not displayed result of feature projection should not be returned as external edge
+    if (aSketchFea && aSketchFea->canBeDisplayed()) {
       if (aSketchFea->isExternal()) {
         std::list<ResultPtr> aResults = aSketchFea->results();
         std::list<ResultPtr>::const_iterator aIt;
         for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
-          ResultConstructionPtr aRes = 
+          ResultConstructionPtr aRes =
             std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aIt);
           if (aRes) {
             std::shared_ptr<GeomAPI_Shape> aShape = aRes->shape();
@@ -624,18 +534,19 @@ ResultPtr PartSet_Tools::findExternalEdge(CompositeFeaturePtr theSketch, std::sh
 }
 
 
-ResultPtr PartSet_Tools::findExternalVertex(CompositeFeaturePtr theSketch, std::shared_ptr<GeomAPI_Vertex> theVert)
+ResultPtr PartSet_Tools::findExternalVertex(CompositeFeaturePtr theSketch,
+                                            std::shared_ptr<GeomAPI_Vertex> theVert)
 {
   for (int i = 0; i < theSketch->numberOfSubs(); i++) {
     FeaturePtr aFeature = theSketch->subFeature(i);
-    std::shared_ptr<SketchPlugin_Feature> aSketchFea = 
+    std::shared_ptr<SketchPlugin_Feature> aSketchFea =
       std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
     if (aSketchFea) {
       if (aSketchFea->isExternal()) {
         std::list<ResultPtr> aResults = aSketchFea->results();
         std::list<ResultPtr>::const_iterator aIt;
         for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
-          ResultConstructionPtr aRes = 
+          ResultConstructionPtr aRes =
             std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aIt);
           if (aRes) {
             std::shared_ptr<GeomAPI_Shape> aShape = aRes->shape();
@@ -652,15 +563,16 @@ ResultPtr PartSet_Tools::findExternalVertex(CompositeFeaturePtr theSketch, std::
 }
 
 
-bool PartSet_Tools::hasVertexShape(const ModuleBase_ViewerPrs& thePrs, FeaturePtr theSketch,
-                                   Handle_V3d_View theView, double& theX, double& theY)
+bool PartSet_Tools::hasVertexShape(const ModuleBase_ViewerPrsPtr& thePrs, FeaturePtr theSketch,
+                                   Handle(V3d_View) theView, double& theX, double& theY)
 {
   bool aHasVertex = false;
 
-  const TopoDS_Shape& aShape = thePrs.shape();
-  if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX)
+  const GeomShapePtr& aShape = thePrs->shape();
+  if (aShape.get() && !aShape->isNull() && aShape->shapeType() == GeomAPI_Shape::VERTEX)
   {
-    const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
+    const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
+    const TopoDS_Vertex& aVertex = TopoDS::Vertex(aTDShape);
     if (!aVertex.IsNull())
     {
       gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
@@ -719,35 +631,20 @@ GeomShapePtr PartSet_Tools::findShapeBy2DPoint(const AttributePtr& theAttribute,
   return aShape;
 }
 
-std::shared_ptr<GeomAPI_Pnt2d> PartSet_Tools::getPoint(std::shared_ptr<ModelAPI_Feature>& theFeature,
-                                                       const std::string& theAttribute)
+std::shared_ptr<GeomAPI_Pnt2d> PartSet_Tools::getPoint(
+                                                  std::shared_ptr<ModelAPI_Feature>& theFeature,
+                                                  const std::string& theAttribute)
 {
-  std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
-
-  if (!theFeature->data())
-    return std::shared_ptr<GeomAPI_Pnt2d>();
-
-  FeaturePtr aFeature;
-  std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
-      ModelAPI_AttributeRefAttr>(theFeature->data()->attribute(theAttribute));
-  if (!anAttr)
-    return std::shared_ptr<GeomAPI_Pnt2d>();
-
-  aFeature = ModelAPI_Feature::feature(anAttr->object());
-
-  if (aFeature && aFeature->getKind() == SketchPlugin_Point::ID())
-    aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-        aFeature->data()->attribute(SketchPlugin_Point::COORD_ID()));
-
-  else if (anAttr->attr()) {
-    aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
-  }
+  std::shared_ptr<GeomDataAPI_Point2D> aPointAttr = ModelGeomAlgo_Point2D::getPointOfRefAttr(
+                                          theFeature.get(), theAttribute, SketchPlugin_Point::ID(),
+                                          SketchPlugin_Point::COORD_ID());
   if (aPointAttr.get() != NULL)
     return aPointAttr->pnt();
   return std::shared_ptr<GeomAPI_Pnt2d>();
 }
 
-FeaturePtr findFirstCoincidenceByData(const DataPtr& theData, std::shared_ptr<GeomAPI_Pnt2d> thePoint)
+FeaturePtr findFirstCoincidenceByData(const DataPtr& theData,
+                                      std::shared_ptr<GeomAPI_Pnt2d> thePoint)
 {
   FeaturePtr aCoincident;
 
@@ -756,16 +653,16 @@ FeaturePtr findFirstCoincidenceByData(const DataPtr& theData, std::shared_ptr<Ge
   for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
     std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
     FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
-    if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { 
-      std::shared_ptr<GeomAPI_Pnt2d> a2dPnt = 
+    if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+      std::shared_ptr<GeomAPI_Pnt2d> a2dPnt =
         PartSet_Tools::getPoint(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A());
-      if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { 
+      if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) {
         aCoincident = aConstrFeature;
         break;
       } else {
         a2dPnt = PartSet_Tools::getPoint(aConstrFeature,
                                           SketchPlugin_ConstraintCoincidence::ENTITY_B());
-        if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { 
+        if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) {
           aCoincident = aConstrFeature;
           break;
         }
@@ -776,8 +673,7 @@ FeaturePtr findFirstCoincidenceByData(const DataPtr& theData, std::shared_ptr<Ge
 }
 
 FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature,
-                                               std::shared_ptr<GeomAPI_Pnt2d> thePoint,
-                                               const bool theSearchInResults)
+                                               std::shared_ptr<GeomAPI_Pnt2d> thePoint)
 {
   FeaturePtr aCoincident;
   if (theFeature.get() == NULL)
@@ -788,58 +684,95 @@ FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature,
   for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
     std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
     FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
-    if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { 
-      std::shared_ptr<GeomAPI_Pnt2d> a2dPnt = 
+    if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+      std::shared_ptr<GeomAPI_Pnt2d> a2dPnt =
         PartSet_Tools::getPoint(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A());
-      if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { 
+      if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) {
         aCoincident = aConstrFeature;
         break;
       } else {
         a2dPnt = PartSet_Tools::getPoint(aConstrFeature,
                                           SketchPlugin_ConstraintCoincidence::ENTITY_B());
-        if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { 
+        if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) {
           aCoincident = aConstrFeature;
           break;
         }
       }
     }
   }
-  if (theSearchInResults) {
-    if (!aCoincident.get()) {
-      std::list<ResultPtr> aResults = theFeature->results();
-      std::list<ResultPtr>::const_iterator aIt;
-      for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
-        ResultPtr aResult = *aIt;
-        aCoincident = findFirstCoincidenceByData(aResult->data(), thePoint);
-        if (aCoincident.get())
-          break;
-      }
+  /// Find by result
+  if (!aCoincident.get()) {
+    std::list<ResultPtr> aResults = theFeature->results();
+    std::list<ResultPtr>::const_iterator aIt;
+    for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) {
+      ResultPtr aResult = *aIt;
+      aCoincident = findFirstCoincidenceByData(aResult->data(), thePoint);
+      if (aCoincident.get())
+        break;
     }
   }
   return aCoincident;
 }
 
 void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList<FeaturePtr>& theList,
+                                     QList<FeaturePtr>& theCoincidencies,
                                      std::string theAttr)
 {
+  std::shared_ptr<GeomAPI_Pnt2d> aOrig = getCoincedencePoint(theStartCoin);
+  if (aOrig.get() == NULL)
+    return;
+
   AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr);
-  if (!aPnt) return;
-  FeaturePtr aObj = ModelAPI_Feature::feature(aPnt->object());
-  if (!theList.contains(aObj)) {
-    std::shared_ptr<GeomAPI_Pnt2d> aOrig = getCoincedencePoint(theStartCoin);
-    if (aOrig.get() == NULL)
-      return;
-    theList.append(aObj);
-    const std::set<AttributePtr>& aRefsList = aObj->data()->refsToMe();
-    std::set<AttributePtr>::const_iterator aIt;
-    for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
-      std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
-      FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
-      if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { 
-        std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincedencePoint(aConstrFeature);
-        if (aPnt.get() && aOrig->isEqual(aPnt)) {
-          findCoincidences(aConstrFeature, theList, SketchPlugin_ConstraintCoincidence::ENTITY_A());
-          findCoincidences(aConstrFeature, theList, SketchPlugin_ConstraintCoincidence::ENTITY_B());
+  if (!aPnt)
+    return;
+  ObjectPtr aObj = aPnt->object();
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
+  if (aFeature.get()) {
+    if (!theList.contains(aFeature)) {
+      theList.append(aFeature);
+      theCoincidencies.append(theStartCoin);
+      const std::set<AttributePtr>& aRefsList = aFeature->data()->refsToMe();
+      std::set<AttributePtr>::const_iterator aIt;
+      for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+        std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
+        FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
+        if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+          if (!theCoincidencies.contains(aConstrFeature)) {
+            std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincedencePoint(aConstrFeature);
+            if (aPnt.get() && aOrig->isEqual(aPnt)) {
+              findCoincidences(aConstrFeature, theList, theCoincidencies,
+                SketchPlugin_ConstraintCoincidence::ENTITY_A());
+              findCoincidences(aConstrFeature, theList, theCoincidencies,
+                SketchPlugin_ConstraintCoincidence::ENTITY_B());
+            }
+          }
+        }
+      }
+    }
+  } else {
+    // Find by Results
+    ResultConstructionPtr aResult = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aObj);
+    if (aResult.get()) {
+      FeaturePtr aFeature = ModelAPI_Feature::feature(aPnt->object());
+      if (!theList.contains(aFeature))
+        theList.append(aFeature);
+      theCoincidencies.append(theStartCoin);
+
+      const std::set<AttributePtr>& aRefsList = aResult->data()->refsToMe();
+      std::set<AttributePtr>::const_iterator aIt;
+      for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+        std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
+        FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
+        if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+          if (!theCoincidencies.contains(aConstrFeature)) {
+            std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincedencePoint(aConstrFeature);
+            if (aPnt.get() && aOrig->isEqual(aPnt)) {
+              findCoincidences(aConstrFeature, theList, theCoincidencies,
+                SketchPlugin_ConstraintCoincidence::ENTITY_A());
+              findCoincidences(aConstrFeature, theList, theCoincidencies,
+                SketchPlugin_ConstraintCoincidence::ENTITY_B());
+            }
+          }
         }
       }
     }
@@ -848,15 +781,15 @@ void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList<FeaturePtr>&
 
 std::shared_ptr<GeomAPI_Pnt2d> PartSet_Tools::getCoincedencePoint(FeaturePtr theStartCoin)
 {
-  std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), 
-                                                                    SketchPlugin_Constraint::ENTITY_A());
+  std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(),
+                                                        SketchPlugin_Constraint::ENTITY_A());
   if (aPnt.get() == NULL)
     aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), SketchPlugin_Constraint::ENTITY_B());
   return aPnt;
 }
 
-AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj, 
-                                                   const TopoDS_Shape theShape, 
+AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj,
+                                                   const TopoDS_Shape theShape,
                                                    FeaturePtr theSketch)
 {
 
@@ -871,15 +804,18 @@ AttributePtr PartSet_Tools::findAttributeBy2dPoint(ObjectPtr theObj,
             new GeomAPI_Pnt(aPoint.X(), aPoint.Y(), aPoint.Z()));
 
         // find the given point in the feature attributes
-        std::list<AttributePtr> anAttiributes = 
+        std::list<AttributePtr> anAttiributes =
           aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
-        std::list<AttributePtr>::const_iterator anIt = anAttiributes.begin(), 
+        std::list<AttributePtr>::const_iterator anIt = anAttiributes.begin(),
                                                 aLast = anAttiributes.end();
         for (; anIt != aLast && !anAttribute; anIt++) {
-          std::shared_ptr<GeomDataAPI_Point2D> aCurPoint = 
+          std::shared_ptr<GeomDataAPI_Point2D> aCurPoint =
             std::dynamic_pointer_cast<GeomDataAPI_Point2D>(*anIt);
+          if (!aCurPoint->isInitialized())
+            continue;
 
-          std::shared_ptr<GeomAPI_Pnt> aPnt = convertTo3D(aCurPoint->x(), aCurPoint->y(), theSketch);
+          std::shared_ptr<GeomAPI_Pnt> aPnt =
+            convertTo3D(aCurPoint->x(), aCurPoint->y(), theSketch);
           if (aPnt && (aPnt->distance(aValue) < Precision::Confusion())) {
             anAttribute = aCurPoint;
             break;
@@ -905,3 +841,18 @@ void PartSet_Tools::sendSubFeaturesEvent(const CompositeFeaturePtr& theComposite
   }
   Events_Loop::loop()->flush(theEventId);
 }
+
+bool PartSet_Tools::isAuxiliarySketchEntity(const ObjectPtr& theObject)
+{
+  bool isAuxiliaryFeature = false;
+
+  FeaturePtr anObjectFeature = ModelAPI_Feature::feature(theObject);
+  std::string anAuxiliaryAttribute = SketchPlugin_SketchEntity::AUXILIARY_ID();
+  AttributeBooleanPtr anAuxiliaryAttr = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+                                    anObjectFeature->data()->attribute(anAuxiliaryAttribute));
+  if (anAuxiliaryAttr.get())
+    isAuxiliaryFeature = anAuxiliaryAttr->value();
+
+
+  return isAuxiliaryFeature;
+}