]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #2027 Sketcher Trim Feature: split shapes by highlighted point is moved from...
authornds <nds@opencascade.com>
Thu, 9 Mar 2017 05:05:34 +0000 (08:05 +0300)
committernds <nds@opencascade.com>
Thu, 9 Mar 2017 05:05:34 +0000 (08:05 +0300)
Trim Circle feature.

15 files changed:
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.cpp
src/GeomAlgoAPI/GeomAlgoAPI_ShapeTools.h
src/ModelGeomAlgo/ModelGeomAlgo_Point2D.cpp
src/ModelGeomAlgo/ModelGeomAlgo_Point2D.h
src/PartSet/PartSet_WidgetFeaturePointSelector.cpp
src/PartSet/PartSet_WidgetSubShapeSelector.cpp
src/SketchAPI/SketchAPI_Sketch.cpp
src/SketchAPI/SketchAPI_Sketch.h
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_ConstraintSplit.cpp
src/SketchPlugin/SketchPlugin_Trim.cpp
src/SketchPlugin/SketchPlugin_Trim.h
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/Test/TestTrimCircle.py [new file with mode: 0644]
src/SketchPlugin/plugin-Sketch.xml

index 14b2fbc41c43dc17a6498515e2b400977a3bb43d..7f7c8765ecc9cc3e5d552b99ac49a7f53fb6e7a0 100644 (file)
@@ -695,6 +695,53 @@ bool GeomAlgoAPI_ShapeTools::isParallel(const std::shared_ptr<GeomAPI_Edge> theE
 
 //==================================================================================================
 void GeomAlgoAPI_ShapeTools::splitShape(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
+                                      const GeomAlgoAPI_ShapeTools::PointToRefsMap& thePointsInfo,
+                                      std::set<std::shared_ptr<GeomAPI_Shape> >& theShapes)
+{
+  // General Fuse to split edge by vertices
+  BOPAlgo_Builder aBOP;
+  TopoDS_Edge aBaseEdge = theBaseShape->impl<TopoDS_Edge>();
+  // Rebuild closed edge to place vertex to one of split points.
+  // This will prevent edge to be split on same vertex.
+  if (BRep_Tool::IsClosed(aBaseEdge))
+  {
+    Standard_Real aFirst, aLast;
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aBaseEdge, aFirst, aLast);
+
+    PointToRefsMap::const_iterator aPIt = thePointsInfo.begin();
+    std::shared_ptr<GeomAPI_Pnt> aPnt = aPIt->first;
+    gp_Pnt aPoint(aPnt->x(), aPnt->y(), aPnt->z());
+
+    TopAbs_Orientation anOrientation = aBaseEdge.Orientation();
+    aBaseEdge = BRepBuilderAPI_MakeEdge(aCurve, aPoint, aPoint).Edge();
+    aBaseEdge.Orientation(anOrientation);
+  }
+  aBOP.AddArgument(aBaseEdge);
+
+  //std::list<std::shared_ptr<GeomAPI_Pnt> >::const_iterator aPtIt = thePoints.begin();
+  PointToRefsMap::const_iterator aPIt = thePointsInfo.begin();
+  for (; aPIt != thePointsInfo.end(); ++aPIt) {
+    std::shared_ptr<GeomAPI_Pnt> aPnt = aPIt->first;
+    TopoDS_Vertex aV = BRepBuilderAPI_MakeVertex(gp_Pnt(aPnt->x(), aPnt->y(), aPnt->z()));
+    aBOP.AddArgument(aV);
+  }
+
+  aBOP.Perform();
+  if (aBOP.ErrorStatus())
+    return;
+
+  // Collect splits
+  const TopTools_ListOfShape& aSplits = aBOP.Modified(aBaseEdge);
+  TopTools_ListIteratorOfListOfShape anIt(aSplits);
+  for (; anIt.More(); anIt.Next()) {
+    std::shared_ptr<GeomAPI_Shape> anEdge(new GeomAPI_Shape);
+    anEdge->setImpl(new TopoDS_Shape(anIt.Value()));
+    theShapes.insert(anEdge);
+  }
+}
+
+//==================================================================================================
+void GeomAlgoAPI_ShapeTools::splitShape_p(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
                                           const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
                                           std::set<std::shared_ptr<GeomAPI_Shape> >& theShapes)
 {
index 22c8867870bc64c40eb835092d90ecc918d406f4..d3b712585176a24a8e7316e42611d48153ebf8ba 100644 (file)
@@ -12,6 +12,7 @@
 #include <GeomAPI_Shape.h>
 #include <GeomAPI_Vertex.h>
 
+#include <map>
 #include <set>
 
 class GeomAPI_Edge;
@@ -20,6 +21,8 @@ class GeomAPI_Face;
 class GeomAPI_PlanarEdges;
 class GeomAPI_Pln;
 class GeomAPI_Pnt;
+class GeomDataAPI_Point2D;
+class ModelAPI_Object;
 
 /// \class GeomAlgoAPI_ShapeTools
 /// \ingroup DataAlgo
@@ -116,14 +119,24 @@ public:
   GEOMALGOAPI_EXPORT static bool isParallel(const std::shared_ptr<GeomAPI_Edge> theEdge,
                                             const std::shared_ptr<GeomAPI_Face> theFace);
 
+  typedef std::map<std::shared_ptr<GeomAPI_Pnt>,
+                   std::pair<std::list<std::shared_ptr<GeomDataAPI_Point2D> >,
+                             std::list<std::shared_ptr<ModelAPI_Object> > > > PointToRefsMap;
   /// \brief Performs the split of the shape by points.
   /// \param[in] theBaseShape shape that should be splitted.
   /// \param[in] thePoints container of points to split
   /// \param[out] theShapes container of shapes after split
   GEOMALGOAPI_EXPORT static void splitShape(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
-                                      const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
+                                      const PointToRefsMap& thePointsInfo,
                                       std::set<std::shared_ptr<GeomAPI_Shape> >& theShapes);
 
+  /// \brief Performs the split of the shape by points.
+  /// \param[in] theBaseShape shape that should be splitted.
+  /// \param[in] thePoints container of points to split
+  /// \param[out] theShapes container of shapes after split
+  GEOMALGOAPI_EXPORT static void splitShape_p(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
+                                      const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
+                                      std::set<std::shared_ptr<GeomAPI_Shape> >& theShapes);
 
   GEOMALGOAPI_EXPORT static std::shared_ptr<GeomAPI_Shape> findShape(
                                     const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
index 5d1a2cf74f373867200dae28ed1cdf882895bad9..e65a2786e312b2fc8f47d068cfe3f12fb5a207f3 100755 (executable)
@@ -125,23 +125,21 @@ namespace ModelGeomAlgo_Point2D {
 
   void appendPoint(const std::shared_ptr<GeomAPI_Pnt>& thePoint,
                    const std::shared_ptr<ModelAPI_Result>& theResult,
-                   std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
-                   std::map<std::shared_ptr<GeomAPI_Pnt>,
-                                std::list< std::shared_ptr<ModelAPI_Object> > >& theObjectToPoint)
+                   PointToRefsMap& thePointToAttributeOrObject)
   {
-    std::list< std::shared_ptr<ModelAPI_Object> > anObjects;
-    if (theObjectToPoint.find(thePoint) != theObjectToPoint.end())
-      anObjects = theObjectToPoint[thePoint];
-    thePoints.push_back(thePoint);
-    anObjects.push_back(theResult);
-    theObjectToPoint[thePoint].push_back(theResult);
+    if (thePointToAttributeOrObject.find(thePoint) != thePointToAttributeOrObject.end())
+      thePointToAttributeOrObject.at(thePoint).second.push_back(theResult);
+    else {
+      std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
+      std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
+      anObjects.push_back(theResult);
+      thePointToAttributeOrObject[thePoint] = std::make_pair(anAttributes, anObjects);
+    }
   }
 
   void appendShapePoints(GeomShapePtr& theShape,
                          const std::shared_ptr<ModelAPI_Result>& theResult,
-                         std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
-                         std::map<std::shared_ptr<GeomAPI_Pnt>,
-                              std::list< std::shared_ptr<ModelAPI_Object> > >& theObjectToPoint)
+                         PointToRefsMap& thePointToAttributeOrObject)
   {
     if (!theShape.get())
       return;
@@ -151,19 +149,19 @@ namespace ModelGeomAlgo_Point2D {
         std::shared_ptr<GeomAPI_Vertex> aVertex =
           std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(theShape));
         std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
-        appendPoint(aPnt, theResult, thePoints, theObjectToPoint);
+        appendPoint(aPnt, theResult, thePointToAttributeOrObject);
       }
       break;
       case GeomAPI_Shape::EDGE: {
         std::shared_ptr<GeomAPI_Edge> anEdge =
           std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge(theShape));
-        appendPoint(anEdge->firstPoint(), theResult, thePoints, theObjectToPoint);
-        appendPoint(anEdge->lastPoint(), theResult, thePoints, theObjectToPoint);
+        appendPoint(anEdge->firstPoint(), theResult, thePointToAttributeOrObject);
+        appendPoint(anEdge->lastPoint(), theResult, thePointToAttributeOrObject);
       }
       break;
       case GeomAPI_Shape::COMPOUND: {
         for(GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) {
-          appendShapePoints(anIt.current(), theResult, thePoints, theObjectToPoint);
+          appendShapePoints(anIt.current(), theResult, thePointToAttributeOrObject);
         }
       }
       break;
@@ -173,9 +171,7 @@ namespace ModelGeomAlgo_Point2D {
 
   void getPointsIntersectedShape(const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
                         const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
-                        std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
-                        std::map<std::shared_ptr<GeomAPI_Pnt>,
-                                std::list< std::shared_ptr<ModelAPI_Object> > >& theObjectToPoint)
+                        PointToRefsMap& thePointToAttributeOrObject)
   {
     GeomShapePtr aFeatureShape;
     {
@@ -201,12 +197,45 @@ namespace ModelGeomAlgo_Point2D {
         GeomShapePtr aShape = aResult->shape();
 
         GeomShapePtr aShapeOfIntersection = aFeatureShape->intersect(aShape);
-        appendShapePoints(aShapeOfIntersection, aResult, thePoints, theObjectToPoint);
+        appendShapePoints(aShapeOfIntersection, aResult, thePointToAttributeOrObject);
       }
     }
   }
 
   void getPointsInsideShape(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                        const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
+                        const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+                        const std::shared_ptr<GeomAPI_Dir>& theDirX,
+                        const std::shared_ptr<GeomAPI_Dir>& theDirY,
+                        PointToRefsMap& thePointToAttributeOrObject)
+  {
+    std::set<std::shared_ptr<GeomDataAPI_Point2D> >::const_iterator anIt = theAttributes.begin(),
+                                                            aLast = theAttributes.end();
+    for (; anIt != aLast; anIt++) {
+      std::shared_ptr<GeomDataAPI_Point2D> anAttribute = *anIt;
+      std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = anAttribute->pnt();
+      std::shared_ptr<GeomAPI_Pnt> aPoint = aPnt2d->to3D(theOrigin, theDirX, theDirY);
+      std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
+      if (isPointOnEdge(theBaseShape, aPoint, aProjectedPoint)) {
+        if (thePointToAttributeOrObject.find(aProjectedPoint) != thePointToAttributeOrObject.end())
+          thePointToAttributeOrObject.at(aProjectedPoint).first.push_back(anAttribute);
+        else {
+          //std::list< std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
+          //anAttributes.push_back(anAttribute);
+          //thePointToAttributeOrObject.insert(aProjectedPoint, anAttributes);
+
+          std::list<std::shared_ptr<GeomDataAPI_Point2D> > anAttributes;
+          std::list<std::shared_ptr<ModelAPI_Object> > anObjects;
+          anAttributes.push_back(anAttribute);
+          thePointToAttributeOrObject[aProjectedPoint] = std::make_pair(anAttributes, anObjects);
+        }
+        //thePoints.push_back(aProjectedPoint);
+        //theAttributeToPoint[anAttribute] = aProjectedPoint;
+      }
+    }
+  }
+
+  void getPointsInsideShape_p(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
                             const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
                             const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
                             const std::shared_ptr<GeomAPI_Dir>& theDirX,
index b5c005bd545218e35c466d272b2ad3dace549b71..6e717c10e623c41a3d0d6cd8f8732700f6272145 100755 (executable)
@@ -62,12 +62,14 @@ namespace ModelGeomAlgo_Point2D {
   /// \param theFeatures a container of features to intersect with the base feature
   /// \param thePoints a container of 3D points belong to the shape
   /// \param theObjectToPoint a container of object to point
+  typedef std::map<std::shared_ptr<GeomAPI_Pnt>,
+                   std::pair<std::list<std::shared_ptr<GeomDataAPI_Point2D> >,
+                             std::list<std::shared_ptr<ModelAPI_Object> > > > PointToRefsMap;
+
   MODELGEOMALGO_EXPORT void getPointsIntersectedShape(
                   const std::shared_ptr<ModelAPI_Feature>& theBaseFeature,
                   const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
-                  std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
-                  std::map<std::shared_ptr<GeomAPI_Pnt>,
-                            std::list< std::shared_ptr<ModelAPI_Object> > >& theObjectToPoint);
+                  PointToRefsMap& thePointToAttributeOrObject);
 
   /// Removes attributes which points are out of the base shape
   /// \param theBaseShape a shape of check
@@ -78,6 +80,22 @@ namespace ModelGeomAlgo_Point2D {
   /// \param thePoints a container of 3D points belong to the shape
   /// \param theAttributeToPoint a container of attribute to point
   MODELGEOMALGO_EXPORT void getPointsInsideShape(
+                        const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                        const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
+                        const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+                        const std::shared_ptr<GeomAPI_Dir>& theDirX,
+                        const std::shared_ptr<GeomAPI_Dir>& theDirY,
+                        PointToRefsMap& thePointToAttributeOrObject);
+
+  /// Removes attributes which points are out of the base shape
+  /// \param theBaseShape a shape of check
+  /// \param theAttributes a container of point 2D attributes
+  /// \param theOrigin origin of a plane to generate 3D point by 2D attribute point
+  /// \param theDirX plane X direction to generate 3D point by 2D attribute point
+  /// \param theDirY plane X direction to generate 3D point by 2D attribute point
+  /// \param thePoints a container of 3D points belong to the shape
+  /// \param theAttributeToPoint a container of attribute to point
+  MODELGEOMALGO_EXPORT void getPointsInsideShape_p(
                               const std::shared_ptr<GeomAPI_Shape> theBaseShape,
                               const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theAttributes,
                               const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
index 92c522464da205dc9dad88428b94616c761806c3..e72db6c832ed4d5da19c26afaffb712246653aa6 100644 (file)
@@ -163,7 +163,7 @@ bool PartSet_WidgetFeaturePointSelector::fillFeature(
 
     std::shared_ptr<ModelAPI_AttributeReference> aRef =
                             std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
-                            feature()->data()->attribute(SketchPlugin_Constraint::VALUE()));
+                            feature()->data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
     aRef->setValue(anObject);
 
     std::shared_ptr<GeomDataAPI_Point2D> anAttributePoint =
@@ -176,10 +176,7 @@ bool PartSet_WidgetFeaturePointSelector::fillFeature(
     // an attempt to clear highlighted item in the viewer: but of OCCT
     XGUI_Tools::workshop(myWorkshop)->displayer()->clearSelected(true);
 #endif
-    static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
-    ModelAPI_EventCreator::get()->sendUpdated(feature(), anEvent);
-    Events_Loop::loop()->flush(anEvent);
-
+    updateObject(feature());
     aFilled = true;
 
     /*
index 0e0a41a2eb78a8959a4cbfce9546435368eaee1e..e9d157a1da87b7e7704fbacf528d3b306129a093 100755 (executable)
@@ -302,11 +302,11 @@ void PartSet_WidgetSubShapeSelector::fillObjectShapes(const ObjectPtr& theObject
     std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
         aData->attribute(SketchPlugin_Sketch::NORM_ID()));
     std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
-    ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
+    ModelGeomAlgo_Point2D::getPointsInsideShape_p(aFeatureShape, aRefAttributes, aC->pnt(),
                                                 aX->dir(), aY, aPoints, aPointToAttributes);
 
     // intersection points
-    if (myUseGraphicIntersection) {
+    /*if (myUseGraphicIntersection) {
       std::list<FeaturePtr> aFeatures;
       for (int i = 0; i < aSketch->numberOfSubs(); i++) {
         FeaturePtr aFeature = aSketch->subFeature(i);
@@ -315,8 +315,8 @@ void PartSet_WidgetSubShapeSelector::fillObjectShapes(const ObjectPtr& theObject
       }
       ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPoints,
                                                        aPointToObjects);
-    }
-    GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPoints, aShapes);
+    }*/
+    GeomAlgoAPI_ShapeTools::splitShape_p(aFeatureShape, aPoints, aShapes);
   }
   myCashedShapes[theObject] = aShapes;
   myCashedReferences[theObject] = aPointToAttributes;
index bacc3c147ddb1bd9e69923130166f5638927a665..fdc8a71fb49940ddb1e28619e24b4558ffeed278 100644 (file)
@@ -24,6 +24,7 @@
 #include <SketchPlugin_ConstraintRadius.h>
 #include <SketchPlugin_ConstraintRigid.h>
 #include <SketchPlugin_ConstraintSplit.h>
+#include <SketchPlugin_Trim.h>
 #include <SketchPlugin_ConstraintTangent.h>
 #include <SketchPlugin_ConstraintVertical.h>
 #include <SketcherPrs_Tools.h>
@@ -481,6 +482,24 @@ std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::addSplit(
   return InterfacePtr(new ModelHighAPI_Interface(aFeature));
 }
 
+//--------------------------------------------------------------------------------------
+std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::addTrim(
+                                        const ModelHighAPI_Reference& theFeature,
+                                        const std::shared_ptr<GeomAPI_Pnt2d>& thePositionPoint)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature =
+    compositeFeature()->addFeature(SketchPlugin_Trim::ID());
+  fillAttribute(theFeature, aFeature->reference(SketchPlugin_Trim::BASE_OBJECT()));
+
+  AttributePtr anAttribute = aFeature->attribute(SketchPlugin_Trim::ENTITY_POINT());
+  if (anAttribute->attributeType() == GeomDataAPI_Point2D::typeId()) {
+    AttributePoint2DPtr aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttribute);
+    fillAttribute(thePositionPoint, aPointAttr);
+  }
+
+  return InterfacePtr(new ModelHighAPI_Interface(aFeature));
+}
+
 //--------------------------------------------------------------------------------------
 std::shared_ptr<ModelHighAPI_Interface> SketchAPI_Sketch::setAngle(
     const ModelHighAPI_RefAttr & theLine1,
index 500c06a6872c35d192978c37fe55356a4ee73d17..216474474f66f55ecfd08bad78eec15f59446068 100644 (file)
@@ -263,6 +263,12 @@ public:
       const ModelHighAPI_RefAttr& thePoint1,
       const ModelHighAPI_RefAttr& thePoint2);
 
+  /// Add trim
+  SKETCHAPI_EXPORT
+  std::shared_ptr<ModelHighAPI_Interface> addTrim(
+      const ModelHighAPI_Reference& theFeature,
+      const std::shared_ptr<GeomAPI_Pnt2d>& thePositionPoint);
+
   /// Set angle
   SKETCHAPI_EXPORT
   std::shared_ptr<ModelHighAPI_Interface> setAngle(
index a8d4c5579a12cdf5d245955160aceb8224cc4fea..32f47bb34fd54c4b019bec0801ea8c1403210171 100644 (file)
@@ -146,4 +146,5 @@ ADD_UNIT_TESTS(TestSketchPointLine.py
                TestHighload.py
                TestSnowflake.py
                TestArcBehavior.py
-               Test1924.py )
+               Test1924.py
+               TestTrimCircle.py )
index b8a7102d9c8a5c817b4634c1eb8c8d060da4f0cc..08be7f1694d1690931c2880b027b822a01cc5584 100755 (executable)
@@ -360,7 +360,7 @@ AISObjectPtr SketchPlugin_ConstraintSplit::getAISObject(AISObjectPtr thePrevious
 
     std::set<std::shared_ptr<GeomAPI_Shape> > aSplitShapes;
 
-    GeomAlgoAPI_ShapeTools::splitShape(aBaseShape, aPoints, aSplitShapes);
+    GeomAlgoAPI_ShapeTools::splitShape_p(aBaseShape, aPoints, aSplitShapes);
     std::shared_ptr<GeomAPI_Shape> aShape =
       GeomAlgoAPI_ShapeTools::findShape(aPoints, aSplitShapes);
 
index 0dfe4a88a58a778e0ad30ce449df8219e5a0ef2c..df4b238c1ba503c5f63e3b1c6d2380ee694bfafa 100644 (file)
@@ -7,6 +7,7 @@
 #include "SketchPlugin_Trim.h"
 
 #include <GeomAPI_Dir2d.h>
+#include <GeomAPI_Edge.h>
 #include <GeomAPI_Pnt2d.h>
 #include <GeomAPI_XY.h>
 #include <GeomDataAPI_Point2D.h>
@@ -22,8 +23,8 @@
 #include <ModelAPI_Session.h>
 #include <ModelAPI_AttributeDouble.h>
 
-#include <SketchPlugin_Line.h>
 #include <SketchPlugin_Arc.h>
+#include <SketchPlugin_ConstraintMiddle.h>
 #include <SketchPlugin_Circle.h>
 #include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_ConstraintEqual.h>
 #include <SketchPlugin_ConstraintTangent.h>
 #include <SketchPlugin_ConstraintLength.h>
 #include <SketchPlugin_ConstraintMirror.h>
+#include <SketchPlugin_Line.h>
 #include <SketchPlugin_MultiRotation.h>
 #include <SketchPlugin_MultiTranslation.h>
-#include <SketchPlugin_ConstraintMiddle.h>
+#include <SketchPlugin_Point.h>
 
 #include <ModelAPI_Events.h>
 #include <SketchPlugin_Line.h>
 
 #include <cmath>
 
+#define DEBUG_TRIM
+#ifdef DEBUG_TRIM
+#include <iostream>
+#endif
+
 //#define DEBUG_SPLIT
 #ifdef DEBUG_SPLIT
 #include <iostream>
 
 //static const double PI = 3.141592653589793238463;
 
+static const std::string OPERATION_HIGHLIGHT_COLOR() { return "128, 0, 0"; }
+
 SketchPlugin_Trim::SketchPlugin_Trim()
 {
 }
 
 void SketchPlugin_Trim::initAttributes()
 {
-  data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeReference::typeId());
+  data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId());
   //data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
   //data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
   data()->addAttribute(ENTITY_POINT(), GeomDataAPI_Point2D::typeId());
@@ -76,23 +85,211 @@ void SketchPlugin_Trim::initAttributes()
 //  return aConstraint;
 //}
 
+void SketchPlugin_Trim::findShapePoints(std::shared_ptr<GeomAPI_Pnt>& aStartPoint,
+                                        std::shared_ptr<GeomAPI_Pnt>& aLastPoint)
+{
+  AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                                            data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
+  ObjectPtr aBaseObject = aBaseObjectAttr->value();
+
+  AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                                            data()->attribute(ENTITY_POINT()));
+  std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
+  std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
+                                                               anAttributePnt2d->y());
+
+  if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
+    fillObjectShapes(aBaseObject);
+
+  const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
+  if (!aShapes.empty()) {
+    std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
+    for (; anIt != aLast; anIt++) {
+      GeomShapePtr aBaseShape = *anIt;
+      std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
+      if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, anAttributePnt, aProjectedPoint)) {
+
+        if (aBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
+          std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aBaseShape));
+          aStartPoint = anEdge->lastPoint();
+          aLastPoint = anEdge->firstPoint();
+        }
+      }
+    }
+  }
+#ifdef DEBUG_TRIM
+  std::cout << "<findShapePoints> => "
+            << "Start Point: ["
+            << aStartPoint->x() << ", " << aStartPoint->y() << ", " << aStartPoint->z() << "]"
+            << "Last Point: ["
+            << aLastPoint->x() << ", " << aLastPoint->y() << ", " << aLastPoint->z() << "]"
+            << std::endl;
+#endif
+}
+
+std::shared_ptr<GeomAPI_Pnt2d> SketchPlugin_Trim::convertPoint(
+                                                   const std::shared_ptr<GeomAPI_Pnt>& thePoint)
+{
+  std::shared_ptr<GeomAPI_Pnt2d> aPoint;
+
+  AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                                            data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
+  ObjectPtr aBaseObject = aBaseObjectAttr->value();
+  //std::map<ObjectPtr, PointToRefsMap> myObjectToPoints;
+  if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end())
+    return aPoint;
+
+  bool aFound = false;
+  const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
+  for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin();
+       aPointIt != aRefsMap.end() && !aFound; aPointIt++) {
+    if (aPointIt->first->isEqual(thePoint)) {
+      const std::pair<std::list<AttributePoint2DPtr >,
+               std::list<ObjectPtr > >& anInfo = aPointIt->second;
+      const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
+      if (!anAttributes.empty()) {
+        aPoint = anAttributes.front()->pnt();
+        aFound = true;
+      }
+      else {
+        std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
+        aPoint = thePoint->to2D(aPlane);
+        aFound = true;
+      }
+    }
+  }
+  if (!aFound)
+    return aPoint;
+  //if (aRefsMap.find(thePoint) == aRefsMap.end())
+  //  return aPoint;
+
+  //const std::pair<std::list<AttributePoint2DPtr >,
+  //         std::list<ObjectPtr > >& anInfo = aRefsMap.at(thePoint);
+
+  //const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
+  //if (!anAttributes.empty())
+  //  aPoint = anAttributes.front()->pnt();
+  //else {
+  //  std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
+  //  aPoint = thePoint->to2D(aPlane);
+  //}
+  return aPoint;
+}
+
 void SketchPlugin_Trim::execute()
 {
-  std::shared_ptr<ModelAPI_Data> aData = data();
+#ifdef DEBUG_SPLIT
+  std::cout << "SketchPlugin_Trim::execute" << std::endl;
+#endif
+
+  SketchPlugin_Sketch* aSketch = sketch();
+  if (!aSketch)
+    return;
 
   // Check the base objects are initialized.
   AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
-                                            aData->attribute(SketchPlugin_Constraint::VALUE()));
+                                            data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
   if(!aBaseObjectAttr->isInitialized()) {
     setError("Error: Base object is not initialized.");
     return;
   }
+  ObjectPtr aBaseObject = aBaseObjectAttr->value();
+  if (!aBaseObject.get())
+    return;
+  FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
+
+//#ifdef DEBUG_TRIM
+//  const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
+//#endif
+  /// points of trim
+  //std::map<std::shared_ptr<GeomAPI_Pnt2d>, std::shared_ptr<GeomAPI_Pnt> > aPntMap;
+
+  std::shared_ptr<GeomAPI_Pnt> aStartShapePoint, aLastShapePoint;
+  findShapePoints(aStartShapePoint, aLastShapePoint);
+  std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint2d = convertPoint(aStartShapePoint);
+  //aPntMap[aStartShapePoint2d] = aStartShapePoint;
+
+  std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint2d = convertPoint(aLastShapePoint);
+  //aPntMap[aLastShapePoint2d] = aLastShapePoint;
+
+  /*AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
+  getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
+  if (!aStartPointAttrOfBase.get() && !anEndPointAttrOfBase.get()) {
+    setError("Error: Feature has no start and end points.");
+    return;
+  }*/
+
+  std::set<FeaturePtr> aFeaturesToDelete, aFeaturesToUpdate;
+  //std::map<FeaturePtr, IdToPointPair> aTangentFeatures;
+  //std::map<FeaturePtr, IdToPointPair> aCoincidenceToFeature;
+  getConstraints(aFeaturesToDelete, aFeaturesToUpdate);//, aTangentFeatures, aCoincidenceToFeature);
+
+  std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
+  std::list<AttributePtr> aRefsToFeature;
+  getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
+
+  std::set<AttributePoint2DPtr> aFurtherCoincidences;
+  std::set<FeaturePtr> aCreatedFeatures;
+  std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
+  const std::string& aKind = aBaseFeature->getKind();
+  if (aKind == SketchPlugin_Circle::ID()) {
+    trimCircle(aStartShapePoint2d, aLastShapePoint2d,
+               aFurtherCoincidences, aCreatedFeatures, aModifiedAttributes);
+    updateRefFeatureConstraints(getFeatureResult(aBaseFeature), aRefsToFeature);
+
+    //AttributePtr aCenterAttr = aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID());
+    aFeaturesToDelete.insert(aBaseFeature);
+    // as circle is removed, temporary fill this attribute
+    aBaseObjectAttr->setObject(ResultPtr());
+  }
+  else if (aKind == SketchPlugin_Line::ID()) {
+  }
+  else if (aKind == SketchPlugin_Arc::ID()) {
+  }
+
+  // coincidence to result points
+  const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
+  std::set<AttributePoint2DPtr>::const_iterator anIt = aFurtherCoincidences.begin(),
+                                                aLast = aFurtherCoincidences.end();
+  for (; anIt != aLast; anIt++) {
+    AttributePoint2DPtr aPointAttribute = (*anIt);
+    std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
+
+    std::shared_ptr<GeomAPI_Pnt> aPoint;
+    if (aPoint2d->isEqual(aStartShapePoint2d))
+      aPoint = aStartShapePoint;
+    else if (aPoint2d->isEqual(aLastShapePoint2d))
+      aPoint = aLastShapePoint;
+    else
+      continue;
 
-  /*std::shared_ptr<GeomDataAPI_Point2D> anAPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+    std::pair<std::list<AttributePoint2DPtr >, std::list<ObjectPtr > > anInfo;
+    for (PointToRefsMap::const_iterator aRefIt = aRefsMap.begin(); aRefIt != aRefsMap.end();
+         aRefIt++)
+    {
+      if (aRefIt->first->isEqual(aPoint)) {
+        anInfo = aRefIt->second;
+        break;
+      }
+    }
+    const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
+    for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
+      anAttrIt != anAttributes.end(); anAttrIt++) {
+      createConstraint(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute, *anAttrIt);
+    }
+
+    const std::list<ObjectPtr>& anObjects = anInfo.second;
+    for (std::list<ObjectPtr>::const_iterator anObjectIt = anObjects.begin();
+      anObjectIt != anObjects.end(); anObjectIt++) {
+      createConstraint(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute, *anObjectIt);
+    }
+  }
+
+  /*AttributePoint2DPtr anAPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
           aData->attribute(ENTITY_A_POINT()));
   std::shared_ptr<GeomAPI_Pnt2d> anAttributeStartPnt2d = anAPoint->pnt();
 
-  std::shared_ptr<GeomDataAPI_Point2D> aBPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+  AttributePoint2DPtr aBPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
           aData->attribute(ENTITY_B_POINT()));
   std::shared_ptr<GeomAPI_Pnt2d> anAttributeEndPnt2d = aBPoint->pnt();
 
@@ -122,16 +319,16 @@ void SketchPlugin_Trim::execute()
 //  // Find feature constraints
   /*FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
 
-  std::set<std::shared_ptr<GeomDataAPI_Point2D> > aNewCoincidencesToSplitFeature;
+  std::set<AttributePoint2DPtr > aNewCoincidencesToSplitFeature;
   AttributePoint2DPtr aFeatureStartPointAttr, aFeatureEndPointAttr;
   getFeaturePoints(aBaseFeature, aFeatureStartPointAttr, aFeatureEndPointAttr);
 
   if (aFeatureStartPointAttr.get() && aFeatureStartPointAttr.get()) { // line or arc
-    std::shared_ptr<GeomDataAPI_Point2D> aStartPointAttribute =
+    AttributePoint2DPtr aStartPointAttribute =
                                std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
                                aFeatureStartPointAttr);
     std::shared_ptr<GeomAPI_Pnt2d> aFeatureStartPnt2d = aStartPointAttribute->pnt();
-    std::shared_ptr<GeomDataAPI_Point2D> anEndPointAttribute =
+    AttributePoint2DPtr anEndPointAttribute =
                                std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
                                aFeatureEndPointAttr);
     std::shared_ptr<GeomAPI_Pnt2d> aFeatureEndPnt2d = anEndPointAttribute->pnt();
@@ -156,9 +353,9 @@ void SketchPlugin_Trim::execute()
 //  std::map<FeaturePtr, IdToPointPair> aCoincidenceToFeature;
 //  getConstraints(aFeaturesToDelete, aFeaturesToUpdate, aTangentFeatures, aCoincidenceToFeature);
 //
-//  std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
-//  std::list<AttributePtr> aRefsToFeature;
-//  getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
+//std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
+//std::list<AttributePtr> aRefsToFeature;
+//getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
 //
 //  std::map<AttributePtr, AttributePtr> aBasePointModifiedAttributes;
 //
@@ -186,7 +383,7 @@ void SketchPlugin_Trim::execute()
 //    for (int i = 1; anIt != aLast; anIt++, i++) {
 //      FeaturePtr aFeature = (*anIt).first;
 //      std::string anAttributeId = (*anIt).second.first;
-//      std::shared_ptr<GeomDataAPI_Point2D> aPointAttr = (*anIt).second.second;
+//      AttributePoint2DPtr aPointAttr = (*anIt).second.second;
 //
 //      std::cout << i << "-" << getFeatureInfo(aFeature) << std::endl;
 //      std::cout <<     " -Attribute to correct:" << anAttributeId << std::endl;
@@ -203,7 +400,7 @@ void SketchPlugin_Trim::execute()
 //    for (int i = 1; anIt != aLast; anIt++, i++) {
 //      FeaturePtr aFeature = (*anIt).first;
 //      std::string anAttributeId = (*anIt).second.first;
-//      std::shared_ptr<GeomDataAPI_Point2D> aPointAttr = (*anIt).second.second;
+//      AttributePoint2DPtr aPointAttr = (*anIt).second.second;
 //
 //      std::cout << i << "-" << getFeatureInfo(aFeature) << std::endl;
 //      std::cout <<     " -Attribute to correct:" << anAttributeId << std::endl;
@@ -230,7 +427,7 @@ void SketchPlugin_Trim::execute()
 //      FeaturePtr aRFeature = ModelAPI_Feature::feature(aRAttr->owner());
 //      aRefsInfo.append("(" + aRFeature->name() + ") ");
 //    }
-//    std::shared_ptr<GeomDataAPI_Point2D> aPointAttr =
+//    AttributePoint2DPtr aPointAttr =
 //      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aBaseAttr);
 //    std::cout << aPointAttr->id().c_str() <<
 //      ": " << "[" << aRefAttributes.size() << "] " << aRefsInfo << std::endl;
@@ -342,21 +539,21 @@ void SketchPlugin_Trim::execute()
 //  // tangency
 //  updateTangentConstraintsToFeature(aTangentFeatures, aFurtherCoincidences);
 //
-//  updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes);
-//
-//  // delete constraints
-//#ifdef DEBUG_SPLIT
-//  std::cout << "remove features and references:" << std::endl;
-//  std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
-//                                       aDLast = aFeaturesToDelete.end();
-//  for (; aDIt != aDLast; aDIt++) {
-//    std::cout << getFeatureInfo(*aDIt, false) << std::endl;
-//    std::cout << std::endl;
-//  }
-//#endif
-//  ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
-//  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
-//
+  updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes);
+
+  // delete constraints
+#ifdef DEBUG_SPLIT
+  std::cout << "remove features and references:" << std::endl;
+  std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
+                                       aDLast = aFeaturesToDelete.end();
+  for (; aDIt != aDLast; aDIt++) {
+    std::cout << getFeatureInfo(*aDIt, false) << std::endl;
+    std::cout << std::endl;
+  }
+#endif
+  ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
+  Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
+
 //#ifdef DEBUG_SPLIT
 //  std::cout << "update features after split:" << std::endl;
 //  std::set<FeaturePtr>::const_iterator anUIt = aFeaturesToUpdate.begin(),
@@ -379,6 +576,10 @@ void SketchPlugin_Trim::execute()
 //    std::cout << getFeatureInfo(aSketch->subFeature(i), false) << std::endl;
 //  }
 //#endif
+
+#ifdef DEBUG_SPLIT
+  std::cout << "SketchPlugin_Trim::done" << std::endl;
+#endif
 }
 
 bool SketchPlugin_Trim::isMacro() const
@@ -386,21 +587,19 @@ bool SketchPlugin_Trim::isMacro() const
   return true;
 }
 
-static const std::string OPERATION_HIGHLIGHT_COLOR() { return "128, 0, 0"; }
 AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 {
   AISObjectPtr anAIS = thePrevious;
   // feature for trim
   AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
-                                           data()->attribute(SketchPlugin_Constraint::VALUE()));
+                                           data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
   ObjectPtr aBaseObject = aBaseObjectAttr->value();
   if (!aBaseObject.get())
     return anAIS;
-
   FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
 
   // point on feature
-  std::shared_ptr<GeomDataAPI_Point2D> aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+  AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
                                            data()->attribute(ENTITY_POINT()));
   std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
   std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(), anAttributePnt2d->y());
@@ -516,7 +715,7 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
   return anAIS;
 }
 
-//std::shared_ptr<GeomDataAPI_Point2D> SketchPlugin_Trim::getPointOfRefAttr(
+//AttributePoint2DPtr SketchPlugin_Trim::getPointOfRefAttr(
 //                                                      const AttributePtr& theAttribute)
 //{
 //  AttributePoint2DPtr aPointAttribute;
@@ -533,198 +732,200 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //  return aPointAttribute;
 //}
 //
-//void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
-//                                                    AttributePoint2DPtr& theStartPointAttr,
-//                                                    AttributePoint2DPtr& theEndPointAttr)
-//{
-//  std::string aFeatureKind = theFeature->getKind();
-//  std::string aStartAttributeName, anEndAttributeName;
-//  if (aFeatureKind == SketchPlugin_Line::ID()) {
-//    aStartAttributeName = SketchPlugin_Line::START_ID();
-//    anEndAttributeName = SketchPlugin_Line::END_ID();
-//  }
-//  else if (aFeatureKind == SketchPlugin_Arc::ID()) {
-//    aStartAttributeName = SketchPlugin_Arc::START_ID();
-//    anEndAttributeName = SketchPlugin_Arc::END_ID();
-//  }
-//  if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
-//    theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-//                                         theFeature->attribute(aStartAttributeName));
-//    theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-//                                         theFeature->attribute(anEndAttributeName));
-//  }
-//}
-//
-//void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete,
-//                                      std::set<FeaturePtr>& theFeaturesToUpdate,
-//                                      std::map<FeaturePtr, IdToPointPair>& theTangentFeatures,
-//                                      std::map<FeaturePtr, IdToPointPair>& theCoincidenceToFeature)
-//{
-//  std::shared_ptr<ModelAPI_Data> aData = data();
-//
-//  // Check the base objects are initialized.
-//  AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
-//                                            aData->attribute(SketchPlugin_Constraint::VALUE()));
-//  FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
-//  ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
-//
-//  std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
-//  std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
-//  aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
-//
-//  std::set<AttributePtr>::const_iterator aIt;
-//  for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
-//    std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
-//    FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
-//    std::string aRefFeatureKind = aRefFeature->getKind();
-//    if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
-//        aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
-//        aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
-//        aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
-//      theFeaturesToDelete.insert(aRefFeature);
-//    else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID())
-//      theFeaturesToUpdate.insert(aRefFeature);
-//    else if (aRefFeatureKind == SketchPlugin_ConstraintTangent::ID()) {
-//      if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) /// TEMPORARY limitaion
-//        /// until tangency between arc and line is implemented
-//        theFeaturesToDelete.insert(aRefFeature);
-//      else {
-//        std::string anAttributeToBeModified;
-//        AttributePoint2DPtr aTangentPoint;
-//        ObjectPtr aResult1 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->object();
-//        ObjectPtr aResult2 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B())->object();
-//        if (aResult1.get() && aResult2.get()) {
-//          FeaturePtr aCoincidenceFeature =
-//            SketchPlugin_ConstraintCoincidence::findCoincidenceFeature
-//                                                       (ModelAPI_Feature::feature(aResult1),
-//                                                        ModelAPI_Feature::feature(aResult2));
-//          // get the point not lying on the splitting feature
-//          for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
-//            AttributeRefAttrPtr aRefAttr = aCoincidenceFeature->refattr(ATTRIBUTE(i));
-//            if (!aRefAttr || aRefAttr->isObject())
-//              continue;
-//            AttributePoint2DPtr aPoint =
-//                std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
-//            if (!aPoint)
-//              continue;
-//            if (aPoint->owner() != aBaseFeature) {
-//              aTangentPoint = aPoint;
-//              break;
-//            }
-//          }
-//        }
-//        if (aTangentPoint.get()) {
-//          FeaturePtr aFeature1 = ModelAPI_Feature::feature(aResult1);
-//          std::string anAttributeToBeModified = aFeature1 == aBaseFeature
-//                       ? SketchPlugin_Constraint::ENTITY_A() : SketchPlugin_Constraint::ENTITY_B();
-//          theTangentFeatures[aRefFeature] = std::make_pair(anAttributeToBeModified, aTangentPoint);
-//        }
-//        else /// there is not coincident point between tangent constraint
-//          theFeaturesToDelete.insert(aRefFeature);
-//      }
-//    }
-//    else if (aRefFeatureKind == SketchPlugin_ConstraintCoincidence::ID()) {
-//      std::string anAttributeToBeModified;
-//      AttributePoint2DPtr aCoincidentPoint;
-//      AttributeRefAttrPtr anAttrA = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A());
-//      AttributeRefAttrPtr anAttrB = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B());
-//      bool isToFeature = false;
-//      if (anAttrA->isObject() || anAttrB->isObject()) { /// coincidence to base feature
-//        FeaturePtr aFeature = anAttrA->isObject() ? ModelAPI_Feature::feature(anAttrA->object())
-//                                                  : FeaturePtr();
-//        isToFeature = aFeature.get() && aFeature == aBaseFeature;
-//        anAttributeToBeModified = anAttrA->id();
-//        if (!isToFeature) {
-//          aFeature = anAttrB->isObject() ? ModelAPI_Feature::feature(anAttrB->object())
-//                                         : FeaturePtr();
-//          isToFeature = aFeature.get() && aFeature == aBaseFeature;
-//          anAttributeToBeModified = anAttrB->id();
-//        }
-//        if (isToFeature)
-//          aCoincidentPoint = SketchPlugin_ConstraintCoincidence::getPoint(aRefFeature);
-//      }
-//      if (!isToFeature) { /// coincidence to point on base feature
-//        AttributePtr anAttribute;
-//
-//        if (!anAttrA->isObject()) {
-//          AttributePtr aCurAttribute = anAttrA->attr();
-//          if (aCurAttribute.get()) {
-//            FeaturePtr aCurFeature = ModelAPI_Feature::feature(aCurAttribute->owner());
-//            if (aCurFeature.get() && aCurFeature == aBaseFeature) {
-//              anAttribute = anAttrB->attr();
-//              anAttributeToBeModified = anAttrA->id();
-//            }
-//          }
-//        }
-//        if (!anAttribute.get() && !anAttrB->isObject()) {
-//          AttributePtr aCurAttribute = anAttrB->attr();
-//          if (aCurAttribute.get()) {
-//            FeaturePtr aCurFeature = ModelAPI_Feature::feature(aCurAttribute->owner());
-//            if (aCurFeature.get() && aCurFeature == aBaseFeature) {
-//              anAttribute = anAttrA->attr();
-//              anAttributeToBeModified = anAttrB->id();
-//            }
-//          }
-//        }
-//        if (anAttribute.get())
-//          aCoincidentPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttribute);
-//      }
-//      if (aCoincidentPoint.get() && isToFeature)
-//        theCoincidenceToFeature[aRefFeature] = std::make_pair(anAttributeToBeModified,
-//                                                              aCoincidentPoint);
-//    }
-//  }
-//}
-//
-//void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
-//                                    std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
-//                                    std::list<AttributePtr>& theRefsToFeature)
-//{
-//  theRefs.clear();
-//
-//  std::list<AttributePtr> aPointAttributes =
-//    theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
-//  std::set<AttributePtr> aPointAttributesSet;
-//
-//  std::list<AttributePtr>::const_iterator aPIt =
-//    aPointAttributes.begin(), aPLast = aPointAttributes.end();
-//  for (; aPIt != aPLast; aPIt++)
-//    aPointAttributesSet.insert(*aPIt);
-//
-//  std::set<AttributePtr> aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe();
-//  std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
-//  aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
-//
-//  std::set<AttributePtr>::const_iterator aIt;
-//  for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
-//    AttributePtr anAttr = (*aIt);
-//    FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
-//    if (anAttrFeature.get() != this &&
-//        anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
-//      AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
-//      if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes
-//        AttributePtr anAttrInRef = aRefAttr->attr();
-//        if (anAttrInRef.get() &&
-//            aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
-//          if (theRefs.find(anAttrInRef) != theRefs.end())
-//            theRefs[anAttrInRef].push_back(aRefAttr);
-//          else {
-//            std::list<AttributePtr> anAttrList;
-//            anAttrList.push_back(aRefAttr);
-//            theRefs[anAttrInRef] = anAttrList;
-//          }
-//        }
-//      }
-//      else { /// find attributes referenced to feature itself
-//        theRefsToFeature.push_back(anAttr);
-//      }
-//    }
-//  }
-//}
-//
+
+void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
+                                         AttributePoint2DPtr& theStartPointAttr,
+                                         AttributePoint2DPtr& theEndPointAttr)
+{
+  std::string aFeatureKind = theFeature->getKind();
+  std::string aStartAttributeName, anEndAttributeName;
+  if (aFeatureKind == SketchPlugin_Line::ID()) {
+    aStartAttributeName = SketchPlugin_Line::START_ID();
+    anEndAttributeName = SketchPlugin_Line::END_ID();
+  }
+  else if (aFeatureKind == SketchPlugin_Arc::ID()) {
+    aStartAttributeName = SketchPlugin_Arc::START_ID();
+    anEndAttributeName = SketchPlugin_Arc::END_ID();
+  }
+  if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
+    theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                         theFeature->attribute(aStartAttributeName));
+    theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                         theFeature->attribute(anEndAttributeName));
+  }
+}
+
+void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete,
+                                      std::set<FeaturePtr>& theFeaturesToUpdate//,
+                                      //std::map<FeaturePtr, IdToPointPair>& theTangentFeatures,
+                                      //std::map<FeaturePtr, IdToPointPair>& theCoincidenceToFeature
+                                      )
+{
+  std::shared_ptr<ModelAPI_Data> aData = data();
+
+  // Check the base objects are initialized.
+  AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                                            aData->attribute(SketchPlugin_Trim::BASE_OBJECT()));
+  FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
+  ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
+
+  std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
+  std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
+  aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
+
+  std::set<AttributePtr>::const_iterator aIt;
+  for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+    std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
+    FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
+    std::string aRefFeatureKind = aRefFeature->getKind();
+    if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
+        aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
+        aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
+        aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
+      theFeaturesToDelete.insert(aRefFeature);
+    else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID())
+      theFeaturesToUpdate.insert(aRefFeature);
+    else if (aRefFeatureKind == SketchPlugin_ConstraintTangent::ID()) {
+      if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) /// TEMPORARY limitaion
+        /// until tangency between arc and line is implemented
+        theFeaturesToDelete.insert(aRefFeature);
+      else {
+        std::string anAttributeToBeModified;
+        AttributePoint2DPtr aTangentPoint;
+        ObjectPtr aResult1 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->object();
+        ObjectPtr aResult2 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B())->object();
+        if (aResult1.get() && aResult2.get()) {
+          FeaturePtr aCoincidenceFeature =
+            SketchPlugin_ConstraintCoincidence::findCoincidenceFeature
+                                                       (ModelAPI_Feature::feature(aResult1),
+                                                        ModelAPI_Feature::feature(aResult2));
+          // get the point not lying on the splitting feature
+          for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
+            AttributeRefAttrPtr aRefAttr = aCoincidenceFeature->refattr(SketchPlugin_Trim::BASE_OBJECT());
+            if (!aRefAttr || aRefAttr->isObject())
+              continue;
+            AttributePoint2DPtr aPoint =
+                std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
+            if (!aPoint)
+              continue;
+            if (aPoint->owner() != aBaseFeature) {
+              aTangentPoint = aPoint;
+              break;
+            }
+          }
+        }
+        if (aTangentPoint.get()) {
+          //FeaturePtr aFeature1 = ModelAPI_Feature::feature(aResult1);
+          //std::string anAttributeToBeModified = aFeature1 == aBaseFeature
+          //             ? SketchPlugin_Constraint::ENTITY_A() : SketchPlugin_Constraint::ENTITY_B();
+          //theTangentFeatures[aRefFeature] = std::make_pair(anAttributeToBeModified, aTangentPoint);
+        }
+        else /// there is not coincident point between tangent constraint
+          theFeaturesToDelete.insert(aRefFeature);
+      }
+    }
+    /*else if (aRefFeatureKind == SketchPlugin_ConstraintCoincidence::ID()) {
+      std::string anAttributeToBeModified;
+      AttributePoint2DPtr aCoincidentPoint;
+      AttributeRefAttrPtr anAttrA = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A());
+      AttributeRefAttrPtr anAttrB = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B());
+      bool isToFeature = false;
+      if (anAttrA->isObject() || anAttrB->isObject()) { /// coincidence to base feature
+        FeaturePtr aFeature = anAttrA->isObject() ? ModelAPI_Feature::feature(anAttrA->object())
+                                                  : FeaturePtr();
+        isToFeature = aFeature.get() && aFeature == aBaseFeature;
+        anAttributeToBeModified = anAttrA->id();
+        if (!isToFeature) {
+          aFeature = anAttrB->isObject() ? ModelAPI_Feature::feature(anAttrB->object())
+                                         : FeaturePtr();
+          isToFeature = aFeature.get() && aFeature == aBaseFeature;
+          anAttributeToBeModified = anAttrB->id();
+        }
+        if (isToFeature)
+          aCoincidentPoint = SketchPlugin_ConstraintCoincidence::getPoint(aRefFeature);
+      }
+      if (!isToFeature) { /// coincidence to point on base feature
+        AttributePtr anAttribute;
+
+        if (!anAttrA->isObject()) {
+          AttributePtr aCurAttribute = anAttrA->attr();
+          if (aCurAttribute.get()) {
+            FeaturePtr aCurFeature = ModelAPI_Feature::feature(aCurAttribute->owner());
+            if (aCurFeature.get() && aCurFeature == aBaseFeature) {
+              anAttribute = anAttrB->attr();
+              anAttributeToBeModified = anAttrA->id();
+            }
+          }
+        }
+        if (!anAttribute.get() && !anAttrB->isObject()) {
+          AttributePtr aCurAttribute = anAttrB->attr();
+          if (aCurAttribute.get()) {
+            FeaturePtr aCurFeature = ModelAPI_Feature::feature(aCurAttribute->owner());
+            if (aCurFeature.get() && aCurFeature == aBaseFeature) {
+              anAttribute = anAttrA->attr();
+              anAttributeToBeModified = anAttrB->id();
+            }
+          }
+        }
+        if (anAttribute.get())
+          aCoincidentPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttribute);
+      }
+      //if (aCoincidentPoint.get() && isToFeature)
+      //  theCoincidenceToFeature[aRefFeature] = std::make_pair(anAttributeToBeModified,
+      //                                                        aCoincidentPoint);
+    }*/
+  }
+}
+
+void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
+                                    std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
+                                    std::list<AttributePtr>& theRefsToFeature)
+{
+  theRefs.clear();
+
+  std::list<AttributePtr> aPointAttributes =
+    theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+  std::set<AttributePtr> aPointAttributesSet;
+
+  std::list<AttributePtr>::const_iterator aPIt =
+    aPointAttributes.begin(), aPLast = aPointAttributes.end();
+  for (; aPIt != aPLast; aPIt++)
+    aPointAttributesSet.insert(*aPIt);
+
+  std::set<AttributePtr> aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe();
+  std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
+  aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
+
+  std::set<AttributePtr>::const_iterator aIt;
+  for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
+    AttributePtr anAttr = (*aIt);
+    FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
+    if (anAttrFeature.get() != this &&
+        anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
+      AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
+      if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes
+        AttributePtr anAttrInRef = aRefAttr->attr();
+        if (anAttrInRef.get() &&
+            aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
+          if (theRefs.find(anAttrInRef) != theRefs.end())
+            theRefs[anAttrInRef].push_back(aRefAttr);
+          else {
+            std::list<AttributePtr> anAttrList;
+            anAttrList.push_back(aRefAttr);
+            theRefs[anAttrInRef] = anAttrList;
+          }
+        }
+      }
+      else { /// find attributes referenced to feature itself
+        theRefsToFeature.push_back(anAttr);
+      }
+    }
+  }
+}
+
 //void SketchPlugin_Trim::updateCoincidenceConstraintsToFeature(
 //      const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToFeature,
-//      const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences,
+//      const std::set<AttributePoint2DPtr >& theFurtherCoincidences,
 //      const std::set<ResultPtr>& theFeatureResults,
 //      const FeaturePtr& theSplitFeature)
 //{
@@ -732,7 +933,7 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //    return;
 //
 //  // we should build coincidence constraints to end of the split feature
-//  std::set<std::shared_ptr<GeomDataAPI_Point2D> > aNewCoincidencesToSplitFeature;
+//  std::set<AttributePoint2DPtr > aNewCoincidencesToSplitFeature;
 //  AttributePoint2DPtr aStartPointAttr, anEndPointAttr;
 //  getFeaturePoints(theSplitFeature, aStartPointAttr, anEndPointAttr);
 //  if (theFurtherCoincidences.find(aStartPointAttr) == theFurtherCoincidences.end())
@@ -801,7 +1002,7 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //
 //void SketchPlugin_Trim::updateTangentConstraintsToFeature(
 //      const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theTangentFeatures,
-//      const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences)
+//      const std::set<AttributePoint2DPtr >& theFurtherCoincidences)
 //{
 //  if (theTangentFeatures.empty())
 //    return;
@@ -836,54 +1037,54 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //#endif
 //  }
 //}
-//
-//void SketchPlugin_Trim::updateRefFeatureConstraints(
-//                                                  const ResultPtr& theFeatureBaseResult,
-//                                                  const std::list<AttributePtr>& theRefsToFeature)
-//{
-//  std::list<AttributePtr>::const_iterator anIt = theRefsToFeature.begin(),
-//                                          aLast = theRefsToFeature.end();
-//  for (; anIt != aLast; anIt++) {
-//    AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
-//    if (aRefAttr.get())
-//      aRefAttr->setObject(theFeatureBaseResult);
-//  }
-//}
-//
-//void SketchPlugin_Trim::updateRefAttConstraints(
-//                    const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
-//                    const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes)
-//{
-//#ifdef DEBUG_SPLIT
-//  std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl;
-//#endif
-//
-//  std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
-//    anIt = theModifiedAttributes.begin(),  aLast = theModifiedAttributes.end();
-//  for (; anIt != aLast; anIt++) {
-//    AttributePtr anAttribute = anIt->first;
-//
-//    /// not found in references
-//    if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
-//      continue;
-//    std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
-//    std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
-//                                            aRLast = aRefAttributes.end();
-//
-//    AttributePtr aNewAttribute = anIt->second;
-//    for (; aRefIt != aRLast; aRefIt++) {
-//      AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
-//      if (aRefAttr.get()) {
-//        aRefAttr->setAttr(aNewAttribute);
-//#ifdef DEBUG_SPLIT
-//        FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
-//        std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
-//#endif
-//      }
-//    }
-//  }
-//}
-//
+
+void SketchPlugin_Trim::updateRefFeatureConstraints(
+                                                  const ResultPtr& theFeatureBaseResult,
+                                                  const std::list<AttributePtr>& theRefsToFeature)
+{
+  std::list<AttributePtr>::const_iterator anIt = theRefsToFeature.begin(),
+                                          aLast = theRefsToFeature.end();
+  for (; anIt != aLast; anIt++) {
+    AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
+    if (aRefAttr.get())
+      aRefAttr->setObject(theFeatureBaseResult);
+  }
+}
+
+void SketchPlugin_Trim::updateRefAttConstraints(
+                    const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
+                    const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes)
+{
+#ifdef DEBUG_SPLIT
+  std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl;
+#endif
+
+  std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
+    anIt = theModifiedAttributes.begin(),  aLast = theModifiedAttributes.end();
+  for (; anIt != aLast; anIt++) {
+    AttributePtr anAttribute = anIt->first;
+
+    /// not found in references
+    if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
+      continue;
+    std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
+    std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
+                                            aRLast = aRefAttributes.end();
+
+    AttributePtr aNewAttribute = anIt->second;
+    for (; aRefIt != aRLast; aRefIt++) {
+      AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
+      if (aRefAttr.get()) {
+        aRefAttr->setAttr(aNewAttribute);
+#ifdef DEBUG_SPLIT
+        FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
+        std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
+#endif
+      }
+    }
+  }
+}
+
 //void SketchPlugin_Trim::splitLine(FeaturePtr& theSplitFeature,
 //                                             FeaturePtr& theBaseFeatureModified,
 //                                             FeaturePtr& theAfterFeature,
@@ -900,7 +1101,7 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //    return;
 //
 //  AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
-//                                           data()->attribute(SketchPlugin_Constraint::VALUE()));
+//                                           data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
 //  FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
 //  std::string aFeatureKind = aBaseFeature->getKind();
 //  if (aFeatureKind != SketchPlugin_Line::ID())
@@ -1034,7 +1235,7 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //    return;
 //
 //  AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
-//                                           data()->attribute(SketchPlugin_Constraint::VALUE()));
+//                                           data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
 //  FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
 //  std::string aFeatureKind = aBaseFeature->getKind();
 //  if (aFeatureKind != SketchPlugin_Arc::ID())
@@ -1160,74 +1361,83 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //    theCreatedFeatures.insert(aConstraintFeature);
 //  }
 //}
-//
-//void SketchPlugin_Trim::splitCircle(FeaturePtr& theSplitFeature,
-//                                               FeaturePtr& theBaseFeatureModified,
-//                                               FeaturePtr& theAfterFeature,
-//                                               std::set<AttributePoint2DPtr>& thePoints,
-//                                               std::set<FeaturePtr>& theCreatedFeatures,
-//                 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
-//{
-//  std::set<FeaturePtr> aCreatedFeatures;
-//  FeaturePtr aConstraintFeature;
-//  theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature
-//
-//  SketchPlugin_Sketch* aSketch = sketch();
-//  if (!aSketch)
-//    return;
-//
-//  AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
-//                                           data()->attribute(SketchPlugin_Constraint::VALUE()));
-//  FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
-//  std::string aFeatureKind = aBaseFeature->getKind();
-//  if (aFeatureKind != SketchPlugin_Circle::ID())
-//    return;
-//
-//  AttributePoint2DPtr aFirstPointAttrOfSplit =
-//    getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
-//  AttributePoint2DPtr aSecondPointAttrOfSplit =
-//    getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
-//
-//  /// split feature
-//  theSplitFeature =
-//    createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit);
-//  bool aSplitReversed = std::dynamic_pointer_cast<SketchPlugin_Arc>(theSplitFeature)->isReversed();
-//  theCreatedFeatures.insert(theSplitFeature);
-//
-//  /// base feature is a left part of the circle
-//  theBaseFeatureModified = createArcFeature(aBaseFeature,
-//    aFirstPointAttrOfSplit, aSecondPointAttrOfSplit);
-//  std::dynamic_pointer_cast<SketchPlugin_Arc>(
-//    theBaseFeatureModified)->setReversed(!aSplitReversed);
-//  theBaseFeatureModified->execute();
-//
-//  theModifiedAttributes.insert(
-//    std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
-//                  theBaseFeatureModified->attribute(SketchPlugin_Arc::CENTER_ID())));
-//
-//  theCreatedFeatures.insert(theBaseFeatureModified);
-//
-//  thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
-//                             (theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID())));
-//  thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
-//                             (theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID())));
-//
-//  // additional constraints between split and base features
-//  aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
-//                     theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()),
-//                     theSplitFeature->attribute(SketchPlugin_Arc::END_ID()));
-//  theCreatedFeatures.insert(aConstraintFeature);
-//  aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
-//                     theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()),
-//                     theSplitFeature->attribute(SketchPlugin_Arc::START_ID()));
-//  theCreatedFeatures.insert(aConstraintFeature);
-//
-//  aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(),
-//                                                       getFeatureResult(theSplitFeature),
-//                                                       getFeatureResult(theBaseFeatureModified));
-//  theCreatedFeatures.insert(aConstraintFeature);
-//}
-//
+
+void SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+                                   const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
+                                   /*FeaturePtr& theSplitFeature,
+                                   FeaturePtr& theBaseFeatureModified,
+                                   FeaturePtr& theAfterFeature,*/
+                                   std::set<AttributePoint2DPtr>& thePoints,
+                                   std::set<FeaturePtr>& theCreatedFeatures,
+                 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
+{
+  // Check the base objects are initialized.
+  AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                                            data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
+  ObjectPtr aBaseObject = aBaseObjectAttr->value();
+  FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
+
+  /// points of trim
+  //std::shared_ptr<GeomAPI_Pnt> aStartShapePoint, aLastShapePoint;
+  //findShapePoints(aStartShapePoint, aLastShapePoint);
+  //std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint2d = convertPoint(aStartShapePoint);
+  //std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint2d = convertPoint(aLastShapePoint);
+  AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
+  getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
+
+  //std::set<FeaturePtr> aCreatedFeatures;
+  //FeaturePtr aConstraintFeature;
+  //theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature
+
+  SketchPlugin_Sketch* aSketch = sketch();
+  //if (!aSketch)
+  //  return;
+
+  //AttributePoint2DPtr aFirstPointAttrOfSplit =
+  //  getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
+  //AttributePoint2DPtr aSecondPointAttrOfSplit =
+  //  getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
+
+  /// split feature
+  //theSplitFeature =
+  //  createArcFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit);
+  //bool aSplitReversed = std::dynamic_pointer_cast<SketchPlugin_Arc>(theSplitFeature)->isReversed();
+  //theCreatedFeatures.insert(theSplitFeature);
+
+  /// base feature is a left part of the circle
+  /*theBaseFeatureModified =*/
+  FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
+  //std::dynamic_pointer_cast<SketchPlugin_Arc>(
+  //  theBaseFeatureModified)->setReversed(!aSplitReversed);
+  //theBaseFeatureModified->execute();
+
+  theModifiedAttributes.insert(
+    std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
+                   anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
+
+  //theCreatedFeatures.insert(theBaseFeatureModified);
+
+  thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+                             (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
+  thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+                             (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
+
+  // additional constraints between split and base features
+  /*aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
+                     theBaseFeatureModified->attribute(SketchPlugin_Arc::END_ID()),
+                     theSplitFeature->attribute(SketchPlugin_Arc::END_ID()));
+  theCreatedFeatures.insert(aConstraintFeature);
+  aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
+                     theBaseFeatureModified->attribute(SketchPlugin_Arc::START_ID()),
+                     theSplitFeature->attribute(SketchPlugin_Arc::START_ID()));
+  theCreatedFeatures.insert(aConstraintFeature);
+
+  aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(),
+                                                       getFeatureResult(theSplitFeature),
+                                                       getFeatureResult(theBaseFeatureModified));
+  theCreatedFeatures.insert(aConstraintFeature);*/
+}
+
 //void SketchPlugin_Trim::arrangePointsOnLine(
 //    const AttributePoint2DPtr& theStartPointAttr,
 //    const AttributePoint2DPtr& theEndPointAttr,
@@ -1245,10 +1455,10 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //
 //void SketchPlugin_Trim::arrangePointsOnArc(
 //    const FeaturePtr& theArc,
-//    const std::shared_ptr<GeomDataAPI_Point2D>& theStartPointAttr,
-//    const std::shared_ptr<GeomDataAPI_Point2D>& theEndPointAttr,
-//    std::shared_ptr<GeomDataAPI_Point2D>& theFirstPointAttr,
-//    std::shared_ptr<GeomDataAPI_Point2D>& theSecondPointAttr) const
+//    const AttributePoint2DPtr& theStartPointAttr,
+//    const AttributePoint2DPtr& theEndPointAttr,
+//    AttributePoint2DPtr& theFirstPointAttr,
+//    AttributePoint2DPtr& theSecondPointAttr) const
 //{
 //  static const double anAngleTol = 1.e-12;
 //
@@ -1279,45 +1489,61 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //    theSecondPointAttr = aTmpPoint;
 //  }
 //}
-//
-//void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute,
-//                                      const AttributePtr& theSourceAttribute)
-//{
-//  std::string anAttributeType = theModifiedAttribute->attributeType();
-//  if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
-//    AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-//                                              theModifiedAttribute);
-//    AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-//                                              theSourceAttribute);
-//
-//    if (aModifiedAttribute.get() && aSourceAttribute.get())
-//      aModifiedAttribute->setValue(aSourceAttribute->pnt());
-//  }
-//  else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
-//    AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
-//                                              theModifiedAttribute);
-//    AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
-//                                              theSourceAttribute);
-//
-//    if (aModifiedAttribute.get() && aSourceAttribute.get())
-//      aModifiedAttribute->setValue(aSourceAttribute->value());
-//  }
-//  else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
-//    AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-//                                                                               theModifiedAttribute);
-//    AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-//                                         theSourceAttribute);
-//    if (!aSourceRefAttr.get())
-//      aRefAttributeToFill->setAttr(theSourceAttribute);
-//    else {
-//      if (aSourceRefAttr->isObject())
-//        aRefAttributeToFill->setObject(aSourceRefAttr->object());
-//      else
-//        aRefAttributeToFill->setAttr(aSourceRefAttr->attr());
-//    }
-//  }
-//}
-//
+
+void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttribute,
+                                           const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+{
+  std::string anAttributeType = theModifiedAttribute->attributeType();
+  if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
+    AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                              theModifiedAttribute);
+    aModifiedAttribute->setValue(thePoint);
+
+#ifdef DEBUG_TRIM
+    std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", " << thePoint->y() << "]" << std::endl;
+#endif
+  }
+}
+
+
+void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute,
+                                      const AttributePtr& theSourceAttribute)
+{
+  std::string anAttributeType = theModifiedAttribute->attributeType();
+  if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
+    AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                              theModifiedAttribute);
+    AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                              theSourceAttribute);
+
+    if (aModifiedAttribute.get() && aSourceAttribute.get())
+      aModifiedAttribute->setValue(aSourceAttribute->pnt());
+  }
+  else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
+    AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+                                              theModifiedAttribute);
+    AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+                                              theSourceAttribute);
+
+    if (aModifiedAttribute.get() && aSourceAttribute.get())
+      aModifiedAttribute->setValue(aSourceAttribute->value());
+  }
+  else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
+    AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                                                               theModifiedAttribute);
+    AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                         theSourceAttribute);
+    if (!aSourceRefAttr.get())
+      aRefAttributeToFill->setAttr(theSourceAttribute);
+    else {
+      if (aSourceRefAttr->isObject())
+        aRefAttributeToFill->setObject(aSourceRefAttr->object());
+      else
+        aRefAttributeToFill->setAttr(aSourceRefAttr->attr());
+    }
+  }
+}
+
 //FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature,
 //                                                const AttributePtr& theFirstPointAttr,
 //                                                const AttributePtr& theSecondPointAttr)
@@ -1340,68 +1566,100 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //  return aFeature;
 //}
 //
-//FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
-//                                                          const AttributePtr& theFirstPointAttr,
-//                                                          const AttributePtr& theSecondPointAttr)
-//{
-//  FeaturePtr aFeature;
-//  SketchPlugin_Sketch* aSketch = sketch();
-//  if (!aSketch || !theBaseFeature.get())
-//    return aFeature;
-//
-//  std::string aCenterAttributeId;
-//  if (theBaseFeature->getKind() == SketchPlugin_Arc::ID())
-//    aCenterAttributeId = SketchPlugin_Arc::CENTER_ID();
-//  else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID())
-//    aCenterAttributeId = SketchPlugin_Circle::CENTER_ID();
-//
-//  if (aCenterAttributeId.empty())
-//    return aFeature;
-//
-//  aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
-//  // update fillet arc: make the arc correct for sure, so, it is not needed to process
-//  // the "attribute updated"
-//  // by arc; moreover, it may cause cyclicity in hte mechanism of updater
-//  bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
-//
-//  aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue(
-//                SketchPlugin_Arc::ARC_TYPE_CENTER_START_END());
-//
-//  fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
-//                theBaseFeature->attribute(aCenterAttributeId));
-//  fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPointAttr);
-//  fillAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPointAttr);
-//
-//  fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
-//                theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
-//
-//  /// fill referersed state of created arc as it is on the base arc
-//  if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
-//    bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
-//    aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed);
-//  }
-//  aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
-//  aFeature->execute(); // to obtain result
-//
-//  return aFeature;
-//}
-//
-//FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
-//                                                    const AttributePtr& theFirstAttribute,
-//                                                    const AttributePtr& theSecondAttribute)
-//{
-//  FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
-//  AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-//                                 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
-//  aRefAttr->setAttr(theFirstAttribute);
-//
-//  aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-//                                 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
-//  aRefAttr->setAttr(theSecondAttribute);
-//
-//  return aConstraint;
-//}
-//
+
+FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
+                                               const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
+                                               const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
+{
+  FeaturePtr aFeature;
+  SketchPlugin_Sketch* aSketch = sketch();
+  if (!aSketch || !theBaseFeature.get())
+    return aFeature;
+
+  std::string aCenterAttributeId;
+  if (theBaseFeature->getKind() == SketchPlugin_Arc::ID())
+    aCenterAttributeId = SketchPlugin_Arc::CENTER_ID();
+  else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID())
+    aCenterAttributeId = SketchPlugin_Circle::CENTER_ID();
+
+  if (aCenterAttributeId.empty())
+    return aFeature;
+
+  aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
+  // update fillet arc: make the arc correct for sure, so, it is not needed to process
+  // the "attribute updated"
+  // by arc; moreover, it may cause cyclicity in hte mechanism of updater
+  bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
+
+  aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue(
+                SketchPlugin_Arc::ARC_TYPE_CENTER_START_END());
+
+  fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
+                theBaseFeature->attribute(aCenterAttributeId));
+  fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint);
+  fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPoint);
+
+  fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
+                theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
+
+  /// fill referersed state of created arc as it is on the base arc
+  if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
+    bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
+    aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed);
+  }
+  aFeature->execute(); // to obtain result
+  aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
+
+  return aFeature;
+}
+
+FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
+                                               const AttributePtr& theFirstAttribute,
+                                               const AttributePtr& theSecondAttribute)
+{
+  FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
+  AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+  aRefAttr->setAttr(theFirstAttribute);
+
+  aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
+  aRefAttr->setAttr(theSecondAttribute);
+
+#ifdef DEBUG_TRIM
+  std::cout << "<createConstraint to attribute> :"
+            << "first attribute - " << theFirstAttribute->id()
+            << "second attribute - " << theSecondAttribute->id()
+            << std::endl;
+#endif
+
+  return aConstraint;
+}
+
+FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
+                                               const AttributePtr& theFirstAttribute,
+                                               const ObjectPtr& theSecondObject)
+{
+  FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
+  AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
+  aRefAttr->setAttr(theFirstAttribute);
+
+  aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+                                 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
+  aRefAttr->setObject(theSecondObject);
+
+#ifdef DEBUG_TRIM
+  std::cout << "<createConstraint to attribute> :"
+            << "first attribute - " << theFirstAttribute->id()
+            << "second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
+            << std::endl;
+#endif
+
+  return aConstraint;
+}
+
+  //
 //FeaturePtr SketchPlugin_Trim::createConstraintForObjects(
 //                                                    const std::string& theConstraintId,
 //                                                    const ObjectPtr& theFirstObject,
@@ -1432,7 +1690,7 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //                              std::dynamic_pointer_cast<SketchPlugin_ConstraintLength>(*anIt);
 //      if (aLenghtFeature.get()) {
 //        std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
-//            ModelAPI_AttributeDouble>(aLenghtFeature->attribute(SketchPlugin_Constraint::VALUE()));
+//            ModelAPI_AttributeDouble>(aLenghtFeature->attribute(SketchPlugin_Trim::BASE_OBJECT()));
 //        double aValue;
 //        if (aLenghtFeature->computeLenghtValue(aValue) && aValueAttr.get())
 //          aValueAttr->setValue(aValue);
@@ -1440,23 +1698,23 @@ AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
 //    }
 //  }
 //}
-//
-//std::shared_ptr<ModelAPI_Result> SketchPlugin_Trim::getFeatureResult(
-//                                    const std::shared_ptr<ModelAPI_Feature>& theFeature)
-//{
-//  std::shared_ptr<ModelAPI_Result> aResult;
-//
-//  std::string aFeatureKind = theFeature->getKind();
-//  if (aFeatureKind == SketchPlugin_Line::ID())
-//    aResult = theFeature->firstResult();
-//  else if (aFeatureKind == SketchPlugin_Arc::ID())
-//    aResult = theFeature->lastResult();
-//  else if (aFeatureKind == SketchPlugin_Circle::ID())
-//    aResult = theFeature->lastResult();
-//
-//  return aResult;
-//}
-//
+
+std::shared_ptr<ModelAPI_Result> SketchPlugin_Trim::getFeatureResult(
+                                    const std::shared_ptr<ModelAPI_Feature>& theFeature)
+{
+  std::shared_ptr<ModelAPI_Result> aResult;
+
+  std::string aFeatureKind = theFeature->getKind();
+  if (aFeatureKind == SketchPlugin_Line::ID())
+    aResult = theFeature->firstResult();
+  else if (aFeatureKind == SketchPlugin_Arc::ID())
+    aResult = theFeature->lastResult();
+  else if (aFeatureKind == SketchPlugin_Circle::ID())
+    aResult = theFeature->lastResult();
+
+  return aResult;
+}
+
 //std::set<std::shared_ptr<ModelAPI_Attribute> > SketchPlugin_Trim::getEdgeAttributes(
 //                                           const std::shared_ptr<ModelAPI_Feature>& theFeature)
 //{
@@ -1547,15 +1805,18 @@ bool SketchPlugin_Trim::useGraphicIntersection() const
 }
 
 //********************************************************************
-#include <SketchPlugin_Point.h>
 void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject)
 {
+  PointToRefsMap aPointsInfo;
+
   std::set<std::shared_ptr<GeomAPI_Shape> > aShapes;
-  std::map<std::shared_ptr<GeomDataAPI_Point2D>, std::shared_ptr<GeomAPI_Pnt> > aPointToAttributes;
-   std::map<std::shared_ptr<GeomAPI_Pnt>,
-                              std::list< std::shared_ptr<ModelAPI_Object> > > aPointToObjects;
+  //std::map<AttributePoint2DPtr, std::shared_ptr<GeomAPI_Pnt> > aPointToAttributes;
+  std::map<std::shared_ptr<GeomAPI_Pnt>,
+                           std::list< AttributePoint2DPtr > > aPointToAttributes;
+  std::map<std::shared_ptr<GeomAPI_Pnt>,
+                           std::list< ObjectPtr > > aPointToObjects;
 
-  std::set<std::shared_ptr<GeomDataAPI_Point2D> > aRefAttributes;
+  std::set<AttributePoint2DPtr > aRefAttributes;
   // current feature
   FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
   std::set<ResultPtr> anEdgeShapes;
@@ -1565,7 +1826,7 @@ void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject)
     GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape();
 
     // coincidences to the feature
-    std::list<std::shared_ptr<GeomAPI_Pnt> > aPoints;
+    //std::list<std::shared_ptr<GeomAPI_Pnt> > aPoints;
 
     ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(),
                          aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
@@ -1580,8 +1841,9 @@ void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject)
     std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
         aData->attribute(SketchPlugin_Sketch::NORM_ID()));
     std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
+
     ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
-                                                aX->dir(), aY, aPoints, aPointToAttributes);
+                                                aX->dir(), aY, aPointsInfo);//aPoints, aPointToAttributes);
 
     // intersection points
     if (useGraphicIntersection()) {
@@ -1591,13 +1853,49 @@ void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject)
         if (aFeature.get())
           aFeatures.push_back(aFeature);
       }
-      ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPoints,
-                                                       aPointToObjects);
+      ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures,// aPoints,
+                                                       aPointsInfo);
     }
-    GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPoints, aShapes);
+    GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes);
+
   }
+
+  myObjectToPoints[theObject] = aPointsInfo;
   myCashedShapes[theObject] = aShapes;
-  myCashedReferences[theObject] = aPointToAttributes;
-  if (useGraphicIntersection())
-    myCashedObjects[theObject] = aPointToObjects;
+  //myCashedReferences[theObject] = aPointToAttributes;
+  //if (useGraphicIntersection())
+  //  myCashedObjects[theObject] = aPointToObjects;
+}
+
+//********************************************************************
+void SketchPlugin_Trim::attributeChanged(const std::string& theID)
+{
+  //data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId());
+  if (theID == SketchPlugin_Trim::BASE_OBJECT()) {
+    bool isValidAttribute = false;
+    // feature for trim
+    AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+                                             data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
+    ObjectPtr aBaseObject = aBaseObjectAttr->value();
+    if (aBaseObject.get()) {
+      FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
+      // point on feature
+      AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                               data()->attribute(ENTITY_POINT()));
+      std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
+      std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(), anAttributePnt2d->y());
+
+      if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
+        fillObjectShapes(aBaseObject);
+
+      const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
+      isValidAttribute = !aShapes.empty();
+
+      if (!isValidAttribute) {
+        bool aWasBlocked = data()->blockSendAttributeUpdated(true);
+        aBaseObjectAttr->setValue(ObjectPtr());
+        data()->blockSendAttributeUpdated(aWasBlocked);
+      }
+    }
+  }
 }
index bebc8b8c2c103596e4bca473d15c69fa479616b9..a1e1387f7ada61121fb39acb1739570bf7c8d327 100644 (file)
@@ -47,7 +47,7 @@ typedef std::pair<std::string, std::shared_ptr<GeomDataAPI_Point2D> > IdToPointP
  *  SketchPlugin_Constraint::ENTITY_A() and SketchPlugin_Constraint::ENTITY_B() for the points of split;
  *
  */
-class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
+class SketchPlugin_Trim : public SketchPlugin_Feature, public GeomAPI_IPresentable
 {
  public:
   /// Split constraint kind
@@ -63,6 +63,13 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
     return MY_KIND;
   }
 
+  /// The value parameter for the constraint
+  inline static const std::string& BASE_OBJECT()
+  {
+    static const std::string MY_CONSTRAINT_BASE_OBJECT("BaseObject");
+    return MY_CONSTRAINT_BASE_OBJECT;
+  }
+
   /// Start 2D point of the split segment
   inline static const std::string& ENTITY_POINT()
   {
@@ -90,6 +97,10 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
   /// This is necessary to perform execute only by apply the feature
   SKETCHPLUGIN_EXPORT virtual bool isPreviewNeeded() const { return false; }
 
+  /// Called on change of any argument-attribute of this object
+  /// \param theID identifier of changed attribute
+  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
   /// \brief Use plugin manager for features creation
   SketchPlugin_Trim();
 
@@ -101,16 +112,19 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
   /// Returns the AIS preview
   SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious);
 
-//private:
-//  /// Returns geom point attribute of the feature bounds. It processes line or arc.
-//  /// For circle feature, the result attributes are null
-//  /// \param theFeature a source feature
-//  /// \param theStartPointAttr an out attribute to start point
-//  /// \param theStartPointAttr an out attribute to end point
-//  void getFeaturePoints(const FeaturePtr& theFeature,
-//                        std::shared_ptr<GeomDataAPI_Point2D>& theStartPointAttr,
-//                        std::shared_ptr<GeomDataAPI_Point2D>& theEndPointAttr);
-//
+  /// Moves the feature : Empty
+  SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY) {};
+
+private:
+  /// Returns geom point attribute of the feature bounds. It processes line or arc.
+  /// For circle feature, the result attributes are null
+  /// \param theFeature a source feature
+  /// \param theStartPointAttr an out attribute to start point
+  /// \param theStartPointAttr an out attribute to end point
+  void getFeaturePoints(const FeaturePtr& theFeature,
+                        std::shared_ptr<GeomDataAPI_Point2D>& theStartPointAttr,
+                        std::shared_ptr<GeomDataAPI_Point2D>& theEndPointAttr);
+
 //  FeaturePtr createCoincidenceConstraint(const AttributePtr& theFirstAttribute,
 //                                         const AttributePtr& theSecondAttribute);
 //
@@ -118,31 +132,31 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
 //  /// \param theAttribute an attribute
 //  /// \param geom point 2D or NULL
 //  std::shared_ptr<GeomDataAPI_Point2D> getPointOfRefAttr(const AttributePtr& theAttribute);
-//
-//  /// Obtains those constraints of the feature that should be modified. output maps contain
-//  /// point of coincidence and attribute id to be modified after split
-//  /// \param theFeaturesToDelete [out] constrains that will be deleted after split
-//  /// \param theFeaturesToUpdate [out] constrains that will be updated after split
-//  /// \param theTangentFeatures  [out] tangent feature to be connected to new feature
-//  /// \param theCoincidenceToFeature [out] coincidence to feature to be connected to new feature
-//  /// \param theCoincidenceToPoint [out] coincidence to point be connected to new feature
-//  void getConstraints(std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete,
-//              std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToUpdate,
-//              std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theTangentFeatures,
-//              std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToFeature/*,
-//              std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToPoint*/);
-//
-//  /// Obtains references to feature point attributes and to feature,
-//  /// e.g. for feature line: 1st container is
-//  ///             <1st line point, list<entity_a in distance, entity_b in parallel> >
-//  ///             <2nd line point, list<> >
-//  ///      for feature circle 2nd container is <entity_a in Radius, entity_b in equal, ...>
-//  /// \param theFeature an investigated feature
-//  /// \param theRefs a container of list of referenced attributes
-//  void getRefAttributes(const FeaturePtr& theFeature,
-//                        std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
-//                        std::list<AttributePtr>& theRefsToFeature);
-//
+
+  /// Obtains those constraints of the feature that should be modified. output maps contain
+  /// point of coincidence and attribute id to be modified after split
+  /// \param theFeaturesToDelete [out] constrains that will be deleted after split
+  /// \param theFeaturesToUpdate [out] constrains that will be updated after split
+  /// \param theTangentFeatures  [out] tangent feature to be connected to new feature
+  /// \param theCoincidenceToFeature [out] coincidence to feature to be connected to new feature
+  /// \param theCoincidenceToPoint [out] coincidence to point be connected to new feature
+  void getConstraints(std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete,
+              std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToUpdate);//,
+              //std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theTangentFeatures,
+              //std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToFeature/*,
+              //std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToPoint*/);
+
+  /// Obtains references to feature point attributes and to feature,
+  /// e.g. for feature line: 1st container is
+  ///             <1st line point, list<entity_a in distance, entity_b in parallel> >
+  ///             <2nd line point, list<> >
+  ///      for feature circle 2nd container is <entity_a in Radius, entity_b in equal, ...>
+  /// \param theFeature an investigated feature
+  /// \param theRefs a container of list of referenced attributes
+  void getRefAttributes(const FeaturePtr& theFeature,
+                        std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
+                        std::list<AttributePtr>& theRefsToFeature);
+
 //  /// Move coincidence constraint from feature to point if it is found
 //  /// \param theCoincidenceToFeature coincidence to feature to be connected to new feature
 //  /// \param theFurtherCoincidences a list of points where coincidences will be build
@@ -161,22 +175,21 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
 //  void updateTangentConstraintsToFeature(
 //              const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theTangentFeatures,
 //              const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
-//
-//
-//  /// Move constraints from base feature to given feature
-//  /// \param theFeature a base feature
-//  /// \param theRefsToFeature list of attributes referenced to base feature
-//  void updateRefFeatureConstraints(const std::shared_ptr<ModelAPI_Result>& theFeatureBaseResult,
-//                                   const std::list<AttributePtr>& theRefsToFeature);
-//
-//  /// Move constraints from attribute of base feature to attribute after modification
-//  /// \param theBaseRefAttributes container of references to the attributes of base feature
-//  /// \param theModifiedAttributes container of attributes placed instead of base attributes
-//  /// at the same place
-//  void updateRefAttConstraints(
-//               const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
-//               const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes);
-//
+
+  /// Move constraints from base feature to given feature
+  /// \param theFeature a base feature
+  /// \param theRefsToFeature list of attributes referenced to base feature
+  void updateRefFeatureConstraints(const std::shared_ptr<ModelAPI_Result>& theFeatureBaseResult,
+                                   const std::list<AttributePtr>& theRefsToFeature);
+
+  /// Move constraints from attribute of base feature to attribute after modification
+  /// \param theBaseRefAttributes container of references to the attributes of base feature
+  /// \param theModifiedAttributes container of attributes placed instead of base attributes
+  /// at the same place
+  void updateRefAttConstraints(
+               const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
+               const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes);
+
 //  /// Make the base object is splitted by the point attributes
 //  /// \param theSplitFeature a result split feature
 //  /// \param theBeforeFeature a feature between start point and the 1st point of split feature
@@ -204,20 +217,22 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
 //                std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
 //                std::set<std::shared_ptr<ModelAPI_Feature>>& theCreatedFeatures,
 //                std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
-//
-//  /// Make the base object is splitted by the point attributes
-//  /// \param theSplitFeature a result split feature
-//  /// \param theBeforeFeature a feature between start point and the 1st point of split feature
-//  /// \param theAfterFeature a feature between last point of split feature and the end point
-//  /// \param thePoints a list of points where coincidences will be build
-//  /// \param theCreatedFeatures a container of created features
-//  void splitCircle(std::shared_ptr<ModelAPI_Feature>& theSplitFeature,
-//                   std::shared_ptr<ModelAPI_Feature>& theBeforeFeature,
-//                   std::shared_ptr<ModelAPI_Feature>& theAfterFeature,
-//                   std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
-//                   std::set<std::shared_ptr<ModelAPI_Feature>>& theCreatedFeatures,
-//                   std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
-//
+
+  /// Make the base object is splitted by the point attributes
+  /// \param theSplitFeature a result split feature
+  /// \param theBeforeFeature a feature between start point and the 1st point of split feature
+  /// \param theAfterFeature a feature between last point of split feature and the end point
+  /// \param thePoints a list of points where coincidences will be build
+  /// \param theCreatedFeatures a container of created features
+  void trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+                  const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
+                  /*std::shared_ptr<ModelAPI_Feature>& theSplitFeature,
+                  std::shared_ptr<ModelAPI_Feature>& theBeforeFeature,
+                  std::shared_ptr<ModelAPI_Feature>& theAfterFeature,*/
+                  std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
+                  std::set<std::shared_ptr<ModelAPI_Feature>>& theCreatedFeatures,
+                  std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
+
 //  /// Correct the first and the second point to provide condition that the first is closer to
 //  /// the start point and the second point - to the last end of current segment. To rearrange
 //  /// them if this condition is not satisfied.
@@ -225,11 +240,11 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
 //  /// \param theEndPointAttr an end point of a segment
 //  /// \param theFirstPointAttr a start point of a segment
 //  /// \param theSecondPointAttr an end point of a segment
-//  void arrangePointsOnLine(const std::shared_ptr<GeomDataAPI_Point2D>& theStartPointAttr,
-//                           const std::shared_ptr<GeomDataAPI_Point2D>& theEndPointAttr,
-//                           std::shared_ptr<GeomDataAPI_Point2D>& theFirstPointAttr,
-//                           std::shared_ptr<GeomDataAPI_Point2D>& theSecondPointAttr) const;
-//
+  void arrangePointsOnLine(const std::shared_ptr<GeomDataAPI_Point2D>& theStartPointAttr,
+                           const std::shared_ptr<GeomDataAPI_Point2D>& theEndPointAttr,
+                           std::shared_ptr<GeomDataAPI_Point2D>& theFirstPointAttr,
+                           std::shared_ptr<GeomDataAPI_Point2D>& theSecondPointAttr) const;
+
 //  /// Correct the first and the second point to provide condition that the first is closer to
 //  /// the start point and the second point - to the last end of current segment. To rearrange
 //  /// them if this condition is not satisfied.
@@ -243,13 +258,19 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
 //                          const std::shared_ptr<GeomDataAPI_Point2D>& theEndPointAttr,
 //                          std::shared_ptr<GeomDataAPI_Point2D>& theFirstPointAttr,
 //                          std::shared_ptr<GeomDataAPI_Point2D>& theSecondPointAttr) const;
-//
-//  /// Fill attribute by value of another attribute. It processes only Point 2D attributes.
-//  /// \param theModifiedAttribute an attribute of GeomDataAPI_Point2D on feature to be modified
-//  /// \param theSourceAttribute an attribute of GeomDataAPI_Point2D to obtain data
-//  void fillAttribute(const AttributePtr& theModifiedAttribute,
-//                     const AttributePtr& theSourceAttribute);
-//
+
+  /// Fill attribute by value of another attribute. It processes only Point 2D attributes.
+  /// \param theModifiedAttribute an attribute of GeomDataAPI_Point2D on feature to be modified
+  /// \param theSourceAttribute an attribute of GeomDataAPI_Point2D to obtain data
+  void fillAttribute(const AttributePtr& theModifiedAttribute,
+                     const AttributePtr& theSourceAttribute);
+
+  /// Fill attribute by value of another attribute. It processes only Point 2D attributes.
+  /// \param theModifiedAttribute an attribute of GeomDataAPI_Point2D on feature to be modified
+  /// \param thePoint a point value
+  void fillPointAttribute(const AttributePtr& theModifiedAttribute,
+                          const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
+
 //  /// Creates a line feature filled by center of base feature and given points
 //  /// \param theBaseFeature another arc feature
 //  /// \param theFirstAttribute an attribute with coordinates for the start point
@@ -258,22 +279,30 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
 //                               const AttributePtr& theFirstPointAttr,
 //                               const AttributePtr& theSecondPointAttr);
 //
-//  /// Creates an arc feature filled by center of base feature and given points
-//  /// \param theBaseFeature another arc feature
-//  /// \param theFirstAttribute an attribute with coordinates for the start point
-//  /// \param theSecondAttribute an attribute with coordinates for the end point
-//  FeaturePtr createArcFeature(const FeaturePtr& theBaseFeature,
-//                              const AttributePtr& theFirstPointAttr,
-//                              const AttributePtr& theSecondPointAttr);
-//
-//  /// Add feature coincidence constraint between given attributes
-//  /// \param theConstraintId a constraint index
-//  /// \param theFirstAttribute an attribute of further coincidence
-//  /// \param theSecondAttribute an attribute of further coincidence
-//  std::shared_ptr<ModelAPI_Feature> createConstraint(const std::string& theConstraintId,
-//                        const std::shared_ptr<ModelAPI_Attribute>& theFirstAttribute,
-//                        const std::shared_ptr<ModelAPI_Attribute>& theSecondAttribute);
-//
+  /// Creates an arc feature filled by center of base feature and given points
+  /// \param theBaseFeature another arc feature
+  /// \param theFirstAttribute an attribute with coordinates for the start point
+  /// \param theSecondAttribute an attribute with coordinates for the end point
+  FeaturePtr createArcFeature(const FeaturePtr& theBaseFeature,
+                              const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
+                              const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint);
+
+  /// Add feature coincidence constraint between given attributes
+  /// \param theConstraintId a constraint index
+  /// \param theFirstAttribute an attribute of further coincidence
+  /// \param theSecondAttribute an attribute of further coincidence
+  std::shared_ptr<ModelAPI_Feature> createConstraint(const std::string& theConstraintId,
+                        const std::shared_ptr<ModelAPI_Attribute>& theFirstAttribute,
+                        const std::shared_ptr<ModelAPI_Attribute>& theSecondAttribute);
+
+  /// Add feature coincidence constraint between given attributes
+  /// \param theConstraintId a constraint index
+  /// \param theFirstAttribute an attribute of further coincidence
+  /// \param theSecondObject an object of further coincidence
+  std::shared_ptr<ModelAPI_Feature> createConstraint(const std::string& theConstraintId,
+                        const std::shared_ptr<ModelAPI_Attribute>& theFirstAttribute,
+                        const std::shared_ptr<ModelAPI_Object>& theSecondObject);
+
 //  /// Add feature coincidence constraint between given attributes
 //  /// \param theConstraintId a constraint index
 //  /// \param theFirstAttribute an attribute of further coincidence
@@ -286,12 +315,12 @@ class SketchPlugin_Trim : public SketchPlugin_ConstraintBase
 //  /// \param theFeaturesToUpdate a constraint index
 //  void updateFeaturesAfterSplit(const std::set<FeaturePtr>& theFeaturesToUpdate);
 //
-//  /// Result result of the feature to build constraint with. For arc, circle it is an edge result.
-//  /// \param theFeature a feature
-//  /// \return result object
-//  std::shared_ptr<ModelAPI_Result> getFeatureResult(
-//                                    const std::shared_ptr<ModelAPI_Feature>& theFeature);
-//
+  /// Result result of the feature to build constraint with. For arc, circle it is an edge result.
+  /// \param theFeature a feature
+  /// \return result object
+  std::shared_ptr<ModelAPI_Result> getFeatureResult(
+                                    const std::shared_ptr<ModelAPI_Feature>& theFeature);
+
 //  /// Returns attributes of the feature, used in edge build, for arc it is end and start points
 //  /// \param theFeature a feature
 //  /// \return container of attributes
@@ -311,17 +340,24 @@ private:
 
   void fillObjectShapes(const ObjectPtr& theObject);
 
+  void findShapePoints(std::shared_ptr<GeomAPI_Pnt>& aStartPoint,
+                       std::shared_ptr<GeomAPI_Pnt>& aLastPoint);
+
+  std::shared_ptr<GeomAPI_Pnt2d> convertPoint(const std::shared_ptr<GeomAPI_Pnt>& thePoint);
+
 private:
   //std::shared_ptr<ModuleBase_ViewerPrs> myCurrentSubShape;
   std::map<ObjectPtr, std::set<GeomShapePtr> > myCashedShapes;
 
-  typedef std::map<std::shared_ptr<GeomDataAPI_Point2D>,
-                   std::shared_ptr<GeomAPI_Pnt> > PntToAttributesMap;
-  std::map<ObjectPtr, PntToAttributesMap> myCashedReferences;
+  //typedef std::map<std::shared_ptr<GeomDataAPI_Point2D>,
+  //                 std::shared_ptr<GeomAPI_Pnt> > PntToAttributesMap;
+  //std::map<ObjectPtr, PntToAttributesMap> myCashedReferences;
 
   typedef std::map<std::shared_ptr<GeomAPI_Pnt>,
-             std::list< std::shared_ptr<ModelAPI_Object> > > PntToObjectsMap;
-  std::map<ObjectPtr, PntToObjectsMap> myCashedObjects;
+                   std::pair<std::list<std::shared_ptr<GeomDataAPI_Point2D> >,
+                             std::list<std::shared_ptr<ModelAPI_Object> > > > PointToRefsMap;
+
+  std::map<ObjectPtr, PointToRefsMap> myObjectToPoints;
 };
 
 #endif
index 5884fa6bb4566ac462f6c5be3a5cb1c083eb06f6..ff1689e16ff2ca945b35fa553939abf43112e95d 100755 (executable)
@@ -940,27 +940,20 @@ bool SketchPlugin_SplitValidator::isValid(const AttributePtr& theAttribute,
         aData->attribute(SketchPlugin_Sketch::NORM_ID()));
     std::shared_ptr<GeomAPI_Dir> aDirY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
 
-    std::list<std::shared_ptr<GeomAPI_Pnt> > aPoints;
-    std::map<std::shared_ptr<GeomDataAPI_Point2D>, std::shared_ptr<GeomAPI_Pnt> >
-      aPointToAttributes;
+    typedef std::map<std::shared_ptr<GeomAPI_Pnt>,
+                     std::pair<std::list<std::shared_ptr<GeomDataAPI_Point2D> >,
+                               std::list<std::shared_ptr<ModelAPI_Object> > > > PointToRefsMap;
+    PointToRefsMap aPointsInfo;
+
+    //std::list<std::shared_ptr<GeomAPI_Pnt> > aPoints;
+    //std::map<std::shared_ptr<GeomDataAPI_Point2D>, std::shared_ptr<GeomAPI_Pnt> >
+    //  aPointToAttributes;
+    //std::map<std::shared_ptr<GeomAPI_Pnt>,
+    //                       std::list< std::shared_ptr<GeomDataAPI_Point2D> > > aPointToAttributes;
     ModelGeomAlgo_Point2D::getPointsInsideShape(anAttrShape, aRefAttributes, aC->pnt(),
-                                                aX->dir(), aDirY, aPoints, aPointToAttributes);
-
-    if (theArguments.size() > 0) { // use graphic intersection
-      // intersection points
-      //std::shared_ptr<ModelAPI_CompositeFeature> aCompositeFeature(aSketch);
-       std::map<std::shared_ptr<GeomAPI_Pnt>,
-                              std::list< std::shared_ptr<ModelAPI_Object> > > aPointToObjects;
-      std::list<FeaturePtr> aFeatures;
-      for (int i = 0; i < aSketch->numberOfSubs(); i++) {
-        FeaturePtr aFeature = aSketch->subFeature(i);
-        if (aFeature.get())
-          aFeatures.push_back(aFeature);
-      }
-      ModelGeomAlgo_Point2D::getPointsIntersectedShape(aSFeature, aFeatures, aPoints,
-                                                       aPointToObjects);
-    }
-    int aCoincidentToFeature = (int)aPoints.size();
+                                                aX->dir(), aDirY, aPointsInfo);//aPoints, aPointToAttributes);
+
+    int aCoincidentToFeature = (int)aPointsInfo.size();//aPoints.size();
     if (aKind == SketchPlugin_Circle::ID())
       aValid = aCoincidentToFeature >= 2;
     else
diff --git a/src/SketchPlugin/Test/TestTrimCircle.py b/src/SketchPlugin/Test/TestTrimCircle.py
new file mode 100644 (file)
index 0000000..aecbb4e
--- /dev/null
@@ -0,0 +1,129 @@
+from salome.shaper import model
+
+from ModelAPI import *
+from GeomDataAPI import *
+from salome.shaper import geom
+import math
+
+TOLERANCE = 1.e-7
+
+SketchPointId = 'SketchPoint'
+SketchLineId = 'SketchLine'
+SketchArcId = 'SketchArc'
+SketchCircleId = 'SketchCircle'
+SketchConstraintCoincidenceId = 'SketchConstraintCoincidence'
+SketchConstraintParallelId = 'SketchConstraintParallel'
+SketchConstraintTangentId = 'SketchConstraintTangent'
+SketchConstraintEqualId = 'SketchConstraintEqual'
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+# Test1:begin split on circle with coincident point and intersection line : smaller part
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1_1 = Sketch_1.addCircle(50, 50, 20)
+SketchLine_1_1 = Sketch_1.addLine(50, 30, 100, 30)
+SketchLine_1_2 = Sketch_1.addLine(60, 50, 100, 30)
+
+SketchConstraintCoincidence_1_1 = Sketch_1.setCoincident(SketchLine_1_1.startPoint(), SketchCircle_1_1.results()[1])
+SketchConstraintCoincidence_1_2 = Sketch_1.setCoincident(SketchLine_1_1.endPoint(), SketchLine_1_2.endPoint())
+GeomPoint_1_1 = geom.Pnt2d(60, 35)
+
+#check number of features before trim
+Sketch_1_feature = featureToCompositeFeature(Sketch_1.feature())
+idList_before_1 = []
+for index in range(Sketch_1_feature.numberOfSubs()):
+  idList_before_1.append(Sketch_1_feature.subFeature(index).getKind())
+assert(idList_before_1.count(SketchCircleId) == 1)
+assert(idList_before_1.count(SketchArcId) == 0)
+assert(idList_before_1.count(SketchLineId) == 2)
+assert(idList_before_1.count(SketchConstraintCoincidenceId) == 2)
+
+#perform trim
+SketchTrim_1_1 = Sketch_1.addTrim(SketchCircle_1_1, GeomPoint_1_1)
+SketchTrim_1_1.execute()
+model.do()
+
+#check number of features after trim
+SketchFeatures = featureToCompositeFeature(Sketch_1.feature())
+idList_after_1 = []
+for SubIndex in range(SketchFeatures.numberOfSubs()):
+    SubFeature = SketchFeatures.subFeature(SubIndex)
+    idList_after_1.append(SubFeature.getKind())
+    if SubFeature.getKind() == SketchArcId:
+      ArcFeature_1 = SubFeature
+
+
+assert(idList_after_1.count(SketchCircleId) == 0)
+assert(idList_after_1.count(SketchArcId) == 1)
+assert(idList_after_1.count(SketchLineId) == 2)
+assert(idList_after_1.count(SketchConstraintCoincidenceId) == 3)
+
+#test created arc: it is not inversed, has coincidence to end line point
+anInversed_1 = ArcFeature_1.boolean("InversedArc").value()
+assert(anInversed_1 == False)
+ArcPoint_1 = geomDataAPI_Point2D(ArcFeature_1.attribute("ArcEndPoint"))
+LinePoint_1 = geomDataAPI_Point2D(SketchLine_1_1.startPoint())
+aDistance_1 = math.hypot(LinePoint_1.x() - ArcPoint_1.x(), LinePoint_1.y() - ArcPoint_1.y())
+#print "Distance " + repr(aDistance)
+assert (math.fabs(aDistance_1) <= TOLERANCE)
+# Test1:end
+
+
+# Test2: split on circle with coincident point and intersection line : largest part
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+move_test_delta_y = 100
+move_test_delta_x = 0
+SketchCircle_2_1 = Sketch_2.addCircle(50, 50 + move_test_delta_y, 20)
+SketchLine_2_1 = Sketch_2.addLine(50, 30 + move_test_delta_y, 100, 30 + move_test_delta_y)
+SketchLine_2_2 = Sketch_2.addLine(60, 50 + move_test_delta_y, 100, 30 + move_test_delta_y)
+
+SketchConstraintCoincidence_2_1 = Sketch_2.setCoincident(SketchLine_2_1.startPoint(), SketchCircle_2_1.results()[1])
+SketchConstraintCoincidence_2_2 = Sketch_2.setCoincident(SketchLine_2_1.endPoint(), SketchLine_2_2.endPoint())
+GeomPoint_2_1 = geom.Pnt2d(50, 75 + move_test_delta_y)
+
+#check number of features before trim
+Sketch_2_feature = featureToCompositeFeature(Sketch_2.feature())
+idList_before_2 = []
+for index in range(Sketch_2_feature.numberOfSubs()):
+  idList_before_2.append(Sketch_2_feature.subFeature(index).getKind())
+assert(idList_before_2.count(SketchCircleId) == 1)
+assert(idList_before_2.count(SketchArcId) == 0)
+assert(idList_before_2.count(SketchLineId) == 2)
+assert(idList_before_2.count(SketchConstraintCoincidenceId) == 2)
+
+#perform trim
+SketchTrim_2_1 = Sketch_2.addTrim(SketchCircle_2_1, GeomPoint_2_1)
+SketchTrim_2_1.execute()
+model.do()
+
+#check number of features after trim
+SketchFeatures = featureToCompositeFeature(Sketch_2.feature())
+idList_after_2 = []
+for SubIndex in range(SketchFeatures.numberOfSubs()):
+    SubFeature = SketchFeatures.subFeature(SubIndex)
+    idList_after_2.append(SubFeature.getKind())
+    if SubFeature.getKind() == SketchArcId:
+      ArcFeature_2 = SubFeature
+
+
+assert(idList_after_2.count(SketchCircleId) == 0)
+assert(idList_after_2.count(SketchArcId) == 1)
+assert(idList_after_2.count(SketchLineId) == 2)
+assert(idList_after_2.count(SketchConstraintCoincidenceId) == 3)
+
+#test created arc : it is not inversed, has coincidence to start line point
+anInversed_2 = ArcFeature_2.boolean("InversedArc").value()
+assert(anInversed_2 == False)
+ArcPoint_2 = geomDataAPI_Point2D(ArcFeature_2.attribute("ArcStartPoint"))
+LinePoint_2 = geomDataAPI_Point2D(SketchLine_2_1.startPoint())
+aDistance_2 = math.hypot(LinePoint_2.x() - ArcPoint_2.x(), LinePoint_2.y() - ArcPoint_2.y())
+#print "Distance " + repr(aDistance_2)
+assert (math.fabs(aDistance_2) <= TOLERANCE)
+# Test2:end
+
+model.end()
+
+#assert(model.checkPythonDump())
index 265d61aa6d37bed6e7d16cc638cb03ecfd5d1d50..5c33b28cce0e75d3788ee95e376300adad4a5f70 100644 (file)
                tooltip="Trim selected segment arc or circle on intersection points nearest to the graphic selection"
                icon="icons/Sketch/trim.png">
         <sketch_feature_point_selector
-            id="ConstraintValue"
+            id="BaseObject"
             label="Split feature"
             tooltip="Select feature for split"
             shape_types="edge"
             use_external="false"
             use_graphic_intersection="true">
-          <validator id="SketchPlugin_SplitValidator" parameters="use_graphic_intersection"/>
+          <!--<validator id="SketchPlugin_SplitValidator" parameters="use_graphic_intersection"/> -->
         </sketch_feature_point_selector>
         <validator id="PartSet_SplitSelection"/>
       </feature>