]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge branch 'master' of newgeom:newgeom
authorvsv <vitaly.smetannikov@opencascade.com>
Mon, 2 Jun 2014 05:41:50 +0000 (09:41 +0400)
committervsv <vitaly.smetannikov@opencascade.com>
Mon, 2 Jun 2014 05:41:50 +0000 (09:41 +0400)
55 files changed:
src/GeomAPI/CMakeLists.txt
src/GeomAPI/GeomAPI_Dir.cpp
src/GeomAPI/GeomAPI_Dir.h
src/GeomAPI/GeomAPI_Lin.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_Lin.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_Lin2d.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_Lin2d.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_Pnt.cpp
src/GeomAPI/GeomAPI_Pnt.h
src/GeomAPI/GeomAPI_Pnt2d.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_Pnt2d.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_XY.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_XY.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_XYZ.cpp
src/GeomAPI/GeomAPI_XYZ.h
src/GeomData/GeomData_Dir.cpp
src/GeomData/GeomData_Dir.h
src/GeomData/GeomData_Point.cpp
src/GeomData/GeomData_Point.h
src/GeomData/GeomData_Point2D.cpp
src/GeomData/GeomData_Point2D.h
src/GeomDataAPI/GeomDataAPI_Dir.h
src/GeomDataAPI/GeomDataAPI_Point.h
src/GeomDataAPI/GeomDataAPI_Point2D.h
src/ModuleBase/ModuleBase_IOperation.cpp
src/ModuleBase/ModuleBase_IOperation.h
src/ModuleBase/ModuleBase_Operation.cpp
src/ModuleBase/ModuleBase_Operation.h
src/ModuleBase/ModuleBase_WidgetPoint2D.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_OperationEditLine.cpp
src/PartSet/PartSet_OperationSketch.cpp
src/PartSet/PartSet_OperationSketchBase.cpp
src/PartSet/PartSet_OperationSketchBase.h
src/PartSet/PartSet_OperationSketchLine.cpp
src/PartSet/PartSet_OperationSketchLine.h
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_ConstraintDiameter.cpp [deleted file]
src/SketchPlugin/SketchPlugin_ConstraintDiameter.h [deleted file]
src/SketchPlugin/SketchPlugin_ConstraintLength.cpp [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintLength.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintRadius.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_Plugin.cpp
src/SketchPlugin/plugin-Sketch.xml
src/SketchSolver/SketchSolver_Constraint.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.h
src/XGUI/XGUI_DocumentDataModel.cpp
src/XGUI/XGUI_ObjectsBrowser.cpp
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_Tools.cpp
src/XGUI/XGUI_Tools.h
src/XGUI/XGUI_ViewWindow.cpp
src/XGUI/XGUI_Workshop.cpp

index 142a02bb44b1fd336663c5fb9bd773481d7b6cb4..ad741d302d83c67fe65adae20fc93ff949e96e45 100644 (file)
@@ -7,8 +7,12 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
 SET(PROJECT_HEADERS
     GeomAPI.h
     GeomAPI_Interface.h
+    GeomAPI_XY.h
     GeomAPI_XYZ.h
     GeomAPI_Pnt.h
+    GeomAPI_Pnt2d.h
+    GeomAPI_Lin.h
+    GeomAPI_Lin2d.h
     GeomAPI_Dir.h
     GeomAPI_Pln.h
     GeomAPI_Shape.h
@@ -16,8 +20,12 @@ SET(PROJECT_HEADERS
 
 SET(PROJECT_SOURCES
     GeomAPI_Interface.cpp
+    GeomAPI_XY.cpp
     GeomAPI_XYZ.cpp
     GeomAPI_Pnt.cpp
+    GeomAPI_Pnt2d.cpp
+    GeomAPI_Lin.cpp
+    GeomAPI_Lin2d.cpp
     GeomAPI_Dir.cpp
     GeomAPI_Pln.cpp
     GeomAPI_Shape.cpp
@@ -35,7 +43,7 @@ INCLUDE_DIRECTORIES(
   ${CAS_INCLUDE_DIRS}
 )
 
-TARGET_LINK_LIBRARIES(GeomAPI ${PROJECT_LIBRARIES} ${CAS_KERNEL})
+TARGET_LINK_LIBRARIES(GeomAPI ${PROJECT_LIBRARIES} ${CAS_KERNEL} ${CAS_MODELER})
 
 SET(SWIG_SCRIPTS
   ${CMAKE_CURRENT_BINARY_DIR}/GeomAPI.py
index 6e8ea2429f790687cc5047a80efe94f2742e310a..abe357b2bfc17e033ddd4af1644aa204ed3b3c5c 100644 (file)
@@ -7,12 +7,16 @@
 
 #include <gp_Dir.hxx>
 
-#define MY_DIR static_cast<gp_Pnt*>(myImpl)
+#define MY_DIR static_cast<gp_Dir*>(myImpl)
 
 GeomAPI_Dir::GeomAPI_Dir(const double theX, const double theY, const double theZ)
   : GeomAPI_Interface(new gp_Dir(theX, theY, theZ))
 {}
 
+GeomAPI_Dir::GeomAPI_Dir(const boost::shared_ptr<GeomAPI_XYZ>& theCoords)
+  : GeomAPI_Interface(new gp_Dir(theCoords->x(), theCoords->y(), theCoords->z()))
+{}
+
 double GeomAPI_Dir::x() const
 {
   return MY_DIR->X();
@@ -32,3 +36,8 @@ const boost::shared_ptr<GeomAPI_XYZ> GeomAPI_Dir::xyz()
 {
   return boost::shared_ptr<GeomAPI_XYZ>(new GeomAPI_XYZ(MY_DIR->X(), MY_DIR->Y(), MY_DIR->Z()));
 }
+
+double GeomAPI_Dir::dot(const boost::shared_ptr<GeomAPI_Dir>& theArg) const
+{
+  return MY_DIR->Dot(theArg->impl<gp_Dir>());
+}
index afdab1c090ccb2e7bbce10e42e98ff26bf4d4898..6ab0f1dd2baced7076eff6b372d6d477e4f1ca49 100644 (file)
@@ -20,6 +20,8 @@ class GEOMAPI_EXPORT GeomAPI_Dir: public GeomAPI_Interface
 public:
   /// Creation of direction by coordinates
   GeomAPI_Dir(const double theX, const double theY, const double theZ);
+  /// Creation of direction by coordinates
+  GeomAPI_Dir(const boost::shared_ptr<GeomAPI_XYZ>& theCoords);
 
   /// returns X coordinate
   double x() const;
@@ -30,6 +32,9 @@ public:
 
   /// returns coordinates of the direction
   const boost::shared_ptr<GeomAPI_XYZ> xyz();
+
+  /// result is a scalar product of directions
+  double dot(const boost::shared_ptr<GeomAPI_Dir>& theArg) const;
 };
 
 #endif
diff --git a/src/GeomAPI/GeomAPI_Lin.cpp b/src/GeomAPI/GeomAPI_Lin.cpp
new file mode 100644 (file)
index 0000000..9d04070
--- /dev/null
@@ -0,0 +1,81 @@
+// File:        GeomAPI_Lin.cpp
+// Created:     29 May 2014
+// Author:      Artem ZHIDKOV
+
+#include <GeomAPI_Lin.h>
+#include <GeomAPI_Pnt.h>
+
+#include <gp_Dir.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Lin2d.hxx>
+#include <gp_Pln.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_XYZ.hxx>
+
+#include <ElSLib.hxx>
+#include <IntAna2d_AnaIntersection.hxx>
+#include <Precision.hxx>
+#include <ProjLib.hxx>
+
+#define MY_LIN static_cast<gp_Lin*>(myImpl)
+
+static gp_Lin* newLine(const double theStartX, const double theStartY, const double theStartZ,
+                       const double theEndX,   const double theEndY,   const double theEndZ)
+{
+  gp_XYZ aDir(theEndX - theStartX, theEndY - theStartY, theEndZ - theStartZ);
+  gp_Pnt aStart(theStartX, theStartY, theStartZ);
+  return new gp_Lin(aStart, gp_Dir(aDir));
+}
+
+
+GeomAPI_Lin::GeomAPI_Lin(const double theStartX, const double theStartY, const double theStartZ,
+                         const double theEndX,   const double theEndY,   const double theEndZ)
+  : GeomAPI_Interface(newLine(theStartX, theStartY, theStartZ, theEndX, theEndY, theEndZ))
+{}
+
+GeomAPI_Lin::GeomAPI_Lin(const boost::shared_ptr<GeomAPI_Pnt>& theStart,
+                         const boost::shared_ptr<GeomAPI_Pnt>& theEnd)
+  : GeomAPI_Interface(newLine(theStart->x(), theStart->y(), theStart->z(), 
+                              theEnd->x(),   theEnd->y(),   theEnd->z()))
+{}
+
+double GeomAPI_Lin::distance(const boost::shared_ptr<GeomAPI_Pnt>& thePoint) const
+{
+  return MY_LIN->Distance(thePoint->impl<gp_Pnt>());
+}
+
+const boost::shared_ptr<GeomAPI_Pnt> GeomAPI_Lin::intersect(
+                const boost::shared_ptr<GeomAPI_Lin>& theLine) const
+{
+  if (MY_LIN->SquareDistance(theLine->impl<gp_Lin>()) > Precision::Confusion())
+    return boost::shared_ptr<GeomAPI_Pnt>();
+
+  const gp_Dir& aDir1 = MY_LIN->Direction();
+  const gp_Dir& aDir2 = theLine->impl<gp_Lin>().Direction();
+  gp_Dir aCross = aDir1.Crossed(aDir2);
+  gp_Pln aPlane(MY_LIN->Location(), aCross); // plane containing both lines
+
+  gp_Lin2d aPrjLine1 = ProjLib::Project(aPlane, *MY_LIN);
+  gp_Lin2d aPrjLine2 = ProjLib::Project(aPlane, theLine->impl<gp_Lin>());
+
+  IntAna2d_AnaIntersection anInter(aPrjLine1, aPrjLine1);
+  if (!anInter.IsDone() || anInter.IsEmpty())
+    return boost::shared_ptr<GeomAPI_Pnt>();
+  const gp_Pnt2d& anIntPnt2d = anInter.Point(0).Value();
+  gp_Pnt aResult = ElSLib::Value(anIntPnt2d.X(), anIntPnt2d.Y(), aPlane);
+
+  return boost::shared_ptr<GeomAPI_Pnt>(
+    new GeomAPI_Pnt(aResult.X(), aResult.Y(), aResult.Z()));
+}
+
+const boost::shared_ptr<GeomAPI_Pnt> GeomAPI_Lin::project(const boost::shared_ptr<GeomAPI_Pnt>& thePoint) const
+{
+  const gp_XYZ& aDir = MY_LIN->Direction().XYZ();
+  const gp_XYZ& aLoc = MY_LIN->Location().XYZ();
+  const gp_XYZ& aPnt = thePoint->impl<gp_Pnt>().XYZ();
+  double aParam = aDir.Dot(aPnt - aLoc);
+
+  gp_XYZ aResult = aPnt + aDir * aParam;
+  return boost::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aResult.X(), aResult.Y(), aResult.Z()));
+}
+
diff --git a/src/GeomAPI/GeomAPI_Lin.h b/src/GeomAPI/GeomAPI_Lin.h
new file mode 100644 (file)
index 0000000..260b5ff
--- /dev/null
@@ -0,0 +1,37 @@
+// File:        GeomAPI_Lin.h
+// Created:     29 May 2014
+// Author:      Artem ZHIDKOV
+
+#ifndef GeomAPI_Lin_HeaderFile
+#define GeomAPI_Lin_HeaderFile
+
+#include <GeomAPI_Interface.h>
+#include <boost/shared_ptr.hpp>
+
+class GeomAPI_Pnt;
+
+/**\class GeomAPI_Lin
+ * \ingroup DataModel
+ * \brief Line in 3D
+ */
+
+class GEOMAPI_EXPORT GeomAPI_Lin: public GeomAPI_Interface
+{
+public:
+  /// Creation of line defined by cordinates of start and end points
+  GeomAPI_Lin(const double theStartX, const double theStartY, const double theStartZ,
+              const double theEndX,   const double theEndY,   const double theEndZ);
+  /// Creation of line defined by start and end points
+  GeomAPI_Lin(const boost::shared_ptr<GeomAPI_Pnt>& theStart,
+              const boost::shared_ptr<GeomAPI_Pnt>& theEnd);
+
+  /// Distance between two points
+  double distance(const boost::shared_ptr<GeomAPI_Pnt>& thePoint) const;
+  /// Intersection of two lines
+  const boost::shared_ptr<GeomAPI_Pnt> intersect(const boost::shared_ptr<GeomAPI_Lin>& theLine) const;
+  /// Project point on line
+  const boost::shared_ptr<GeomAPI_Pnt> project(const boost::shared_ptr<GeomAPI_Pnt>& thePoint) const;
+};
+
+#endif
+
diff --git a/src/GeomAPI/GeomAPI_Lin2d.cpp b/src/GeomAPI/GeomAPI_Lin2d.cpp
new file mode 100644 (file)
index 0000000..2d698c0
--- /dev/null
@@ -0,0 +1,62 @@
+// File:        GeomAPI_Lin2d.cpp
+// Created:     29 May 2014
+// Author:      Artem ZHIDKOV
+
+#include <GeomAPI_Lin2d.h>
+#include <GeomAPI_Pnt2d.h>
+
+#include <gp_Dir2d.hxx>
+#include <gp_Lin2d.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_XY.hxx>
+
+#include <IntAna2d_AnaIntersection.hxx>
+
+#define MY_LIN2D static_cast<gp_Lin2d*>(myImpl)
+
+static gp_Lin2d* newLine2d(const double theStartX, const double theStartY,
+                           const double theEndX,   const double theEndY)
+{
+  gp_XY aDir(theEndX - theStartX, theEndY - theStartY);
+  gp_Pnt2d aStart(theStartX, theStartY);
+  return new gp_Lin2d(aStart, gp_Dir2d(aDir));
+}
+
+
+GeomAPI_Lin2d::GeomAPI_Lin2d(const double theStartX, const double theStartY,
+                             const double theEndX,   const double theEndY)
+  : GeomAPI_Interface(newLine2d(theStartX, theStartY, theEndX, theEndY))
+{}
+
+GeomAPI_Lin2d::GeomAPI_Lin2d(const boost::shared_ptr<GeomAPI_Pnt2d>& theStart,
+                         const boost::shared_ptr<GeomAPI_Pnt2d>& theEnd)
+  : GeomAPI_Interface(newLine2d(theStart->x(), theStart->y(),
+                                theEnd->x(),   theEnd->y()))
+{}
+
+double GeomAPI_Lin2d::distance(const boost::shared_ptr<GeomAPI_Pnt2d>& theOther) const
+{
+  return MY_LIN2D->Distance(theOther->impl<gp_Pnt2d>());
+}
+
+const boost::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Lin2d::intersect(
+                const boost::shared_ptr<GeomAPI_Lin2d>& theLine) const
+{
+  IntAna2d_AnaIntersection anInter(*MY_LIN2D, theLine->impl<gp_Lin2d>());
+  if (!anInter.IsDone() || anInter.IsEmpty())
+    return boost::shared_ptr<GeomAPI_Pnt2d>();
+  const gp_Pnt2d& aResult = anInter.Point(0).Value();
+  return boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aResult.X(), aResult.Y()));
+}
+
+const boost::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Lin2d::project(const boost::shared_ptr<GeomAPI_Pnt2d>& thePoint) const
+{
+  const gp_XY& aDir = MY_LIN2D->Direction().XY();
+  const gp_XY& aLoc = MY_LIN2D->Location().XY();
+  const gp_XY& aPnt = thePoint->impl<gp_Pnt2d>().XY();
+  double aParam = aDir.Dot(aPnt - aLoc);
+
+  gp_XY aResult = aPnt + aDir * aParam;
+  return boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aResult.X(), aResult.Y()));
+}
+
diff --git a/src/GeomAPI/GeomAPI_Lin2d.h b/src/GeomAPI/GeomAPI_Lin2d.h
new file mode 100644 (file)
index 0000000..32f55d3
--- /dev/null
@@ -0,0 +1,37 @@
+// File:        GeomAPI_Lin2d.h
+// Created:     29 May 2014
+// Author:      Artem ZHIDKOV
+
+#ifndef GeomAPI_Lin2d_HeaderFile
+#define GeomAPI_Lin2d_HeaderFile
+
+#include <GeomAPI_Interface.h>
+#include <boost/shared_ptr.hpp>
+
+class GeomAPI_Pnt2d;
+
+/**\class GeomAPI_Lin2d
+ * \ingroup DataModel
+ * \brief Line in 2D
+ */
+
+class GEOMAPI_EXPORT GeomAPI_Lin2d: public GeomAPI_Interface
+{
+public:
+  /// Creation of line defined by cordinates of start and end points
+  GeomAPI_Lin2d(const double theStartX, const double theStartY,
+                const double theEndX,   const double theEndY);
+  /// Creation of line defined by start and end points
+  GeomAPI_Lin2d(const boost::shared_ptr<GeomAPI_Pnt2d>& theStart,
+                const boost::shared_ptr<GeomAPI_Pnt2d>& theEnd);
+
+  /// Distance between two points
+  double distance(const boost::shared_ptr<GeomAPI_Pnt2d>& theOther) const;
+  /// Intersection of two lines
+  const boost::shared_ptr<GeomAPI_Pnt2d> intersect(const boost::shared_ptr<GeomAPI_Lin2d>& theLine) const;
+  /// Project point on line
+  const boost::shared_ptr<GeomAPI_Pnt2d> project(const boost::shared_ptr<GeomAPI_Pnt2d>& thePoint) const;
+};
+
+#endif
+
index 83d1dddf9adad8bc90bbff2829df19c80238f8e3..abf73f07bad436622fbc36819131fdc4f994cbde 100644 (file)
@@ -51,3 +51,8 @@ const boost::shared_ptr<GeomAPI_XYZ> GeomAPI_Pnt::xyz()
 {
   return boost::shared_ptr<GeomAPI_XYZ>(new GeomAPI_XYZ(MY_PNT->X(), MY_PNT->Y(), MY_PNT->Z()));
 }
+
+double GeomAPI_Pnt::distance(const boost::shared_ptr<GeomAPI_Pnt>& theOther) const
+{
+  return MY_PNT->Distance(theOther->impl<gp_Pnt>());
+}
index a63974d98c597c088c4e98037a3a0d1d19e57989..9be8ad0ec3d5a876f9664a55751f35fb2da60e6d 100644 (file)
@@ -39,6 +39,9 @@ public:
 
   /// returns coordinates of the point
   const boost::shared_ptr<GeomAPI_XYZ> xyz();
+
+  /// Distance between two points
+  double distance(const boost::shared_ptr<GeomAPI_Pnt>& theOther) const;
 };
 
 #endif
diff --git a/src/GeomAPI/GeomAPI_Pnt2d.cpp b/src/GeomAPI/GeomAPI_Pnt2d.cpp
new file mode 100644 (file)
index 0000000..1b4ee55
--- /dev/null
@@ -0,0 +1,48 @@
+// File:        GeomAPI_Pnt2d.cpp
+// Created:     29 May 2014
+// Author:      Artem ZHIDKOV
+
+#include<GeomAPI_Pnt2d.h>
+#include<GeomAPI_XY.h>
+
+#include<gp_Pnt2d.hxx>
+
+#define MY_PNT2D static_cast<gp_Pnt2d*>(myImpl)
+
+GeomAPI_Pnt2d::GeomAPI_Pnt2d(const double theX, const double theY)
+  : GeomAPI_Interface(new gp_Pnt2d(theX, theY))
+{}
+
+GeomAPI_Pnt2d::GeomAPI_Pnt2d(const boost::shared_ptr<GeomAPI_XY>& theCoords)
+  : GeomAPI_Interface(new gp_Pnt2d(theCoords->x(), theCoords->y()))
+{}
+
+double GeomAPI_Pnt2d::x() const
+{
+  return MY_PNT2D->X();
+}
+
+double GeomAPI_Pnt2d::y() const
+{
+  return MY_PNT2D->Y();
+}
+
+void GeomAPI_Pnt2d::setX(const double theX)
+{
+  return MY_PNT2D->SetX(theX);
+}
+
+void GeomAPI_Pnt2d::setY(const double theY)
+{
+  return MY_PNT2D->SetY(theY);
+}
+
+const boost::shared_ptr<GeomAPI_XY> GeomAPI_Pnt2d::xy()
+{
+  return boost::shared_ptr<GeomAPI_XY>(new GeomAPI_XY(MY_PNT2D->X(), MY_PNT2D->Y()));
+}
+
+double GeomAPI_Pnt2d::distance(const boost::shared_ptr<GeomAPI_Pnt2d>& theOther) const
+{
+  return MY_PNT2D->Distance(theOther->impl<gp_Pnt2d>());
+}
diff --git a/src/GeomAPI/GeomAPI_Pnt2d.h b/src/GeomAPI/GeomAPI_Pnt2d.h
new file mode 100644 (file)
index 0000000..a1faf62
--- /dev/null
@@ -0,0 +1,44 @@
+// File:        GeomAPI_Pnt2d.h
+// Created:     29 May 2014
+// Author:      Artem ZHIDKOV
+
+#ifndef GeomAPI_Pnt2d_HeaderFile
+#define GeomAPI_Pnt2d_HeaderFile
+
+#include <GeomAPI_Interface.h>
+#include <boost/shared_ptr.hpp>
+
+class GeomAPI_XY;
+
+/**\class GeomAPI_Pnt2d
+ * \ingroup DataModel
+ * \brief 2D point defined by two coordinates
+ */
+
+class GEOMAPI_EXPORT GeomAPI_Pnt2d: public GeomAPI_Interface
+{
+public:
+  /// Creation of point by coordinates
+  GeomAPI_Pnt2d(const double theX, const double theY);
+  /// Creation of point by coordinates
+  GeomAPI_Pnt2d(const boost::shared_ptr<GeomAPI_XY>& theCoords);
+
+  /// returns X coordinate
+  double x() const;
+  /// returns Y coordinate
+  double y() const;
+
+  /// sets X coordinate
+  void setX(const double theX);
+  /// sets Y coordinate
+  void setY(const double theY);
+
+  /// returns coordinates of the point
+  const boost::shared_ptr<GeomAPI_XY> xy();
+
+  /// Distance between two points
+  double distance(const boost::shared_ptr<GeomAPI_Pnt2d>& theOther) const;
+};
+
+#endif
+
diff --git a/src/GeomAPI/GeomAPI_XY.cpp b/src/GeomAPI/GeomAPI_XY.cpp
new file mode 100644 (file)
index 0000000..94341c3
--- /dev/null
@@ -0,0 +1,65 @@
+// File:        GeomAPI_XY.cpp
+// Created:     30 May 2014
+// Author:      Artem ZHIDKOV
+
+#include<GeomAPI_XY.h>
+
+#include<gp_XY.hxx>
+
+#define MY_XY static_cast<gp_XY*>(myImpl)
+
+GeomAPI_XY::GeomAPI_XY(const double theX, const double theY)
+  : GeomAPI_Interface(new gp_XY(theX, theY))
+{}
+
+double GeomAPI_XY::x() const
+{
+  return MY_XY->X();
+}
+
+double GeomAPI_XY::y() const
+{
+  return MY_XY->Y();
+}
+
+void GeomAPI_XY::setX(const double theX)
+{
+  return MY_XY->SetX(theX);
+}
+
+void GeomAPI_XY::setY(const double theY)
+{
+  return MY_XY->SetY(theY);
+}
+
+const boost::shared_ptr<GeomAPI_XY> GeomAPI_XY::added(
+  const boost::shared_ptr<GeomAPI_XY>& theArg)
+{
+  boost::shared_ptr<GeomAPI_XY> aResult(
+    new GeomAPI_XY(MY_XY->X() + theArg->x(), MY_XY->Y() + theArg->y()));
+  return aResult;
+}
+
+const boost::shared_ptr<GeomAPI_XY> GeomAPI_XY::multiplied(const double theArg)
+{
+  boost::shared_ptr<GeomAPI_XY> aResult(
+    new GeomAPI_XY(MY_XY->X() * theArg, MY_XY->Y() * theArg));
+  return aResult;
+}
+
+double GeomAPI_XY::dot(const boost::shared_ptr<GeomAPI_XY>& theArg) const
+{
+  return MY_XY->Dot(theArg->impl<gp_XY>());
+}
+
+double GeomAPI_XY::cross(const boost::shared_ptr<GeomAPI_XY>& theArg) const
+{
+  return MY_XY->Crossed(theArg->impl<gp_XY>());
+}
+
+double GeomAPI_XY::distance(const boost::shared_ptr<GeomAPI_XY>& theOther) const
+{
+  gp_XY aResult(theOther->x() - x(), theOther->y() - y());
+  return aResult.Modulus();
+}
+
diff --git a/src/GeomAPI/GeomAPI_XY.h b/src/GeomAPI/GeomAPI_XY.h
new file mode 100644 (file)
index 0000000..0f0187a
--- /dev/null
@@ -0,0 +1,47 @@
+// File:        GeomAPI_XY.hxx
+// Created:     30 May 2014
+// Author:      Artem ZHIDKOV
+
+#ifndef GeomAPI_XY_HeaderFile
+#define GeomAPI_XY_HeaderFile
+
+#include <GeomAPI_Interface.h>
+#include <boost/shared_ptr.hpp>
+
+/**\class GeomAPI_XY
+ * \ingroup DataModel
+ * \brief 2 coordinates: they may represent vector or point or something else
+ */
+
+class GEOMAPI_EXPORT GeomAPI_XY: public GeomAPI_Interface
+{
+public:
+  /// Creation by coordinates
+  GeomAPI_XY(const double theX, const double theY);
+
+  /// returns X coordinate
+  double x() const;
+  /// returns Y coordinate
+  double y() const;
+
+  /// sets X coordinate
+  void setX(const double theX);
+  /// sets Y coordinate
+  void setY(const double theY);
+
+  /// result is sum of coordinates of this and the given argument
+  const boost::shared_ptr<GeomAPI_XY> added(const boost::shared_ptr<GeomAPI_XY>& theArg);
+  /// result is coordinates multiplied by the argument
+  const boost::shared_ptr<GeomAPI_XY> multiplied(const double theArg);
+
+  /// result is a scalar product of two triplets
+  double dot(const boost::shared_ptr<GeomAPI_XY>& theArg) const;
+  /// result is a cross product of two triplets
+  double cross(const boost::shared_ptr<GeomAPI_XY>& theArg) const;
+
+  /// Distance between two pairs
+  double distance(const boost::shared_ptr<GeomAPI_XY>& theOther) const;
+};
+
+#endif
+
index 30c246323a26d18feb7e9e8b9117816852c4b5b9..f413005fd0aebc80ab6744fef5787a82920b4a85 100644 (file)
@@ -50,9 +50,35 @@ const boost::shared_ptr<GeomAPI_XYZ> GeomAPI_XYZ::added(
   return aResult;
 }
 
+const boost::shared_ptr<GeomAPI_XYZ> GeomAPI_XYZ::decreased(
+  const boost::shared_ptr<GeomAPI_XYZ>& theArg)
+{
+  boost::shared_ptr<GeomAPI_XYZ> aResult(new GeomAPI_XYZ(MY_XYZ->X() - theArg->x(),
+    MY_XYZ->Y() - theArg->y(), MY_XYZ->Z() - theArg->z()));
+  return aResult;
+}
+
 const boost::shared_ptr<GeomAPI_XYZ> GeomAPI_XYZ::multiplied(const double theArg)
 {
   boost::shared_ptr<GeomAPI_XYZ> aResult(new GeomAPI_XYZ(MY_XYZ->X() * theArg,
     MY_XYZ->Y() * theArg, MY_XYZ->Z() * theArg));
   return aResult;
 }
+
+double GeomAPI_XYZ::dot(const boost::shared_ptr<GeomAPI_XYZ>& theArg) const
+{
+  return MY_XYZ->Dot(theArg->impl<gp_XYZ>());
+}
+
+const boost::shared_ptr<GeomAPI_XYZ> GeomAPI_XYZ::cross(const boost::shared_ptr<GeomAPI_XYZ>& theArg) const
+{
+  gp_XYZ aResult = MY_XYZ->Crossed(theArg->impl<gp_XYZ>());
+  return boost::shared_ptr<GeomAPI_XYZ>(new GeomAPI_XYZ(aResult.X(), aResult.Y(), aResult.Z()));
+}
+
+double GeomAPI_XYZ::distance(const boost::shared_ptr<GeomAPI_XYZ>& theOther) const
+{
+  gp_XYZ aResult(theOther->x() - x(), theOther->y() - y(), theOther->z() - z());
+  return aResult.Modulus();
+}
+
index 6042428e5e15c068ae2e83e6578ea97ed944cfca..ffcaa9d8675e97f9c0cab0502a45ff46b44b0ecb 100644 (file)
@@ -35,8 +35,18 @@ public:
 
   /// result is sum of coordinates of this and the given argument
   const boost::shared_ptr<GeomAPI_XYZ> added(const boost::shared_ptr<GeomAPI_XYZ>& theArg);
+  /// result is difference between coordinates of this and the given argument
+  const boost::shared_ptr<GeomAPI_XYZ> decreased(const boost::shared_ptr<GeomAPI_XYZ>& theArg);
   /// result is coordinates multiplied by the argument
   const boost::shared_ptr<GeomAPI_XYZ> multiplied(const double theArg);
+
+  /// result is a scalar product of two triplets
+  double dot(const boost::shared_ptr<GeomAPI_XYZ>& theArg) const;
+  /// result is a cross product of two triplets
+  const boost::shared_ptr<GeomAPI_XYZ> cross(const boost::shared_ptr<GeomAPI_XYZ>& theArg) const;
+
+  /// Distance between two triplets
+  double distance(const boost::shared_ptr<GeomAPI_XYZ>& theOther) const;
 };
 
 #endif
index 070e94562ff56705f0276b3baf85fec704454e78..44f04fe307900b6867a4bba70a6d7bd480b7c984 100644 (file)
@@ -22,6 +22,11 @@ void GeomData_Dir::setValue(const double theX, const double theY, const double t
   }
 }
 
+void GeomData_Dir::setValue(const boost::shared_ptr<GeomAPI_Dir>& theDir)
+{
+  setValue(theDir->x(), theDir->y(), theDir->z());
+}
+
 double GeomData_Dir::x() const
 {
   return myCoords->Value(0);
index a7c1a2497363120d9a90bbba4820f844910f60ea..1b6dd6c64bf9090060cc596fcd69533c6bc204df 100644 (file)
@@ -23,6 +23,8 @@ class GeomData_Dir : public GeomDataAPI_Dir
 public:
   /// Defines the double value
   GEOMDATA_EXPORT virtual void setValue(const double theX, const double theY, const double theZ);
+  /// Defines the direction
+  GEOMDATA_EXPORT virtual void setValue(const boost::shared_ptr<GeomAPI_Dir>& theDir);
 
   /// Returns the X double value
   GEOMDATA_EXPORT virtual double x() const;
index 6ad2ac56479b99942b5c4c2ac55be0947aedb3a9..da6299703174b694c2d95b179b905a738c2dfc23 100644 (file)
@@ -21,6 +21,11 @@ void GeomData_Point::setValue(const double theX, const double theY, const double
   }
 }
 
+void GeomData_Point::setValue(const boost::shared_ptr<GeomAPI_Pnt>& thePoint)
+{
+  setValue(thePoint->x(), thePoint->y(), thePoint->z());
+}
+
 double GeomData_Point::x() const
 {
   return myCoords->Value(0);
index ee319e89e53ad505005fac78e7eed5cd396af140..116039cf196daad35fe7e6e5aa6cfe3130bc79a5 100644 (file)
@@ -21,6 +21,8 @@ class GeomData_Point : public GeomDataAPI_Point
 public:
   /// Defines the double value
   GEOMDATA_EXPORT virtual void setValue(const double theX, const double theY, const double theZ);
+  /// Defines the point
+  GEOMDATA_EXPORT virtual void setValue(const boost::shared_ptr<GeomAPI_Pnt>& thePoint);
 
   /// Returns the X double value
   GEOMDATA_EXPORT virtual double x() const;
index 8af702953a020f407e2360e2b054f1ec87f60820..334d2070a320b1c19d0f9cf73450d143eca4f868 100644 (file)
@@ -5,6 +5,7 @@
 #include "GeomData_Point2D.h"
 #include "Model_Events.h"
 #include <Events_Loop.h>
+#include <GeomAPI_Pnt2d.h>
 
 using namespace std;
 
@@ -19,6 +20,11 @@ void GeomData_Point2D::setValue(const double theX, const double theY)
   }
 }
 
+void GeomData_Point2D::setValue(const boost::shared_ptr<GeomAPI_Pnt2d>& thePoint)
+{
+  setValue(thePoint->x(), thePoint->y());
+}
+
 double GeomData_Point2D::x() const
 {
   return myCoords->Value(0);
@@ -29,6 +35,13 @@ double GeomData_Point2D::y() const
   return myCoords->Value(1);
 }
 
+boost::shared_ptr<GeomAPI_Pnt2d> GeomData_Point2D::pnt()
+{
+  boost::shared_ptr<GeomAPI_Pnt2d> aResult(
+    new GeomAPI_Pnt2d(myCoords->Value(0), myCoords->Value(1)));
+  return aResult;
+}
+
 GeomData_Point2D::GeomData_Point2D(TDF_Label& theLabel)
 {
   // check the attribute could be already presented in this doc (after load document)
index 4b3d4671c43dcf0c85d70f82669a25aa3e153da1..8e3c124b3d45515ee57177707277c7035bf38d25 100644 (file)
@@ -21,11 +21,15 @@ class GeomData_Point2D : public GeomDataAPI_Point2D
 public:
   /// Defines the double value
   GEOMDATA_EXPORT virtual void setValue(const double theX, const double theY);
+  /// Defines the point
+  GEOMDATA_EXPORT virtual void setValue(const boost::shared_ptr<GeomAPI_Pnt2d>& thePoint);
 
   /// Returns the X double value
   GEOMDATA_EXPORT virtual double x() const;
   /// Returns the Y double value
   GEOMDATA_EXPORT virtual double y() const;
+  /// Returns the 2D point
+  GEOMDATA_EXPORT virtual boost::shared_ptr<GeomAPI_Pnt2d> pnt();
 
 protected:
   /// Initializes attributes
index dbe8ef5e26f0a2c5d6f3d1e4d1648e1c0c4d2c96..a25c9faaf976137abbf605eda322fe2c7379576a 100644 (file)
@@ -20,6 +20,8 @@ class GeomDataAPI_Dir : public ModelAPI_Attribute
 public:
   /// Defines the double value
   virtual void setValue(const double theX, const double theY, const double theZ) = 0;
+  /// Defines the direction
+  virtual void setValue(const boost::shared_ptr<GeomAPI_Dir>& theDir) = 0;
 
   /// Returns the X double value
   virtual double x() const = 0;
index c9581b2bea7fd6ff38aecada82a7cf5cbeff58a8..5f08bde0264495703c61458ffacf5002b7aff05f 100644 (file)
@@ -20,6 +20,8 @@ class GeomDataAPI_Point : public ModelAPI_Attribute
 public:
   /// Defines the double value
   virtual void setValue(const double theX, const double theY, const double theZ) = 0;
+  /// Defines the point
+  virtual void setValue(const boost::shared_ptr<GeomAPI_Pnt>& thePoint) = 0;
 
   /// Returns the X double value
   virtual double x() const = 0;
index bfc8094c2c121a7ca803ab869edc0b04373448b0..f5eb429382bffd9528137114adb9ed7b70938345 100644 (file)
@@ -8,6 +8,8 @@
 #include "GeomDataAPI.h"
 #include <ModelAPI_Attribute.h>
 
+class GeomAPI_Pnt2d;
+
 /**\class GeomDataAPI_Point2D
  * \ingroup DataModel
  * \brief Attribute that contains 2D point coordinates.
@@ -18,11 +20,15 @@ class GeomDataAPI_Point2D : public ModelAPI_Attribute
 public:
   /// Defines the double value
   virtual void setValue(const double theX, const double theY) = 0;
+  /// Defines the point
+  virtual void setValue(const boost::shared_ptr<GeomAPI_Pnt2d>& thePoint) = 0;
 
   /// Returns the X double value
   virtual double x() const = 0;
   /// Returns the Y double value
   virtual double y() const = 0;
+  /// Returns the 2D point
+  virtual boost::shared_ptr<GeomAPI_Pnt2d> pnt() = 0;
 
   /// Returns the type of this class of attributes
   static inline std::string type() {return std::string("Point2D");}
index 4e339672b65edcac0e9924f165f1d4c7a146bf05..378af8663e35751e213566728e7ea3bfc3e41849 100644 (file)
@@ -31,6 +31,11 @@ ModuleBase_OperationDescription* ModuleBase_IOperation::getDescription() const
   return myDescription;
 }
 
+bool ModuleBase_IOperation::canBeCommitted() const
+{
+  return true;
+}
+
 bool ModuleBase_IOperation::isGranted(ModuleBase_IOperation* /*theOperation*/) const
 {
   return false;
@@ -74,6 +79,8 @@ void ModuleBase_IOperation::commit()
 
   document()->finishOperation();
   emit stopped();
+  
+  afterCommitOperation();
 }
 
 void ModuleBase_IOperation::setRunning(bool theState)
index b3373e4bf2764955aa3d8513df6a91a9500d3b48..4af5c227f6abe858f23262cd958fab9cc3e2cd2a 100644 (file)
@@ -55,6 +55,10 @@ public:
   /// /returns the instance of the description class
   ModuleBase_OperationDescription* getDescription() const;
 
+  /// Verifies whether this operator can be commited.
+  /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled
+  virtual bool canBeCommitted() const;
+
   /// Verifies whether this operator can be always started above any already running one
   /// \return Returns TRUE if current operation must not be checked for ActiveOperation->IsValid( this )
   /// This method must be redefined in derived operation if operation of derived class
@@ -118,6 +122,9 @@ protected:
   virtual void abortOperation() = 0;
   /// Virtual method called when operation committed (see commit() method for more description)
   virtual void commitOperation() = 0;
+  /// Virtual method called after operation committed (see commit() method for more description)
+  /// it is important that the method is called after the stop() signal is emitted
+  virtual void afterCommitOperation() = 0;
 
   /// Returns pointer to the root document.
   boost::shared_ptr<ModelAPI_Document> document() const;
index c26eadb2a9e2d50b73ed90752ae33a91e51aebc0..8bf69185cea2baa2bb0260b6742d5d46aa98ab23 100644 (file)
@@ -98,6 +98,10 @@ void ModuleBase_Operation::commitOperation()
   if (myFeature) myFeature->execute();
 }
 
+void ModuleBase_Operation::afterCommitOperation()
+{
+}
+
 void ModuleBase_Operation::flushUpdated()
 {
   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_UPDATED));
index e66d58ab99c56ebfe6b6fe46bafa5c818693c568..833dbf57c80872c4234aafdf4a3191b3da4d0c68 100644 (file)
@@ -80,6 +80,8 @@ protected:
   virtual void abortOperation();
   /// Virtual method called when operation committed (see commit() method for more description)
   virtual void commitOperation();
+  /// Virtual method called after operation committed (see commit() method for more description)
+  virtual void afterCommitOperation();
 
   /// Send update message by loop
   void flushUpdated();
index 623eaae6392f1c774103ac809ef28750d29cdce3..0f397b1017bf3f2eb55cb24a2383c947962d8c78 100644 (file)
@@ -71,10 +71,6 @@ ModuleBase_WidgetPoint2D::~ModuleBase_WidgetPoint2D()
 bool ModuleBase_WidgetPoint2D::storeValue(boost::shared_ptr<ModelAPI_Feature> theFeature)
 {
   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
-  if (!aData) {
-     ObjectPtr anObj = boost::dynamic_pointer_cast<ModelAPI_Object>(theFeature);
-     if (anObj) aData = anObj->featureRef()->data();
-  }
   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
     boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(myFeatureAttributeID));
 
@@ -89,10 +85,6 @@ bool ModuleBase_WidgetPoint2D::storeValue(boost::shared_ptr<ModelAPI_Feature> th
 bool ModuleBase_WidgetPoint2D::restoreValue(boost::shared_ptr<ModelAPI_Feature> theFeature)
 {
   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
-  if (!aData) {
-     ObjectPtr anObj = boost::dynamic_pointer_cast<ModelAPI_Object>(theFeature);
-     if (anObj) aData = anObj->featureRef()->data();
-  }
   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
     boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(myFeatureAttributeID));
 
index 374b1d503bb2607c30e30610eeaeb09e4395df78..3d93034020fd5ae115d03761f5ee5d1f0174a6c2 100644 (file)
@@ -8,6 +8,7 @@
 #include <PartSet_TestOCC.h>
 
 #include <ModuleBase_Operation.h>
+#include <ModelAPI_Object.h>
 
 #include <XGUI_MainWindow.h>
 #include <XGUI_Displayer.h>
@@ -20,6 +21,7 @@
 #include <XGUI_ViewerProxy.h>
 #include <XGUI_ContextMenuMgr.h>
 #include <XGUI_PropertyPanel.h>
+#include <XGUI_Tools.h>
 
 #include <Config_PointerMessage.h>
 #include <Config_ModuleReader.h>
@@ -441,7 +443,15 @@ void PartSet_Module::editFeature(FeaturePtr theFeature)
     return;
 
   if (theFeature->getKind() == "Sketch") {
-    onLaunchOperation(theFeature->getKind(), theFeature);
-    updateCurrentPreview(theFeature->getKind());
+    FeaturePtr aFeature = theFeature;
+    if (XGUI_Tools::isModelObject(aFeature)) {
+      ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
+      aFeature = aObject->featureRef();
+    }
+
+    if (aFeature) {
+      onLaunchOperation(aFeature->getKind(), aFeature);
+      updateCurrentPreview(aFeature->getKind());
+    }
   }
 }
index d69aab8e0ab2793a2c05372cb97afcbdf7b9025b..2edee70af2cfbcde14f496eaccc9b242869fbe6d 100644 (file)
@@ -108,7 +108,7 @@ void PartSet_OperationEditLine::mousePressed(QMouseEvent* theEvent, Handle(V3d_V
         emit setSelection(aSelected);
       }
       else if (aFeature) {
-        emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
+        restartOperation(PartSet_OperationEditLine::Type(), aFeature);
       }
     }
   }
@@ -144,7 +144,6 @@ void PartSet_OperationEditLine::mouseMoved(QMouseEvent* theEvent, Handle(V3d_Vie
       moveLinePoint(aFeature, aDeltaX, aDeltaY, LINE_ATTR_END);
     }
   }
-  flushUpdated();
   sendFeatures();
 
   myCurPoint.setPoint(aPoint);
@@ -243,5 +242,6 @@ void PartSet_OperationEditLine::sendFeatures()
     Events_Loop::loop()->send(aMessage);
   }
   Events_Loop::loop()->flush(anEvent);
+  flushUpdated();
 }
 
index f50dcb41df200e73602dd1eac89418db885328f6..3270705d61af4f68d75d8ad4c06526a29c76bc0a 100644 (file)
@@ -85,7 +85,7 @@ void PartSet_OperationSketch::mousePressed(QMouseEvent* theEvent, Handle_V3d_Vie
     if (theHighlighted.size() == 1) {
       boost::shared_ptr<ModelAPI_Feature> aFeature = theHighlighted.front().feature();
       if (aFeature)
-        emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
+        restartOperation(PartSet_OperationEditLine::Type(), aFeature);
     }
     else
       myFeatures = theHighlighted;
@@ -101,7 +101,7 @@ void PartSet_OperationSketch::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View)
     boost::shared_ptr<ModelAPI_Feature> aFeature = PartSet_Tools::NearestFeature(theEvent->pos(),
                                                                 theView, feature(), myFeatures);
     if (aFeature)
-      emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
+      restartOperation(PartSet_OperationEditLine::Type(), aFeature);
   }
 }
 
index 46b9a05411bad19924e4420dea5a8c7eedfbbe39..ae751b269ec8f14ce686d059e24a9f4c5f6128c0 100644 (file)
@@ -5,7 +5,6 @@
 #include <PartSet_OperationSketchBase.h>
 
 #include <SketchPlugin_Feature.h>
-#include <ModelAPI_Object.h>
 
 #include <V3d_View.hxx>
 
@@ -32,12 +31,6 @@ boost::shared_ptr<GeomAPI_Shape> PartSet_OperationSketchBase::preview(
 {
   boost::shared_ptr<SketchPlugin_Feature> aFeature = 
                               boost::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
-  if (!aFeature) { // if it is reference to a object feature
-    boost::shared_ptr<ModelAPI_Object> anObj = 
-      boost::dynamic_pointer_cast<ModelAPI_Object>(theFeature);
-    if (anObj) 
-      aFeature = boost::dynamic_pointer_cast<SketchPlugin_Feature>(anObj->featureRef());
-  }
   if (!aFeature)
     return boost::shared_ptr<GeomAPI_Shape>();
   return aFeature->preview();
@@ -95,3 +88,9 @@ void PartSet_OperationSketchBase::keyReleased(std::string theName, QKeyEvent* th
 {
   keyReleased(theEvent->key());
 }
+
+void PartSet_OperationSketchBase::restartOperation(const std::string& theType,
+                                                   boost::shared_ptr<ModelAPI_Feature> theFeature)
+{
+  emit launchOperation(theType, theFeature);
+}
index 4da9b950332a2e00ea86e667bdc8d0c99fde2caf..0c10c6c1a9fb3b4074138b9b43f62e72f5d168fa 100644 (file)
@@ -94,6 +94,13 @@ public:
 
   virtual void keyReleased(std::string theName, QKeyEvent* theEvent);
 
+  /// Emits a signal about the operation start. This signal has an information about the feature.
+  /// If the provided feature is empty, the current operation feature is used.
+  /// \param theType a type of an operation started
+  /// theFeature the operation argument
+  void restartOperation(const std::string& theType,
+         boost::shared_ptr<ModelAPI_Feature> theFeature = boost::shared_ptr<ModelAPI_Feature>());
+
 signals:
   /// signal about the request to launch operation
   /// theName the operation name
index ddd9bd7281857bdf1ab1d34ac2ebc7adb9e60068..4ca7d3200991b2acfa7782b722b84f3e8e15cce5 100644 (file)
@@ -54,6 +54,11 @@ PartSet_OperationSketchLine::~PartSet_OperationSketchLine()
 {
 }
 
+bool PartSet_OperationSketchLine::canBeCommitted() const
+{
+  return myPointSelectionMode == SM_DonePoint;
+}
+
 bool PartSet_OperationSketchLine::isGranted(ModuleBase_IOperation* theOperation) const
 {
   return theOperation->getDescription()->operationId().toStdString() == PartSet_OperationSketch::Type();
@@ -87,6 +92,15 @@ void PartSet_OperationSketchLine::mouseReleased(QMouseEvent* theEvent, Handle(V3
                                                 const std::list<XGUI_ViewerPrs>& theSelected,
                                                 const std::list<XGUI_ViewerPrs>& /*theHighlighted*/)
 {
+  if (myPointSelectionMode == SM_DonePoint)
+  {
+    // if the point creation is finished, the next mouse release should commit the modification
+    // the next release can happens by double click in the viewer
+    commit();
+    restartOperation(PartSet_OperationSketchLine::Type(), feature());
+    return;
+  }
+
   double aX, anY;
 
   bool isFoundPoint = false;
@@ -137,8 +151,6 @@ void PartSet_OperationSketchLine::mouseReleased(QMouseEvent* theEvent, Handle(V3
       }
     }
   }
-  //if (!isFoundPoint)
-  //  return;
 
   switch (myPointSelectionMode)
   {
@@ -187,8 +199,7 @@ void PartSet_OperationSketchLine::mouseMoved(QMouseEvent* theEvent, Handle(V3d_V
     case SM_DonePoint:
     {
       commit();
-      emit featureConstructed(feature(), FM_Deactivation);
-      emit launchOperation(PartSet_OperationSketchLine::Type(), feature());
+      restartOperation(PartSet_OperationSketchLine::Type(), feature());
     }
     default:
       break;
@@ -216,8 +227,7 @@ void PartSet_OperationSketchLine::keyReleased(const int theKey)
       if (myPointSelectionMode == SM_DonePoint)
       {
         commit();
-        emit featureConstructed(feature(), FM_Deactivation);
-        emit launchOperation(PartSet_OperationSketchLine::Type(), boost::shared_ptr<ModelAPI_Feature>());
+        restartOperation(PartSet_OperationSketchLine::Type(), feature());
       }
       //else
       //  abort();
@@ -228,7 +238,6 @@ void PartSet_OperationSketchLine::keyReleased(const int theKey)
       if (myPointSelectionMode == SM_DonePoint)
       {
         commit();
-        emit featureConstructed(feature(), FM_Deactivation);
       }
       else
         abort();
@@ -258,6 +267,12 @@ void PartSet_OperationSketchLine::stopOperation()
   emit multiSelectionEnabled(true);
 }
 
+void PartSet_OperationSketchLine::afterCommitOperation()
+{
+  PartSet_OperationSketchBase::afterCommitOperation();  
+  emit featureConstructed(feature(), FM_Deactivation);
+}
+
 boost::shared_ptr<ModelAPI_Feature> PartSet_OperationSketchLine::createFeature(const bool theFlushMessage)
 {
   boost::shared_ptr<ModelAPI_Feature> aNewFeature = ModuleBase_Operation::createFeature(false);
@@ -320,8 +335,12 @@ void PartSet_OperationSketchLine::setConstraints(double theX, double theY)
     case SM_SecondPoint:
       aPointArg = LINE_ATTR_END;
       break;
+    default:
+      break;
   }
 
+  boost::shared_ptr<ModelAPI_Feature> aSkFeature = feature();
+
   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
   boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
                                                               (aData->attribute(aPointArg));
index d0c08e2865a923167bce06b6dfac85eb97d6dada..cda1781c45b0c7289af0356d3524c8480f921ebc 100644 (file)
@@ -36,7 +36,11 @@ public:
   /// Destructor
   virtual ~PartSet_OperationSketchLine();
 
-   /// Returns that this operator can be started above already running one.
+  /// Verifies whether this operator can be commited.
+  /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled
+  virtual bool canBeCommitted() const;
+
+  /// Returns that this operator can be started above already running one.
    /// The runned operation should be the sketch feature modified operation
   /// \param theOperation the previous running operation
   virtual bool isGranted(ModuleBase_IOperation* theOperation) const;
@@ -97,6 +101,9 @@ protected:
   /// Restore the multi selection state
   virtual void stopOperation();
 
+  /// Virtual method called after operation committed (see commit() method for more description)
+  virtual void afterCommitOperation();
+
   /// Creates an operation new feature
   /// In addition to the default realization it appends the created line feature to
   /// the sketch feature
index a1ee7a3620d1000b3af52e54e21091f7644d9585..9a4d7cf766d9adef77756ab45bf4048da12d68cd 100644 (file)
@@ -12,9 +12,10 @@ SET(PROJECT_HEADERS
     SketchPlugin_Constraint.h
     SketchPlugin_ConstraintCoincidence.h
     SketchPlugin_ConstraintDistance.h
-    SketchPlugin_ConstraintDiameter.h
+    SketchPlugin_ConstraintLength.h
     SketchPlugin_ConstraintParallel.h
     SketchPlugin_ConstraintPerpendicular.h
+    SketchPlugin_ConstraintRadius.h
 )
 
 SET(PROJECT_SOURCES
@@ -27,9 +28,10 @@ SET(PROJECT_SOURCES
     SketchPlugin_Arc.cpp
     SketchPlugin_ConstraintCoincidence.cpp
     SketchPlugin_ConstraintDistance.cpp
-    SketchPlugin_ConstraintDiameter.cpp
+    SketchPlugin_ConstraintLength.cpp
     SketchPlugin_ConstraintParallel.cpp
     SketchPlugin_ConstraintPerpendicular.cpp
+    SketchPlugin_ConstraintRadius.cpp
 )
 
 SET(PROJECT_LIBRARIES
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintDiameter.cpp b/src/SketchPlugin/SketchPlugin_ConstraintDiameter.cpp
deleted file mode 100644 (file)
index 179cce9..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// File:    SketchPlugin_ConstraintDiameter.cpp
-// Created: 26 May 2014
-// Author:  Artem ZHIDKOV
-
-#include "SketchPlugin_ConstraintDiameter.h"
-
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_Data.h>
-#include <SketchPlugin_Point.h>
-
-SketchPlugin_ConstraintDiameter::SketchPlugin_ConstraintDiameter()
-{
-}
-
-void SketchPlugin_ConstraintDiameter::initAttributes()
-{
-  data()->addAttribute(CONSTRAINT_ATTR_VALUE,    ModelAPI_AttributeDouble::type());
-  data()->addAttribute(CONSTRAINT_ATTR_ENTITY_A, ModelAPI_AttributeRefAttr::type());
-}
-
-void SketchPlugin_ConstraintDiameter::execute()
-{
-}
-
-const boost::shared_ptr<GeomAPI_Shape>&  SketchPlugin_ConstraintDiameter::preview()
-{
-  /// \todo Preview for diameter constraint
-  return getPreview();
-}
-
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintDiameter.h b/src/SketchPlugin/SketchPlugin_ConstraintDiameter.h
deleted file mode 100644 (file)
index 1ac7a32..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// File:    SketchPlugin_ConstraintDiameter.h
-// Created: 26 May 2014
-// Author:  Artem ZHIDKOV
-
-#ifndef SketchPlugin_ConstraintDiameter_HeaderFile
-#define SketchPlugin_ConstraintDiameter_HeaderFile
-
-#include "SketchPlugin.h"
-#include "SketchPlugin_Constraint.h"
-
-
-/** \class SketchPlugin_ConstraintDiameter
- *  \ingroup DataModel
- *  \brief Feature for creation of a new constraint which defines a diameter of a circle
- *
- *  These constraint has two attributes:
- *  CONSTRAINT_ATTR_VALUE (diameter), CONSTRAINT_ATTR_ENTITY_A (a circle)
- */
-class SketchPlugin_ConstraintDiameter: public SketchPlugin_Constraint
-{
-public:
-  /// \brief Returns the kind of a feature
-  SKETCHPLUGIN_EXPORT virtual const std::string& getKind() 
-  {static std::string MY_KIND = "SketchConstraintDiameter"; return MY_KIND;}
-
-  /// \brief Returns to which group in the document must be added feature
-  SKETCHPLUGIN_EXPORT virtual const std::string& getGroup() 
-  {static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
-
-  /// \brief Creates a new part document if needed
-  SKETCHPLUGIN_EXPORT virtual void execute();
-
-  /// \brief Request for initialization of data model of the feature: adding all attributes
-  SKETCHPLUGIN_EXPORT virtual void initAttributes();
-
-  /// \brief Returns the sketch preview
-  SKETCHPLUGIN_EXPORT virtual const boost::shared_ptr<GeomAPI_Shape>& preview();
-
-  /// \brief Use plugin manager for features creation
-  SketchPlugin_ConstraintDiameter();
-};
-
-#endif
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp b/src/SketchPlugin/SketchPlugin_ConstraintLength.cpp
new file mode 100644 (file)
index 0000000..07a8690
--- /dev/null
@@ -0,0 +1,29 @@
+// File:    SketchPlugin_ConstraintLength.cpp
+// Created: 30 May 2014
+// Author:  Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintLength.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+
+SketchPlugin_ConstraintLength::SketchPlugin_ConstraintLength()
+{
+}
+
+void SketchPlugin_ConstraintLength::initAttributes()
+{
+  data()->addAttribute(CONSTRAINT_ATTR_VALUE,    ModelAPI_AttributeDouble::type());
+  data()->addAttribute(CONSTRAINT_ATTR_ENTITY_A, ModelAPI_AttributeRefAttr::type());
+}
+
+void SketchPlugin_ConstraintLength::execute()
+{
+}
+
+const boost::shared_ptr<GeomAPI_Shape>&  SketchPlugin_ConstraintLength::preview()
+{
+  /// \todo Preview for distance constraint
+  return getPreview();
+}
+
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintLength.h b/src/SketchPlugin/SketchPlugin_ConstraintLength.h
new file mode 100644 (file)
index 0000000..3e4cde4
--- /dev/null
@@ -0,0 +1,44 @@
+// File:    SketchPlugin_ConstraintLength.h
+// Created: 30 May 2014
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchPlugin_ConstraintLength_HeaderFile
+#define SketchPlugin_ConstraintLength_HeaderFile
+
+#include "SketchPlugin.h"
+#include "SketchPlugin_Constraint.h"
+#include <list>
+
+
+/** \class SketchPlugin_ConstraintLength
+ *  \ingroup DataModel
+ *  \brief Feature for creation of a new constraint which defines a length of a line segment
+ *
+ *  These constraint has two attributes:
+ *  CONSTRAINT_ATTR_VALUE (length) and CONSTRAINT_ATTR_ENTITY_A (segment)
+ */
+class SketchPlugin_ConstraintLength: public SketchPlugin_Constraint
+{
+public:
+  /// \brief Returns the kind of a feature
+  SKETCHPLUGIN_EXPORT virtual const std::string& getKind() 
+  {static std::string MY_KIND = "SketchConstraintLength"; return MY_KIND;}
+
+  /// \brief Returns to which group in the document must be added feature
+  SKETCHPLUGIN_EXPORT virtual const std::string& getGroup() 
+  {static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
+
+  /// \brief Creates a new part document if needed
+  SKETCHPLUGIN_EXPORT virtual void execute();
+
+  /// \brief Request for initialization of data model of the feature: adding all attributes
+  SKETCHPLUGIN_EXPORT virtual void initAttributes();
+
+  /// \brief Returns the sketch preview
+  SKETCHPLUGIN_EXPORT virtual const boost::shared_ptr<GeomAPI_Shape>& preview();
+
+  /// \brief Use plugin manager for features creation
+  SketchPlugin_ConstraintLength();
+};
+
+#endif
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp b/src/SketchPlugin/SketchPlugin_ConstraintRadius.cpp
new file mode 100644 (file)
index 0000000..6eb620f
--- /dev/null
@@ -0,0 +1,30 @@
+// File:    SketchPlugin_ConstraintRadius.cpp
+// Created: 26 May 2014
+// Author:  Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintRadius.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <SketchPlugin_Point.h>
+
+SketchPlugin_ConstraintRadius::SketchPlugin_ConstraintRadius()
+{
+}
+
+void SketchPlugin_ConstraintRadius::initAttributes()
+{
+  data()->addAttribute(CONSTRAINT_ATTR_VALUE,    ModelAPI_AttributeDouble::type());
+  data()->addAttribute(CONSTRAINT_ATTR_ENTITY_A, ModelAPI_AttributeRefAttr::type());
+}
+
+void SketchPlugin_ConstraintRadius::execute()
+{
+}
+
+const boost::shared_ptr<GeomAPI_Shape>&  SketchPlugin_ConstraintRadius::preview()
+{
+  /// \todo Preview for diameter constraint
+  return getPreview();
+}
+
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintRadius.h b/src/SketchPlugin/SketchPlugin_ConstraintRadius.h
new file mode 100644 (file)
index 0000000..26a0ecb
--- /dev/null
@@ -0,0 +1,44 @@
+// File:    SketchPlugin_ConstraintRadius.h
+// Created: 26 May 2014
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchPlugin_ConstraintRadius_HeaderFile
+#define SketchPlugin_ConstraintRadius_HeaderFile
+
+#include "SketchPlugin.h"
+#include "SketchPlugin_Constraint.h"
+
+
+/** \class SketchPlugin_ConstraintRadius
+ *  \ingroup DataModel
+ *  \brief Feature for creation of a new constraint which defines 
+ *         a radius of a circle or an arc of circle
+ *
+ *  These constraint has two attributes:
+ *  CONSTRAINT_ATTR_VALUE (radius), CONSTRAINT_ATTR_ENTITY_A (a circle)
+ */
+class SketchPlugin_ConstraintRadius: public SketchPlugin_Constraint
+{
+public:
+  /// \brief Returns the kind of a feature
+  SKETCHPLUGIN_EXPORT virtual const std::string& getKind() 
+  {static std::string MY_KIND = "SketchConstraintRadius"; return MY_KIND;}
+
+  /// \brief Returns to which group in the document must be added feature
+  SKETCHPLUGIN_EXPORT virtual const std::string& getGroup() 
+  {static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
+
+  /// \brief Creates a new part document if needed
+  SKETCHPLUGIN_EXPORT virtual void execute();
+
+  /// \brief Request for initialization of data model of the feature: adding all attributes
+  SKETCHPLUGIN_EXPORT virtual void initAttributes();
+
+  /// \brief Returns the sketch preview
+  SKETCHPLUGIN_EXPORT virtual const boost::shared_ptr<GeomAPI_Shape>& preview();
+
+  /// \brief Use plugin manager for features creation
+  SketchPlugin_ConstraintRadius();
+};
+
+#endif
index bbbbd878e55ae9b791ddae879d7c0b9981293837..23a6cf05a17cc3fb364a10d7f616943df9d71c6b 100644 (file)
@@ -6,9 +6,10 @@
 #include "SketchPlugin_Arc.h"
 #include "SketchPlugin_ConstraintCoincidence.h"
 #include "SketchPlugin_ConstraintDistance.h"
-#include "SketchPlugin_ConstraintDiameter.h"
+#include "SketchPlugin_ConstraintLength.h"
 #include "SketchPlugin_ConstraintParallel.h"
 #include "SketchPlugin_ConstraintPerpendicular.h"
+#include "SketchPlugin_ConstraintRadius.h"
 #include <ModelAPI_PluginManager.h>
 #include <ModelAPI_Document.h>
 
@@ -43,8 +44,8 @@ boost::shared_ptr<ModelAPI_Feature> SketchPlugin_Plugin::createFeature(string th
   else if (theFeatureID == "SketchConstraintDistance") {
     return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintDistance);
   }
-  else if (theFeatureID == "SketchConstraintDiameter") {
-    return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintDiameter);
+  else if (theFeatureID == "SketchConstraintLength") {
+    return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintLength);
   }
   else if (theFeatureID == "SketchConstraintParallel") {
     return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintParallel);
@@ -52,6 +53,9 @@ boost::shared_ptr<ModelAPI_Feature> SketchPlugin_Plugin::createFeature(string th
   else if (theFeatureID == "SketchConstraintPerpendicular") {
     return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintPerpendicular);
   }
+  else if (theFeatureID == "SketchConstraintRadius") {
+    return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintRadius);
+  }
   // feature of such kind is not found
   return boost::shared_ptr<ModelAPI_Feature>();
 }
index ff3007d33ccd65fcf67797bda938336235ff8883..d91e6066c9fd86126cf4a318f0d94d8f649a628e 100644 (file)
@@ -20,7 +20,8 @@
       </feature>
       <feature id="SketchConstraintCoincidence" title="Points coincidence" tooltip="Create constraint for the coincidence of two points" internal="1"/>
       <feature id="SketchConstraintDistance" title="Distance between objects" tooltip="Create constraint for the distance from a point to an object" internal="1"/>
-      <feature id="SketchConstraintDiameter" title="Diameter of a circle" tooltip="Create constraint for the given diameter of a circle" internal="1"/>
+      <feature id="SketchConstraintLength" title="Length of a line" tooltip="Create constraint for the given length of a line segment" internal="1"/>
+      <feature id="SketchConstraintRadius" title="Radius of a circle or an arc" tooltip="Create constraint for the given radius of a circle or an arc" internal="1"/>
       <feature id="SketchConstraintParallel" title="Parallelism of a lines" tooltip="Create constraint defining two parallel lines" internal="1"/>
       <feature id="SketchConstraintPerpendicular" title="Orthgonality of a lines" tooltip="Create constraint defining two perpendicular lines" internal="1"/>
     </group>
index 2bfd8e697780bd2265b8c903347d3d017870868d..2e8a1fae82df22d5e3ba133b0d157b112ea4971e 100644 (file)
@@ -138,6 +138,28 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Const
     return getType();
   }
 
+  // Constraint for the given length of a line
+  if (aConstraintKind.compare("SketchConstraintLength") == 0)
+  {
+    int aNbLines = 0;
+    for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
+    {
+      boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
+        boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
+        );
+      if (!anAttr) continue;
+      if (anAttr->isFeature() && anAttr->feature()->getKind().compare("SketchLine") == 0)
+      {
+        myAttributesList[aNbLines++] = CONSTRAINT_ATTRIBUTES[indAttr];
+        break;
+      }
+    }
+    if (aNbLines == 1)
+      myType = SLVS_C_PT_PT_DISTANCE;
+    return getType();
+  }
+
   // Constraint for two parallel/perpendicular lines
   bool isParallel = (aConstraintKind.compare("SketchConstraintParallel") == 0);
   bool isPerpendicular = (aConstraintKind.compare("SketchConstraintPerpendicular") == 0);
@@ -163,8 +185,8 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Const
     return getType();
   }
 
-  // Constraint for diameter of a circle
-  if (aConstraintKind.compare("SketchConstraintDiameter") == 0)
+  // Constraint for radius of a circle or an arc of circle
+  if (aConstraintKind.compare("SketchConstraintRadius") == 0)
   {
     int aNbEntities = 2; // lines in SolveSpace constraints should started from CONSTRAINT_ATTR_ENTITY_C attribute
     for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
@@ -175,7 +197,7 @@ const int& SketchSolver_Constraint::getType(boost::shared_ptr<SketchPlugin_Const
         );
       if (!anAttr || !anAttr->isFeature()) continue;
       const std::string& aKind = anAttr->feature()->getKind();
-      if (aKind.compare("SketchCircle") == 0)
+      if (aKind.compare("SketchCircle") == 0 || aKind.compare("SketchArc") == 0)
       {
         myAttributesList[aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
         continue;
index 3b8a08211c51475eed4cd5c70dfb7049566c2069..ce1d5f87ef18ebbf337c59edb3ba412f9a65c67d 100644 (file)
@@ -116,7 +116,11 @@ bool SketchSolver_ConstraintGroup::isInteract(
         theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[i])
       );
     if (!aCAttrRef) continue;
-    if (myEntityMap.find(aCAttrRef->attr()) != myEntityMap.end())
+    if (!aCAttrRef->isFeature() && 
+        myEntityAttrMap.find(aCAttrRef->attr()) != myEntityAttrMap.end())
+      return true;
+    if (aCAttrRef->isFeature() && 
+        myEntityFeatMap.find(aCAttrRef->feature()) != myEntityFeatMap.end())
       return true;
   }
 
@@ -166,6 +170,9 @@ bool SketchSolver_ConstraintGroup::changeConstraint(
       myNeedToSolve = true;
       aConstrIter->valA = aDistance;
     }
+    // SketchPlugin circle defined by its radius, but SolveSpace uses constraint for diameter
+    if (aConstrType == SLVS_C_DIAMETER)
+      aDistance *= 2.0;
   }
 
   Slvs_hEntity aConstrEnt[CONSTRAINT_ATTR_SIZE]; // parameters of the constraint
@@ -177,54 +184,30 @@ bool SketchSolver_ConstraintGroup::changeConstraint(
         theConstraint->data()->attribute(aConstraintAttributes[indAttr])
       );
     if (!aConstrAttr) continue;
-    aConstrEnt[indAttr] = changeEntity(aConstrAttr->attr());
+
+    // For the length constraint the start and end points of the line should be added to the entities list instead of line
+    if (aConstrType == SLVS_C_PT_PT_DISTANCE && theConstraint->getKind().compare("SketchConstraintLength") == 0)
+    {
+      boost::shared_ptr<ModelAPI_Data> aData = aConstrAttr->feature()->data();
+      aConstrEnt[indAttr]   = changeEntity(aData->attribute(LINE_ATTR_START));
+      aConstrEnt[indAttr+1] = changeEntity(aData->attribute(LINE_ATTR_END));
+      break; // there should be no other entities
+    }
+    else if (aConstrAttr->isFeature())
+      aConstrEnt[indAttr] = changeEntity(aConstrAttr->feature());
+    else
+      aConstrEnt[indAttr] = changeEntity(aConstrAttr->attr());
   }
 
   if (aConstrMapIter == myConstraintMap.end())
   {
     // Several points may be coincident, it is not necessary to store all constraints between them.
     // Try to find sequence of coincident points which connects the points of new constraint
-    if (aConstrType == SLVS_C_POINTS_COINCIDENT)
+    if (aConstrType == SLVS_C_POINTS_COINCIDENT &&
+        !addCoincidentPoints(aConstrEnt[0], aConstrEnt[1]))
     {
-      std::vector< std::set<Slvs_hEntity> >::iterator aCoPtIter = myCoincidentPoints.begin();
-      std::vector< std::set<Slvs_hEntity> >::iterator aFirstFound = myCoincidentPoints.end();
-      for ( ; aCoPtIter != myCoincidentPoints.end(); aCoPtIter++)
-      {
-        bool isFound[2] = { // indicate which point ID was already in coincidence constraint
-          aCoPtIter->find(aConstrEnt[0]) != aCoPtIter->end(),
-          aCoPtIter->find(aConstrEnt[1]) != aCoPtIter->end(),
-        };
-        if (isFound[0] && isFound[1]) // points are already connected by coincidence constraints => no need additional one
-        {
-          myExtraCoincidence.insert(theConstraint); // the constraint is stored for further purposes
-          return false;
-        }
-        if ((isFound[0] && !isFound[1]) || (!isFound[0] && isFound[1]))
-        {
-          if (aFirstFound != myCoincidentPoints.end())
-          { // there are two groups of coincident points connected by created constraint => merge them
-            int aFirstFoundShift = aFirstFound - myCoincidentPoints.begin();
-            int aCurrentShift = aCoPtIter - myCoincidentPoints.begin();
-            aFirstFound->insert(aCoPtIter->begin(), aCoPtIter->end());
-            myCoincidentPoints.erase(aCoPtIter);
-            aFirstFound = myCoincidentPoints.begin() + aFirstFoundShift;
-            aCoPtIter = myCoincidentPoints.begin() + aCurrentShift;
-          }
-          else
-          {
-            aCoPtIter->insert(aConstrEnt[isFound[0] ? 1 : 0]);
-            aFirstFound = aCoPtIter;
-          }
-        }
-      }
-      // No points were found, need to create new set
-      if (aFirstFound == myCoincidentPoints.end())
-      {
-        std::set<Slvs_hEntity> aNewSet;
-        aNewSet.insert(aConstrEnt[0]);
-        aNewSet.insert(aConstrEnt[1]);
-        myCoincidentPoints.push_back(aNewSet);
-      }
+      myExtraCoincidence.insert(theConstraint); // the constraint is stored for further purposes
+      return false;
     }
 
     // Create SolveSpace constraint structure
@@ -247,9 +230,9 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
 {
   // If the entity is already in the group, try to find it
   std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
-    aEntIter = myEntityMap.find(theEntity);
+    aEntIter = myEntityAttrMap.find(theEntity);
   std::vector<Slvs_Param>::const_iterator aParamIter; // looks at first parameter of already existent entity or at the end of vector otherwise
-  if (aEntIter == myEntityMap.end()) // no such entity => should be created
+  if (aEntIter == myEntityAttrMap.end()) // no such entity => should be created
     aParamIter = myParams.end();
   else
   { // the entity already exists
@@ -257,6 +240,7 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
     int aParamPos = Search(myEntities[aEntPos].param[0], myParams);
     aParamIter = myParams.begin() + aParamPos;
   }
+  const bool isEntExists = (aEntIter != myEntityAttrMap.end()); // defines that the entity already exists
 
   // Look over supported types of entities
 
@@ -269,13 +253,13 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
     Slvs_hParam aY = changeParameter(aPoint->y(), aParamIter);
     Slvs_hParam aZ = changeParameter(aPoint->z(), aParamIter);
 
-    if (aEntIter != myEntityMap.end()) // the entity already exists
+    if (isEntExists)
       return aEntIter->second;
 
     // New entity
     Slvs_Entity aPtEntity = Slvs_MakePoint3d(++myEntityMaxID, myID, aX, aY, aZ);
     myEntities.push_back(aPtEntity);
-    myEntityMap[theEntity] = aPtEntity.h;
+    myEntityAttrMap[theEntity] = aPtEntity.h;
     return aPtEntity.h;
   }
 
@@ -291,13 +275,13 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
     Slvs_hParam aU = changeParameter(aPoint2D->x(), aParamIter);
     Slvs_hParam aV = changeParameter(aPoint2D->y(), aParamIter);
 
-    if (aEntIter != myEntityMap.end()) // the entity already exists
+    if (isEntExists)
       return aEntIter->second;
 
     // New entity
     Slvs_Entity aPt2DEntity = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, aU, aV);
     myEntities.push_back(aPt2DEntity);
-    myEntityMap[theEntity] = aPt2DEntity.h;
+    myEntityAttrMap[theEntity] = aPt2DEntity.h;
     return aPt2DEntity.h;
   }
 
@@ -308,18 +292,39 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
   {
     Slvs_hParam aValue = changeParameter(aScalar->value(), aParamIter);
 
-    if (aEntIter != myEntityMap.end()) // the entity already exists
+    if (isEntExists)
       return aEntIter->second;
 
     // New entity
     Slvs_Entity aDistance = Slvs_MakeDistance(++myEntityMaxID, myID, myWorkplane.h, aValue);
     myEntities.push_back(aDistance);
-    myEntityMap[theEntity] = aDistance.h;
+    myEntityAttrMap[theEntity] = aDistance.h;
     return aDistance.h;
   }
 
+  /// \todo Other types of entities
+
+  // Unsupported or wrong entity type
+  return SLVS_E_UNKNOWN;
+}
+
+
+// ============================================================================
+//  Function: changeEntity
+//  Class:    SketchSolver_ConstraintGroup
+//  Purpose:  create/update the element defined by the feature affected by any constraint
+// ============================================================================
+Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
+                boost::shared_ptr<ModelAPI_Feature> theEntity)
+{
+  // If the entity is already in the group, try to find it
+  std::map<boost::shared_ptr<ModelAPI_Feature>, Slvs_hEntity>::const_iterator
+    aEntIter = myEntityFeatMap.find(theEntity);
+  // defines that the entity already exists
+  const bool isEntExists = (myEntityFeatMap.find(theEntity) != myEntityFeatMap.end());
+
   // SketchPlugin features
-  boost::shared_ptr<SketchPlugin_Feature> aFeature =
+  boost::shared_ptr<SketchPlugin_Feature> aFeature;
     boost::dynamic_pointer_cast<SketchPlugin_Feature>(theEntity);
   if (aFeature)
   { // Verify the feature by its kind
@@ -331,13 +336,13 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
       Slvs_hEntity aStart = changeEntity(aFeature->data()->attribute(LINE_ATTR_START));
       Slvs_hEntity aEnd   = changeEntity(aFeature->data()->attribute(LINE_ATTR_END));
 
-      if (aEntIter != myEntityMap.end()) // the entity already exists
+      if (isEntExists)
         return aEntIter->second;
 
       // New entity
       Slvs_Entity aLineEntity = Slvs_MakeLineSegment(++myEntityMaxID, myID, myWorkplane.h, aStart, aEnd);
       myEntities.push_back(aLineEntity);
-      myEntityMap[theEntity] = aLineEntity.h;
+      myEntityFeatMap[theEntity] = aLineEntity.h;
       return aLineEntity.h;
     }
     // Circle
@@ -346,14 +351,14 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
       Slvs_hEntity aCenter = changeEntity(aFeature->data()->attribute(CIRCLE_ATTR_CENTER));
       Slvs_hEntity aRadius = changeEntity(aFeature->data()->attribute(CIRCLE_ATTR_RADIUS));
 
-      if (aEntIter != myEntityMap.end()) // the entity already exists
+      if (isEntExists)
         return aEntIter->second;
 
       // New entity
       Slvs_Entity aCircleEntity = 
         Slvs_MakeCircle(++myEntityMaxID, myID, myWorkplane.h, aCenter, myWorkplane.normal, aRadius);
       myEntities.push_back(aCircleEntity);
-      myEntityMap[theEntity] = aCircleEntity.h;
+      myEntityFeatMap[theEntity] = aCircleEntity.h;
       return aCircleEntity.h;
     }
     // Arc
@@ -363,13 +368,13 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
       Slvs_hEntity aStart  = changeEntity(aFeature->data()->attribute(ARC_ATTR_START));
       Slvs_hEntity aEnd    = changeEntity(aFeature->data()->attribute(ARC_ATTR_END));
 
-      if (aEntIter != myEntityMap.end()) // the entity already exists
+      if (isEntExists)
         return aEntIter->second;
 
       Slvs_Entity anArcEntity = Slvs_MakeArcOfCircle(++myEntityMaxID, myID, 
                                   myWorkplane.h, myWorkplane.normal, aCenter, aStart, aEnd);
       myEntities.push_back(anArcEntity);
-      myEntityMap[theEntity] = anArcEntity.h;
+      myEntityFeatMap[theEntity] = anArcEntity.h;
       return anArcEntity.h;
     }
     // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
@@ -377,16 +382,16 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
     {
       Slvs_hEntity aPoint = changeEntity(aFeature->data()->attribute(POINT_ATTR_COORD));
 
-      if (aEntIter != myEntityMap.end()) // the entity already exists
+      if (isEntExists)
         return aEntIter->second;
 
       // Both the sketch point and its attribute (coordinates) link to the same SolveSpace point identifier
-      myEntityMap[theEntity] = aPoint;
+      myEntityFeatMap[theEntity] = aPoint;
       return aPoint;
     }
   }
 
-  /// \todo Other types of entities
+  /// \todo Other types of features
 
   // Unsupported or wrong entity type
   return SLVS_E_UNKNOWN;
@@ -420,9 +425,9 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeNormal(
 
   // Try to find existent normal
   std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
-    aEntIter = myEntityMap.find(theNorm);
+    aEntIter = myEntityAttrMap.find(theNorm);
   std::vector<Slvs_Param>::const_iterator aParamIter; // looks to the first parameter of already existent entity or to the end of vector otherwise
-  if (aEntIter == myEntityMap.end()) // no such entity => should be created
+  if (aEntIter == myEntityAttrMap.end()) // no such entity => should be created
     aParamIter = myParams.end();
   else
   { // the entity already exists, update it
@@ -436,14 +441,14 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeNormal(
   for (int i = 0; i < 4; i++)
     aNormParams[i] = changeParameter(aNormCoord[i], aParamIter);
 
-  if (aEntIter != myEntityMap.end()) // the entity already exists
+  if (aEntIter != myEntityAttrMap.end()) // the entity already exists
     return aEntIter->second;
 
   // Create a normal
   Slvs_Entity aNormal = Slvs_MakeNormal3d(++myEntityMaxID, myID,
                 aNormParams[0], aNormParams[1], aNormParams[2], aNormParams[3]);
   myEntities.push_back(aNormal);
-  myEntityMap[theNorm] = aNormal.h;
+  myEntityAttrMap[theNorm] = aNormal.h;
   return aNormal.h;
 }
 
@@ -545,9 +550,10 @@ void SketchSolver_ConstraintGroup::resolveConstraints()
     if (!myConstrSolver.getResult(myParams))
       return;
 
+    // We should go through the attributes map, because only attributes have valued parameters
     std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator
-      anEntIter = myEntityMap.begin();
-    for ( ; anEntIter != myEntityMap.end(); anEntIter++)
+      anEntIter = myEntityAttrMap.begin();
+    for ( ; anEntIter != myEntityAttrMap.end(); anEntIter++)
       updateAttribute(anEntIter->first, anEntIter->second);
   }
   /// \todo Implement error handling
@@ -592,8 +598,8 @@ void SketchSolver_ConstraintGroup::mergeGroups(
   else if (!theGroup.myTempPointWhereDragged.empty())
   { // Need to create additional transient constraint
     std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
-      aFeatureIter = theGroup.myEntityMap.begin();
-    for (; aFeatureIter != theGroup.myEntityMap.end(); aFeatureIter++)
+      aFeatureIter = theGroup.myEntityAttrMap.begin();
+    for (; aFeatureIter != theGroup.myEntityAttrMap.end(); aFeatureIter++)
       if (aFeatureIter->second == myTempPointWDrgdID)
       {
         addTemporaryConstraintWhereDragged(aFeatureIter->first);
@@ -621,6 +627,7 @@ void SketchSolver_ConstraintGroup::splitGroup(std::vector<SketchSolver_Constrain
     Slvs_hEntity aConstrEnt[] = {
       aConstrIter->ptA,     aConstrIter->ptB,
       aConstrIter->entityA, aConstrIter->entityB};
+    std::vector<int> anIndexes;
     // Go through the groupped entities and find even one of entities of current constraint
     std::vector< std::set<Slvs_hEntity> >::iterator aGrEntIter;
     for (aGrEntIter = aGroupsEntities.begin(); aGrEntIter != aGroupsEntities.end(); aGrEntIter++)
@@ -630,18 +637,10 @@ void SketchSolver_ConstraintGroup::splitGroup(std::vector<SketchSolver_Constrain
         if (aConstrEnt[i] != 0)
           isFound = (aGrEntIter->find(aConstrEnt[i]) != aGrEntIter->end());
       if (isFound)
-      {
-        for (int i = 0; i < 4; i++)
-          if (aConstrEnt[i] != 0)
-            aGrEntIter->insert(aConstrEnt[i]);
-        aGroupsConstr[aGrEntIter - aGroupsEntities.begin()].insert(aConstrIter->h);
-        if (aGrEntIter->size() > aGroupsEntities[aMaxNbEntities].size())
-          aMaxNbEntities = aGrEntIter - aGroupsEntities.begin();
-        break;
-      }
+        anIndexes.push_back(aGrEntIter - aGroupsEntities.begin());
     }
     // Add new group if no one is found
-    if (aGrEntIter == aGroupsEntities.end())
+    if (anIndexes.empty())
     {
       std::set<Slvs_hEntity> aNewGrEnt;
       for (int i = 0; i < 4; i++)
@@ -655,6 +654,36 @@ void SketchSolver_ConstraintGroup::splitGroup(std::vector<SketchSolver_Constrain
       if (aNewGrEnt.size() > aGroupsEntities[aMaxNbEntities].size())
         aMaxNbEntities = aGroupsEntities.size() - 1;
     }
+    else if (anIndexes.size() == 1)
+    { // Add entities indexes into the found group
+      for (int i = 0; i < 4; i++)
+        if (aConstrEnt[i] != 0)
+          aGrEntIter->insert(aConstrEnt[i]);
+      aGroupsConstr[aGrEntIter - aGroupsEntities.begin()].insert(aConstrIter->h);
+      if (aGrEntIter->size() > aGroupsEntities[aMaxNbEntities].size())
+        aMaxNbEntities = aGrEntIter - aGroupsEntities.begin();
+    }
+    else 
+    { // There are found several connected groups, merge them
+      std::vector< std::set<Slvs_hEntity> >::iterator aFirstGroup = 
+        aGroupsEntities.begin() + anIndexes.front();
+      std::vector< std::set<Slvs_hConstraint> >::iterator aFirstConstr = 
+        aGroupsConstr.begin() + anIndexes.front();
+      std::vector<int>::iterator anInd = anIndexes.begin();
+      for (++anInd; anInd != anIndexes.end(); anInd++)
+      {
+        aFirstGroup->insert(aGroupsEntities[*anInd].begin(), aGroupsEntities[*anInd].end());
+        aFirstConstr->insert(aGroupsConstr[*anInd].begin(), aGroupsConstr[*anInd].end());
+      }
+      if (aFirstGroup->size() > aGroupsEntities[aMaxNbEntities].size())
+        aMaxNbEntities = anIndexes.front();
+      // Remove merged groups
+      for (anInd = anIndexes.end() - 1; anInd != anIndexes.begin(); anInd--)
+      {
+        aGroupsEntities.erase(aGroupsEntities.begin() + (*anInd));
+        aGroupsConstr.erase(aGroupsConstr.begin() + (*anInd));
+      }
+    }
   }
 
   if (aGroupsEntities.size() <= 1)
@@ -797,7 +826,7 @@ void SketchSolver_ConstraintGroup::updateAttribute(
 void SketchSolver_ConstraintGroup::updateEntityIfPossible(
                 boost::shared_ptr<ModelAPI_Attribute> theEntity)
 {
-  if (myEntityMap.find(theEntity) != myEntityMap.end())
+  if (myEntityAttrMap.find(theEntity) != myEntityAttrMap.end())
   {
     // If the attribute is a point and it is changed (the group needs to rebuild),
     // probably user has dragged this point into this position,
@@ -836,8 +865,8 @@ void SketchSolver_ConstraintGroup::addTemporaryConstraintWhereDragged(
 {
   // Find identifier of the entity
   std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
-    anEntIter = myEntityMap.find(theEntity);
-  if (anEntIter == myEntityMap.end())
+    anEntIter = myEntityAttrMap.find(theEntity);
+  if (anEntIter == myEntityAttrMap.end())
     return ;
 
   // If this is a first dragged point, its parameters should be placed 
@@ -952,17 +981,30 @@ void SketchSolver_ConstraintGroup::removeConstraint(boost::shared_ptr<SketchPlug
 
   // Remove unused entities
   std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator
-    anEntMapIter = myEntityMap.begin();
-  while (anEntMapIter != myEntityMap.end())
+    anEntAttrIter = myEntityAttrMap.begin();
+  while (anEntAttrIter != myEntityAttrMap.end())
   {
-    if (anEntToRemove.find(anEntMapIter->second) != anEntToRemove.end())
+    if (anEntToRemove.find(anEntAttrIter->second) != anEntToRemove.end())
     {
       std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator
-        aRemovedIter = anEntMapIter;
-      anEntMapIter++;
-      myEntityMap.erase(aRemovedIter);
+        aRemovedIter = anEntAttrIter;
+      anEntAttrIter++;
+      myEntityAttrMap.erase(aRemovedIter);
     }
-    else anEntMapIter++;
+    else anEntAttrIter++;
+  }
+  std::map<boost::shared_ptr<ModelAPI_Feature>, Slvs_hEntity>::iterator
+    anEntFeatIter = myEntityFeatMap.begin();
+  while (anEntFeatIter != myEntityFeatMap.end())
+  {
+    if (anEntToRemove.find(anEntFeatIter->second) != anEntToRemove.end())
+    {
+      std::map<boost::shared_ptr<ModelAPI_Feature>, Slvs_hEntity>::iterator
+        aRemovedIter = anEntFeatIter;
+      anEntFeatIter++;
+      myEntityFeatMap.erase(aRemovedIter);
+    }
+    else anEntFeatIter++;
   }
   std::set<Slvs_hEntity>::const_reverse_iterator aRemIter = anEntToRemove.rbegin();
   for ( ; aRemIter != anEntToRemove.rend(); aRemIter++)
@@ -993,6 +1035,58 @@ void SketchSolver_ConstraintGroup::removeConstraint(boost::shared_ptr<SketchPlug
 }
 
 
+// ============================================================================
+//  Function: addCoincidentPoints
+//  Class:    SketchSolver_ConstraintGroup
+//  Purpose:  add coincident point the appropriate list of such points
+// ============================================================================
+bool SketchSolver_ConstraintGroup::addCoincidentPoints(
+                const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2)
+{
+  std::vector< std::set<Slvs_hEntity> >::iterator aCoPtIter = myCoincidentPoints.begin();
+  std::vector< std::set<Slvs_hEntity> >::iterator aFirstFound = myCoincidentPoints.end();
+  while (aCoPtIter != myCoincidentPoints.end())
+  {
+    bool isFound[2] = { // indicate which point ID was already in coincidence constraint
+      aCoPtIter->find(thePoint1) != aCoPtIter->end(),
+      aCoPtIter->find(thePoint2) != aCoPtIter->end(),
+    };
+    if (isFound[0] && isFound[1]) // points are already connected by coincidence constraints => no need additional one
+      return false;
+    if ((isFound[0] && !isFound[1]) || (!isFound[0] && isFound[1]))
+    {
+      if (aFirstFound != myCoincidentPoints.end())
+      { // there are two groups of coincident points connected by created constraint => merge them
+        int aFirstFoundShift = aFirstFound - myCoincidentPoints.begin();
+        int aCurrentShift = aCoPtIter - myCoincidentPoints.begin();
+        aFirstFound->insert(aCoPtIter->begin(), aCoPtIter->end());
+        myCoincidentPoints.erase(aCoPtIter);
+        aFirstFound = myCoincidentPoints.begin() + aFirstFoundShift;
+        aCoPtIter = myCoincidentPoints.begin() + aCurrentShift;
+        continue;
+      }
+      else
+      {
+        aCoPtIter->insert(isFound[0] ? thePoint2 : thePoint1);
+        aFirstFound = aCoPtIter;
+      }
+    }
+    aCoPtIter++;
+  }
+  // No points were found, need to create new set
+  if (aFirstFound == myCoincidentPoints.end())
+  {
+    std::set<Slvs_hEntity> aNewSet;
+    aNewSet.insert(thePoint1);
+    aNewSet.insert(thePoint2);
+    myCoincidentPoints.push_back(aNewSet);
+  }
+
+  return true;
+}
+
+
+
 
 // ========================================================
 // =========      Auxiliary functions       ===============
index fe629046b16ef4ed3b8f9bcd7dce62cfe2b74ae8..7baeac158450944060cc9d49ea54f98aa62afcc0 100644 (file)
@@ -104,6 +104,7 @@ protected:
    *  \return identifier of changed entity or 0 if entity could not be changed
    */
   Slvs_hEntity changeEntity(boost::shared_ptr<ModelAPI_Attribute> theEntity);
+  Slvs_hEntity changeEntity(boost::shared_ptr<ModelAPI_Feature>   theEntity);
 
   /** \brief Adds or updates a normal in the group
    *
@@ -158,6 +159,14 @@ private:
    */
   bool addWorkplane(boost::shared_ptr<SketchPlugin_Feature> theSketch);
 
+  /** \brief Add the entities of constraint for points coincidence into the appropriate list
+   *  \param[in] thePoint1 identifier of the first point
+   *  \param[in] thePoint2 identifier of the second point
+   *  \return \c true if the points are added successfully, and 
+   *          \c false if the constraint is the extra one (should not be created in SolveSpace)
+   */
+  bool addCoincidentPoints(const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2);
+
 private:
   // SolveSpace entities
   Slvs_hGroup                  myID;            ///< the index of the group
@@ -182,7 +191,9 @@ private:
   std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_hConstraint>
                                myConstraintMap; ///< The map between SketchPlugin and SolveSpace constraints
   std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>
-                               myEntityMap;     ///< The map between parameters of constraints and their equivalent SolveSpace entities
+                               myEntityAttrMap;     ///< The map between "attribute" parameters of constraints and their equivalent SolveSpace entities
+  std::map<boost::shared_ptr<ModelAPI_Feature>, Slvs_hEntity>
+                               myEntityFeatMap;     ///< The map between "feature" parameters of constraints and their equivalent SolveSpace entities
 
   // Conincident items
   std::vector< std::set<Slvs_hEntity> >
index 37c78f82a4aec5b3f23d24765e9a8a83bd4b6756..066ebdcae6985bf5c7d038401f4f726f173f98fe 100644 (file)
@@ -1,6 +1,7 @@
 #include "XGUI_DocumentDataModel.h"
 #include "XGUI_PartDataModel.h"
 #include "XGUI_Workshop.h"
+#include "XGUI_Tools.h"
 
 #include <ModelAPI_PluginManager.h>
 #include <ModelAPI_Document.h>
@@ -492,7 +493,7 @@ Qt::ItemFlags XGUI_DocumentDataModel::flags(const QModelIndex& theIndex) const
 QModelIndex XGUI_DocumentDataModel::partIndex(const FeaturePtr& theFeature) const 
 {
   FeaturePtr aFeature = theFeature;
-  if (!aFeature->data()) {
+  if (XGUI_Tools::isModelObject(aFeature)) {
     ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
     aFeature = aObject->featureRef();
   }
index 258a59f8021fe2b6663f57dbac02b351f4151dad..125e1aaf4bc17cd6d52adda9f90296f88e671bb0 100644 (file)
@@ -1,5 +1,6 @@
 #include "XGUI_ObjectsBrowser.h"
 #include "XGUI_DocumentDataModel.h"
+#include "XGUI_Tools.h"
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_PluginManager.h>
@@ -85,7 +86,7 @@ void XGUI_DataTree::commitData(QWidget* theEditor)
     FeaturePtr aFeature = mySelectedData.first();
     PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
     aMgr->rootDocument()->startOperation();
-    if (aFeature->data())
+    if (!XGUI_Tools::isModelObject(aFeature))
       aFeature->data()->setName(qPrintable(aRes));
     else
       boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature)->setName(qPrintable(aRes));
index 3fb2cad89dce5d54dc9705829b0555b0fdc9adb3..514c5b2f116c1f760e975a7dbc1f86efb86bda20 100644 (file)
@@ -115,8 +115,12 @@ bool XGUI_OperationMgr::canStopOperation()
 void XGUI_OperationMgr::onCommitOperation()
 {
   ModuleBase_Operation* anOperation = currentOperation();
-  if (anOperation)
-    anOperation->commit();
+  if (anOperation) {
+    if (anOperation->canBeCommitted())
+      anOperation->commit();
+    else
+      anOperation->abort();
+  }
 }
 
 void XGUI_OperationMgr::onAbortOperation()
index 8ce0a36ac0bcb25349a31bd518513a43d995496f..339d08369551b6128bcff4b93083563a4150848e 100644 (file)
@@ -8,6 +8,8 @@
 #include <iostream>
 #include <sstream>
 
+namespace XGUI_Tools
+{
 //******************************************************************
 QString dir(const QString& path, bool isAbs)
 {
@@ -53,6 +55,12 @@ QRect makeRect(const int x1, const int y1, const int x2, const int y2)
   return QRect(qMin(x1, x2), qMin(y1, y2), qAbs(x2 - x1), qAbs(y2 - y1));
 }
 
+//******************************************************************
+bool isModelObject(boost::shared_ptr<ModelAPI_Feature> theFeature)
+{
+  return theFeature && !theFeature->data();
+}
+
 //******************************************************************
 std::string featureInfo(boost::shared_ptr<ModelAPI_Feature> theFeature)
 {
@@ -62,3 +70,4 @@ std::string featureInfo(boost::shared_ptr<ModelAPI_Feature> theFeature)
   return QString(aStream.str().c_str()).toStdString();
 }
 
+}
\ No newline at end of file
index 5c8be08e85065d082c519e782efa1056285032ac..d20260f8e3046847cc6d0b53c51f0f1e021e2190 100644 (file)
@@ -19,46 +19,58 @@ class ModelAPI_Feature;
  \param abs if true (default) \a path parameter is treated as absolute file path
  \return directory part of the file path
  */
-QString XGUI_EXPORT dir(const QString& path, bool isAbs = true);
+namespace XGUI_Tools
+{
+  QString XGUI_EXPORT dir(const QString& path, bool isAbs = true);
 
-/*!
- \brief Return file name part of the file path.
+  /*!
  \brief Return file name part of the file path.
 
- \param path file path
- \param withExt if true (default) complete file name (with all
- extension except the last) is returned, otherwise only base name
- is returned
- \return file name part of the file path
- */
-QString XGUI_EXPORT file(const QString& path, bool withExt = true);
  \param path file path
  \param withExt if true (default) complete file name (with all
  extension except the last) is returned, otherwise only base name
  is returned
  \return file name part of the file path
  */
+  QString XGUI_EXPORT file(const QString& path, bool withExt = true);
 
-/*!
- \brief Return extension part of the file path.
+  /*!
  \brief Return extension part of the file path.
 
- \param path file path
- \param full if true complete extension (all extensions, dot separated)
- is returned, otherwise (default) only last extension is returned
- \return extension part of the file path 
- */
-QString XGUI_EXPORT extension(const QString& path, bool full = false);
  \param path file path
  \param full if true complete extension (all extensions, dot separated)
  is returned, otherwise (default) only last extension is returned
  \return extension part of the file path 
  */
+  QString XGUI_EXPORT extension(const QString& path, bool full = false);
 
-/*!
- \brief Add a slash (platform-specific) to the end of \a path
- if it is not already there.
- \param path directory path
- \return modified path (with slash added to the end)
- */
-QString XGUI_EXPORT addSlash(const QString& path);
+  /*!
  \brief Add a slash (platform-specific) to the end of \a path
  if it is not already there.
  \param path directory path
  \return modified path (with slash added to the end)
  */
+  QString XGUI_EXPORT addSlash(const QString& path);
 
-/*! 
- Creates a rect with TopLeft = ( min(x1,x2), min(y1,y2) )
- and BottomRight = ( TopLeft + (x2-x1)(y2-y1) )    
- */
-QRect XGUI_EXPORT makeRect(const int x1, const int y1, const int x2, const int y2);
+  /*! 
+   Creates a rect with TopLeft = ( min(x1,x2), min(y1,y2) )
+   and BottomRight = ( TopLeft + (x2-x1)(y2-y1) )    
+   */
+  QRect XGUI_EXPORT makeRect(const int x1, const int y1, const int x2, const int y2);
+
+  /// The model concerning tools
+
+  /*!
+   Returns true if the feature is a model object
+   \param theFeature a feature
+  */
+  bool XGUI_EXPORT isModelObject(boost::shared_ptr<ModelAPI_Feature> theFeature);
+
+  /*!
+   Returns the string presentation of the given feature
+   \param theFeature a feature
+  */
+  std::string XGUI_EXPORT featureInfo(boost::shared_ptr<ModelAPI_Feature> theFeature);
+}
 
-/*!
- Returns the string presentation of the given feature
- \param theFeature a feature
-*/
-std::string XGUI_EXPORT featureInfo(boost::shared_ptr<ModelAPI_Feature> theFeature);
 #endif
index 5a1a9ba4097ed64aeef7c13082fce24c09e0f8ae..7c0bc5d9ac14c8c9e225178db90b52ae4344bf63 100644 (file)
@@ -727,7 +727,7 @@ void XGUI_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
       myCurrX = theEvent->x();
       myCurrY = theEvent->y();
       drawRect();
-      QRect rect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
+      QRect rect = XGUI_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
       if (!rect.isEmpty())
         myViewPort->fitRect(rect);
       endDrawRect();
@@ -859,7 +859,7 @@ void XGUI_ViewWindow::drawRect()
   }
 
   myRectBand->setUpdatesEnabled(false);
-  QRect aRect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
+  QRect aRect = XGUI_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
   myRectBand->initGeometry(aRect);
 
   if (!myRectBand->isVisible())
@@ -1039,7 +1039,7 @@ void XGUI_ViewWindow::dumpView()
     QApplication::setOverrideCursor( Qt::WaitCursor );
     QImage aPicture = myViewPort->dumpView();
 
-    QString aFmt = extension(aFileName).toUpper();
+    QString aFmt = XGUI_Tools::extension(aFileName).toUpper();
     if( aFmt.isEmpty() )
       aFmt = QString( "BMP" ); // default format
     else if( aFmt == "JPG" )
index b21bc9e12be38e40d1e01aa1673d01bccd7e9136..980b8c8e0f28243771c285ceab2c4f9e74a423d9 100644 (file)
@@ -737,7 +737,7 @@ void XGUI_Workshop::changeCurrentDocument(FeaturePtr thePart)
   PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
   if (thePart) {
     DocumentPtr aFeaDoc;
-    if (thePart->data()) {
+    if (!XGUI_Tools::isModelObject(thePart)) {
       aFeaDoc = thePart->data()->docRef("PartDocument")->value();
     } else {
       ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(thePart);
@@ -808,7 +808,7 @@ void XGUI_Workshop::deleteFeatures(QFeatureList theList)
     foreach (FeaturePtr aFeature, theList) {
       if (aFeature->getKind() == "Part") {
         DocumentPtr aDoc;
-        if (aFeature->data()) {
+        if (!XGUI_Tools::isModelObject(aFeature)) {
           aDoc = aFeature->data()->docRef("PartDocument")->value();
         } else {
           ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
@@ -819,7 +819,7 @@ void XGUI_Workshop::deleteFeatures(QFeatureList theList)
           aDoc->close();
         }
       } else {
-        if (!aFeature->data()) {
+        if (XGUI_Tools::isModelObject(aFeature)) {
           ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
           aFeature = aObject->featureRef();
         }