Salome HOME
0022661: EDF GEOM: [HYDRO] Integration of the polyline editor in GEOM
authorskv <skv@opencascade.com>
Mon, 8 Sep 2014 12:07:16 +0000 (16:07 +0400)
committervsr <vsr@opencascade.com>
Fri, 10 Oct 2014 09:29:30 +0000 (13:29 +0400)
79 files changed:
CMakeLists.txt
doc/salome/examples/polyline.py [new file with mode: 0644]
doc/salome/gui/GEOM/images/polyline_dlg.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/polyline_dlg_add_section.png [new file with mode: 0644]
doc/salome/gui/GEOM/images/polyline_dlg_edit_section.png [new file with mode: 0644]
doc/salome/gui/GEOM/input/creating_basic_go.doc
doc/salome/gui/GEOM/input/creating_polyline.doc [new file with mode: 0644]
doc/salome/gui/GEOM/input/tui_polyline.doc [new file with mode: 0644]
idl/GEOM_Gen.idl
src/CMakeLists.txt
src/CurveCreator/CMakeLists.txt
src/CurveCreator/CurveCreator.hxx
src/CurveCreator/CurveCreator_Curve.cxx
src/CurveCreator/CurveCreator_Curve.hxx
src/CurveCreator/CurveCreator_CurveEditor.cxx [deleted file]
src/CurveCreator/CurveCreator_CurveEditor.hxx [deleted file]
src/CurveCreator/CurveCreator_Diff.cxx
src/CurveCreator/CurveCreator_Diff.hxx
src/CurveCreator/CurveCreator_Displayer.cxx [new file with mode: 0644]
src/CurveCreator/CurveCreator_Displayer.hxx [new file with mode: 0644]
src/CurveCreator/CurveCreator_ICurve.cxx [deleted file]
src/CurveCreator/CurveCreator_ICurve.hxx
src/CurveCreator/CurveCreator_Listener.hxx [deleted file]
src/CurveCreator/CurveCreator_Macro.hxx
src/CurveCreator/CurveCreator_NewPointDlg.cxx [deleted file]
src/CurveCreator/CurveCreator_NewPointDlg.h [deleted file]
src/CurveCreator/CurveCreator_NewSectionDlg.cxx [changed mode: 0755->0644]
src/CurveCreator/CurveCreator_NewSectionDlg.h [changed mode: 0755->0644]
src/CurveCreator/CurveCreator_Operation.cxx
src/CurveCreator/CurveCreator_Operation.hxx
src/CurveCreator/CurveCreator_PosPoint.hxx [new file with mode: 0644]
src/CurveCreator/CurveCreator_Section.hxx
src/CurveCreator/CurveCreator_TableView.cxx [new file with mode: 0644]
src/CurveCreator/CurveCreator_TableView.h [new file with mode: 0644]
src/CurveCreator/CurveCreator_TreeView.cxx [changed mode: 0755->0644]
src/CurveCreator/CurveCreator_TreeView.h [changed mode: 0755->0644]
src/CurveCreator/CurveCreator_UndoOptsDlg.cxx [deleted file]
src/CurveCreator/CurveCreator_UndoOptsDlg.h [deleted file]
src/CurveCreator/CurveCreator_Utils.cxx [new file with mode: 0644]
src/CurveCreator/CurveCreator_Utils.hxx [new file with mode: 0644]
src/CurveCreator/CurveCreator_UtilsICurve.cxx [new file with mode: 0644]
src/CurveCreator/CurveCreator_UtilsICurve.hxx [new file with mode: 0644]
src/CurveCreator/CurveCreator_Widget.cxx
src/CurveCreator/CurveCreator_Widget.h
src/EntityGUI/CMakeLists.txt
src/EntityGUI/EntityGUI.cxx
src/EntityGUI/EntityGUI_PolylineDlg.cxx [new file with mode: 0644]
src/EntityGUI/EntityGUI_PolylineDlg.h [new file with mode: 0644]
src/GEOM/GEOM_Function.cxx
src/GEOM/GEOM_Function.hxx
src/GEOMGUI/GEOM_images.ts
src/GEOMGUI/GEOM_msg_en.ts
src/GEOMGUI/GeometryGUI.cxx
src/GEOMGUI/GeometryGUI_Operations.h
src/GEOMImpl/CMakeLists.txt
src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx
src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx
src/GEOMImpl/GEOMImpl_IPolyline2D.cxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_IPolyline2D.hxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_PolylineDriver.cxx
src/GEOMImpl/GEOMImpl_PolylineDriver.hxx
src/GEOMImpl/GEOMImpl_PolylineDumper.cxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_PolylineDumper.hxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_Types.hxx [changed mode: 0755->0644]
src/GEOM_I/GEOM_ICurvesOperations_i.cc
src/GEOM_I/GEOM_ICurvesOperations_i.hh
src/GEOM_I/GEOM_IHealingOperations_i.cc
src/GEOM_I/GEOM_IHealingOperations_i.hh
src/GEOM_I/GEOM_IOperations_i.cc
src/GEOM_I/GEOM_IOperations_i.hh
src/GEOM_SWIG/geomBuilder.py
src/GEOM_SWIG/gsketcher.py
src/OperationGUI/CMakeLists.txt
src/OperationGUI/OperationGUI.cxx
src/SKETCHER/CMakeLists.txt
src/SKETCHER/Sketcher.hxx [new file with mode: 0644]
src/SKETCHER/Sketcher_Profile.hxx
src/SKETCHER/Sketcher_Utils.cxx [new file with mode: 0644]
src/SKETCHER/Sketcher_Utils.hxx [new file with mode: 0644]

index d741a55cc0bd61c08c3a90b1c5bb990493f904ba..91ef62ccb68ea2d1231d8542915ce0d17daefeed 100755 (executable)
@@ -67,20 +67,7 @@ OPTION(SALOME_BUILD_TESTS "Build SALOME tests" ON)
 OPTION(SALOME_BUILD_GUI "Enable GUI" ON)
 CMAKE_DEPENDENT_OPTION(SALOME_GEOM_USE_OPENCV "Enable shape recognition from picture" OFF
                        "SALOME_BUILD_GUI" OFF)
-CMAKE_DEPENDENT_OPTION(SALOME_GEOM_BUILD_CC "Enable curve creator (experimental)" OFF
-                       "SALOME_BUILD_GUI" OFF)
-MARK_AS_ADVANCED(SALOME_BUILD_GUI SALOME_GEOM_USE_OPENCV SALOME_GEOM_BUILD_CC)
-
-# Debug options (!!! FOR DEVELOPERS ONLY !!! TO BE REMOVED LATER !!!)
-IF(CMAKE_BUILD_TYPE MATCHES "^Debug$")
-  CMAKE_DEPENDENT_OPTION(SALOME_GEOM_DEBUG_CC "Debug curve creator" OFF
-                        "SALOME_GEOM_BUILD_CC" OFF)
-  MARK_AS_ADVANCED(SALOME_GEOM_DEBUG_CC)
-
-  IF(SALOME_GEOM_DEBUG_CC)
-    ADD_DEFINITIONS(-DDEBUG_CURVE_CREATOR)
-  ENDIF(SALOME_GEOM_DEBUG_CC)
-ENDIF()
+MARK_AS_ADVANCED(SALOME_BUILD_GUI SALOME_GEOM_USE_OPENCV)
 
 # Prerequisites
 # =============
@@ -242,7 +229,7 @@ SET(_${PROJECT_NAME}_exposed_targets
 )
 IF(SALOME_BUILD_GUI)
   LIST(APPEND _${PROJECT_NAME}_exposed_targets 
-    AdvancedGUI BasicGUI BlocksGUI BooleanGUI BuildGUI DisplayGUI DlgRef EntityGUI GEOMBase
+    AdvancedGUI BasicGUI BlocksGUI BooleanGUI BuildGUI DisplayGUI DlgRef CurveCreator EntityGUI GEOMBase
     GEOMFiltersSelection GEOM GEOMToolsGUI GenerationGUI GroupGUI Material MeasureGUI GEOMObject
     OperationGUI PrimitiveGUI RepairGUI TransformationGUI DependencyTree
     STLPluginGUI BREPPluginGUI STEPPluginGUI IGESPluginGUI XAOPluginGUI VTKPluginGUI
@@ -255,12 +242,6 @@ IF(SALOME_GEOM_USE_OPENCV)
     )
 ENDIF(SALOME_GEOM_USE_OPENCV)
 
-IF(SALOME_GEOM_BUILD_CC)
-  LIST(APPEND _${PROJECT_NAME}_exposed_targets 
-    CurveCreator
-    )
-ENDIF(SALOME_GEOM_BUILD_CC)
-
 # Add all targets to the build-tree export set
 EXPORT(TARGETS ${_${PROJECT_NAME}_exposed_targets}
   FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake)
diff --git a/doc/salome/examples/polyline.py b/doc/salome/examples/polyline.py
new file mode 100644 (file)
index 0000000..8b79256
--- /dev/null
@@ -0,0 +1,48 @@
+# 2D polyline
+
+import salome
+salome.salome_init()
+import GEOM
+from salome.geom import geomBuilder
+geompy = geomBuilder.New(salome.myStudy)
+gg = salome.ImportComponentGUI("GEOM")
+
+# create vertices
+p1 = geompy.MakeVertex(70.,  0.,  0.)
+p2 = geompy.MakeVertex(70., 70., 80.)
+p3 = geompy.MakeVertex( 0., 70.,  0.)
+
+#create a vector from two points
+vector_arc = geompy.MakeVector(p1, p3)
+
+# create an arc from three points
+arc = geompy.MakeArc(p1, p2, p3)
+
+# create a wire
+wire = geompy.MakeWire([vector_arc, arc])
+
+# create a planar face
+isPlanarWanted = 1
+face = geompy.MakeFace(wire, isPlanarWanted)
+
+# Create a 2D polyline with Polyline2D interface
+pl = geompy.Polyline2D()
+pl.addSection("section 1", GEOM.Polyline, True, [0, 0, 10, 0, 10, 10])
+polyline1 = pl.result([100, 0, 0, 1, 1, 1, -1, 1, 0])
+
+pl = geompy.Polyline2D()
+pl.addSection("section 2", GEOM.Interpolation, False)
+pl.addPoints([20, 0, 30, 0, 30, 10])
+polyline2 = pl.result(face)
+
+# add objects in the study
+id_face = geompy.addToStudy(face,"Face")
+id_polyline1 = geompy.addToStudy(polyline1, "Polyline1")
+id_polyline2 = geompy.addToStudy(polyline2, "Polyline2")
+
+# display the first polyline and the second polyline with its planar face
+gg.createAndDisplayGO(id_face)
+gg.setDisplayMode(id_face,1)
+gg.setTransparency(id_face,0.5)
+gg.createAndDisplayGO(id_polyline1)
+gg.createAndDisplayGO(id_polyline2)
diff --git a/doc/salome/gui/GEOM/images/polyline_dlg.png b/doc/salome/gui/GEOM/images/polyline_dlg.png
new file mode 100644 (file)
index 0000000..532817c
Binary files /dev/null and b/doc/salome/gui/GEOM/images/polyline_dlg.png differ
diff --git a/doc/salome/gui/GEOM/images/polyline_dlg_add_section.png b/doc/salome/gui/GEOM/images/polyline_dlg_add_section.png
new file mode 100644 (file)
index 0000000..9a6c1b9
Binary files /dev/null and b/doc/salome/gui/GEOM/images/polyline_dlg_add_section.png differ
diff --git a/doc/salome/gui/GEOM/images/polyline_dlg_edit_section.png b/doc/salome/gui/GEOM/images/polyline_dlg_edit_section.png
new file mode 100644 (file)
index 0000000..69df41e
Binary files /dev/null and b/doc/salome/gui/GEOM/images/polyline_dlg_edit_section.png differ
index 6693b469d61b294e6281b7877342f5e4ad1f2622..efdff95118b5804968425b48b56f36189cf8316e 100644 (file)
@@ -15,6 +15,7 @@ geometrical objects as:
 <li>\subpage create_isoline_page</li>
 <li>\subpage create_sketcher_page</li>
 <li>\subpage create_3dsketcher_page</li>
+<li>\subpage create_polyline_page</li>
 <li>\subpage create_vector_page</li>
 <li>\subpage create_plane_page</li>
 <li>\subpage create_lcs_page</li>
diff --git a/doc/salome/gui/GEOM/input/creating_polyline.doc b/doc/salome/gui/GEOM/input/creating_polyline.doc
new file mode 100644 (file)
index 0000000..7ec3643
--- /dev/null
@@ -0,0 +1,107 @@
+/*!
+
+\page create_polyline_page 2D Polyline
+
+The 2D Polyline allows drawing arbitrary 2D shapes. 
+
+To create a <b>2D Polyline</b> select in the main menu  <b>New Entity -> Basic -> 2D Polyline</b>.
+
+\image html polyline_dlg.png
+
+A polyline represents a section or a set of sections. Each section is constructed from a sequence of 2D points
+connected either by linear setgments or an interpolation curve. Every section has its own attributes:
+- \b Name, 
+- \b Type (Polyline or Spline),
+- \b Closed flag.
+
+A Polyline created represents a shape that lies on the XOY plane. It can have the following types:
+- \b Vertex for a single section with only 1 point.
+- \b Wire for a single section with 2 or more points. A Wire can have multiple edges for more then 2 points if the section type is Polyline.
+A single edge in the result wire is obtained for a Spline or Polyline with 2 points.
+- \b Compound of Wires and/or Vertices if there are several sections.
+
+For the moment only one reference coordinate system for polyline creation is supported. The XOY plane of the <b>Global coordinate system</b>
+is suggested. Implementation of another reference coordinate system is a subject of further development of this functionality.
+Restore button orientates the viewer correspondingly to the chosen working plane and fits the scene to show all objects.
+For the moment this button works with only one plane.
+
+It is possible to import a shape in this dialog using <b>Import polyline</b> selection button. To do it an imported object should satisfy conditions
+for polyline shapes mentioned above. If a valid shape is selected, when dialog is opened, it is initialized by this shape.
+Though the shape can be on any plane, an imported polyline will be defined on XOY plane only due to the limitation.
+
+The group \b Sections in this dialog represents the Polyline construction framework. Its toolbar has the following operations:
+- \b Undo
+- \b Redo
+- <b>Insert new section</b>
+- <b>Addition mode</b>
+- <b>Modification mode</b> - not implemented
+- <b>Detection mode</b> - not implemented
+- \b Remove
+- <b>Join selected sections</b>
+
+<b>Undo/Redo</b> buttons allows to undo/redo changes of the polyline.
+
+<b>Insert new section</b> button opens a dialog that allows to add a new section:
+
+\image html polyline_dlg_add_section.png
+
+In this dialog it is possible to choose:
+- \b Name of section
+- \b Type of section
+- \b Closed flag
+
+To create a new section \b Add button should be clicked. \b Cancel button is used to cancel this operation.
+After clicking \b Add button a new section is appeared on the list. Its name supplemented by its type and closedness
+information (see icon) and the number of points (equal to 0 after creation).
+
+To modify section parameters it is possible to double-click on a section in the list. In this case the following dialog appears:
+
+\image html polyline_dlg_edit_section.png
+
+To apply modifications the button \b Ok should be clicked.
+
+<b>Addition mode</b> allows to add points to a section. It is necessary to select a particular section in a list of sections
+and make some mouse clicks in the viewer. A section preview is recomputed after each click.
+
+<b>Modification mode</b> and <b>Detection mode</b> are not implemented for the moment.
+
+\b Remove button allows to remove a section. It is available if all modes are deactivated and one section is selected.
+
+<b>Join selected sections</b> button is available in modification mode if two or more sections are selected. It is used to
+merge several sections into the first one from selection list. Joined section has parameters of the first selected one. Points of
+the other sections are appended at the end of the list of the first section points.
+
+Some actions are available via popup menu by right mouse button click.
+
+If all modes are deactivated:
+- <b>Join all sections</b> - join all defined sections into the first one.
+- \b Join - join sections. Available if two or more sections are selected.
+
+In <b>Addition mode</b>:
+- <b>Join all sections</b> - join all defined sections into the first one.
+
+In <b>Modification mode</b>:
+- <b>Join all sections</b> - join all defined sections into the first one.
+- \b Join - join sections. Available if two or more sections are selected.
+- <b>Clear all</b> - remove all sections. Available if at least one section is selected.
+- <b>Set closed</b> - set all selected section's Closed flag. Available if at least one section is selected.
+- <b>Set open</b>  - reset all selected section's Closed flag. Available if at least one section is selected.
+- <b>Set polyline</b> - set all selected section's type to Polyline. Available if at least one section is selected.
+- <b>Set spline</b>  - set all selected section's type to Spline. Available if at least one section is selected.
+
+In <b>Detection mode</b>:
+- <b>Join all sections</b> - join all defined sections into the first one.
+- \b Join - join sections. Available if two or more sections are selected.
+
+<h2>TUI Commands</h2>
+
+
+To create the 2D polyline in TUI Polyline2D interface is used.
+
+<em>pl = geompy.Polyline2D()</em> - returns an instance of Polyline2D interface <i>pl</i>.
+
+See the \ref gsketcher.Polyline2D "Polyline2D" interface documentation for more information.
+
+Our <b>TUI Scripts</b> provide you with useful examples of the use of
+\ref tui_polyline_page "2D Polyline".
+*/
diff --git a/doc/salome/gui/GEOM/input/tui_polyline.doc b/doc/salome/gui/GEOM/input/tui_polyline.doc
new file mode 100644 (file)
index 0000000..ff83b90
--- /dev/null
@@ -0,0 +1,6 @@
+/*!
+
+\page tui_polyline_page 2D Polyline
+\tui_script{polyline.py}
+
+*/
index 076f4fed4ce7cbf245c0547fc5105345d7af742d..8863bae2696b537bc7257d2d8c73dce00ec46bf9 100644 (file)
@@ -164,7 +164,8 @@ module GEOM
   /*!
    * \brief Kind of the curves.
    *
-   * Used in the functions GEOM_ICurvesOperations.MakeCurveParametric(), GEOM_ICurvesOperations.MakeCurveParametricNew()
+   * Used in the functions GEOM_ICurvesOperations.MakeCurveParametric(), GEOM_ICurvesOperations.MakeCurveParametricNew(),
+   * GEOM_ICurvesOperations.MakePolyline2D, GEOM_ICurvesOperations.MakePolyline2DOnPlane.
    */
   enum curve_type {
     /*! Polyline curve */
@@ -208,11 +209,12 @@ module GEOM
   };
 
 
-  typedef sequence<string>      string_array;
-  typedef sequence<short>       short_array;
-  typedef sequence<boolean>     ListOfBool;
-  typedef sequence<long>        ListOfLong;
-  typedef sequence<double>      ListOfDouble;
+  typedef sequence<string>       string_array;
+  typedef sequence<short>        short_array;
+  typedef sequence<boolean>      ListOfBool;
+  typedef sequence<long>         ListOfLong;
+  typedef sequence<double>       ListOfDouble;
+  typedef sequence<ListOfDouble> ListOfListOfDouble;
 
   interface GEOM_Object;
   interface GEOM_BaseObject;
@@ -3332,6 +3334,72 @@ module GEOM
      *  \return New GEOM_Object, containing the created wire.
      */
     GEOM_Object Make3DSketcher (in ListOfDouble theCoordinates);
+
+    /*!
+     *  \brief Create a 2D polyline (wire or a compound of wires).
+     *
+     *  The polyline can have several sections. Each section represents a set
+     *  of points in the form of list of coordinates of the following order:
+     *  x1, y1, x2, y2, ..., xN, yN
+     *  Each section has its own name, type of curve (can be either
+     *  GEOM::Polyline or GEOM::Interpolation) and Closed flag.
+     *  For each section a wire is created. It represents either a polyline or
+     *  interpolation BSpline either closed or not depending on the Closed flag.
+     *  The result represents a wire if there is only one section is defined.
+     *  Otherwise a compound of wires is returned.
+     *
+     *  \param theCoordsList the list of coordinates list. theCoordsList[0]
+     *         is the coordinates list of the first section. theCoordsList[1]
+     *         is for the second section etc.
+     *  \param theNamesList the list of names. The order corresponds to
+     *         theCoordsList.
+     *  \param theTypesList the list of curve types. The order corresponds to
+     *         theCoordsList.
+     *  \param theClosedList the list of Closed flags. The order corresponds to
+     *         theCoordsList.
+     *  \param theWorkingPlane 9 double values, defining origin,
+     *         OZ and OX directions of the working plane.
+     *  \return New GEOM_Object, containing the created wire or a compound
+     *          of wires.
+     */
+    GEOM_Object MakePolyline2D (in ListOfListOfDouble theCoordsList,
+                                in string_array       theNamesList,
+                                in short_array        theTypesList,
+                                in ListOfBool         theClosedList,
+                                in ListOfDouble       theWorkingPlane);
+
+    /*!
+     *  \brief Create a 2D polyline (wire or a compound of wires).
+     *
+     *  The polyline can have several sections. Each section represents a set
+     *  of points in the form of list of coordinates of the following order:
+     *  x1, y1, x2, y2, ..., xN, yN
+     *  Each section has its own name, type of curve (can be either
+     *  GEOM::Polyline or GEOM::Interpolation) and Closed flag.
+     *  For each section a wire is created. It represents either a polyline or
+     *  interpolation BSpline either closed or not depending on the Closed flag.
+     *  The result represents a wire if there is only one section is defined.
+     *  Otherwise a compound of wires is returned.
+     *
+     *  \param theCoordsList the list of coordinates list. theCoordsList[0]
+     *         is the coordinates list of the first section. theCoordsList[1]
+     *         is for the second section etc.
+     *  \param theNamesList the list of names. The order corresponds to
+     *         theCoordsList.
+     *  \param theTypesList the list of curve types. The order corresponds to
+     *         theCoordsList.
+     *  \param theClosedList the list of Closed flags. The order corresponds to
+     *         theCoordsList.
+     *  \param theWorkingPlane planar Face or LCS(Marker) of the working plane.
+     *  \return New GEOM_Object, containing the created wire or a compound
+     *          of wires.
+     */
+    GEOM_Object MakePolyline2DOnPlane (in ListOfListOfDouble theCoordsList,
+                                       in string_array       theNamesList,
+                                       in short_array        theTypesList,
+                                       in ListOfBool         theClosedList,
+                                       in GEOM_Object        theWorkingPlane);
+
   };
 
  // # GEOM_ILocalOperations:
index 7c10ef0d46bf1359159233c34ceed3ec97d18a8d..b4f792af168280ad432e6dfaafb9c5ec7560b762 100755 (executable)
@@ -27,15 +27,6 @@ SET(SUBDIRS_COMMON
   STLPlugin BREPPlugin STEPPlugin IGESPlugin XAOPlugin VTKPlugin
   )
 
-##
-# Curve creator
-##
-IF(SALOME_GEOM_BUILD_CC)
-  SET(SUBDIRS_CC
-    CurveCreator
-    )
-ENDIF()
-
 ##
 # OPENCV
 ##
@@ -52,7 +43,7 @@ IF(SALOME_BUILD_GUI)
   SET(SUBDIRS_GUI
     OBJECT DlgRef GEOMFiltersSelection Material GEOMGUI
     GEOMBase DependencyTree GEOMToolsGUI DisplayGUI BasicGUI PrimitiveGUI GenerationGUI
-    EntityGUI BuildGUI BooleanGUI TransformationGUI OperationGUI
+    CurveCreator EntityGUI BuildGUI BooleanGUI TransformationGUI OperationGUI
     RepairGUI MeasureGUI GroupGUI BlocksGUI AdvancedGUI
     GEOM_SWIG_WITHIHM
     )
index 34582d31c73ed3a0d84c20c9f64d953ff04e16ae..15677b68ca95916d38877be7de81518b37bc7c33 100644 (file)
@@ -57,9 +57,8 @@ IF(SALOME_BUILD_GUI)
   # header files / to be processed by moc
   SET(_moc_HEADERS
     CurveCreator_NewSectionDlg.h
-    CurveCreator_NewPointDlg.h
+    CurveCreator_TableView.h
     CurveCreator_TreeView.h
-#    CurveCreator_UndoOptsDlg.h
     CurveCreator_Widget.h
   )
 ENDIF(SALOME_BUILD_GUI)
@@ -68,13 +67,15 @@ ENDIF(SALOME_BUILD_GUI)
 SET(_other_HEADERS
   CurveCreator.hxx
   CurveCreator_Curve.hxx
-  CurveCreator_CurveEditor.hxx
   CurveCreator_Diff.hxx
+  CurveCreator_Displayer.hxx
   CurveCreator_ICurve.hxx
-  CurveCreator_Listener.hxx
   CurveCreator_Macro.hxx
   CurveCreator_Operation.hxx
+  CurveCreator_PosPoint.hxx
   CurveCreator_Section.hxx
+  CurveCreator_UtilsICurve.hxx
+  CurveCreator_Utils.hxx
 )
 
 # header files / to install
@@ -90,17 +91,17 @@ ENDIF(SALOME_BUILD_GUI)
 # sources / static
 SET(_other_SOURCES
   CurveCreator_Curve.cxx
-  CurveCreator_CurveEditor.cxx
   CurveCreator_Diff.cxx
-  CurveCreator_ICurve.cxx
+  CurveCreator_Displayer.cxx
   CurveCreator_Operation.cxx
+  CurveCreator_Utils.cxx
+  CurveCreator_UtilsICurve.cxx
 )
 IF(SALOME_BUILD_GUI)
   LIST(APPEND _other_SOURCES
-    CurveCreator_NewPointDlg.cxx
     CurveCreator_NewSectionDlg.cxx
+    CurveCreator_TableView.cxx
     CurveCreator_TreeView.cxx
-#    CurveCreator_UndoOptsDlg.cxx
     CurveCreator_Widget.cxx
   )
 ENDIF(SALOME_BUILD_GUI)
index 74a3faec45cf89926b4e5d88aceca9ab11a1f3d2..9cd7ec720723ca117438fbac5f5e60928be73ae7 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #define _CurveCreator_HeaderFile
 
 #include <deque>
+#include <map>
+#include <list>
+
+struct CurveCreator_Section;
+struct CurveCreator_PosPoint;
 
 namespace CurveCreator
 {
-
-  //! Dimension of the curve
-  enum Dimension
-  {
-    Dim2d = 2,
-    Dim3d = 3
-  };
-
-  //! Type of the section
-  enum Type
-  {
-    Polyline,
-    BSpline
-  };
-
   //! Points coordinates
   typedef float TypeCoord;
 
+  /** List of coordinates in format depends on section dimension:
+   *  2D: [x1, y1,     x2, y2,     x3, y3,     ..]
+   *  3D: [x1, y1, z1, x2, y2, z2, x3, y3, z3, ..]
+   */
   typedef std::deque<TypeCoord> Coordinates;
 
+  //! List of sections
+  typedef std::deque<CurveCreator_Section *> Sections;
+
+  // List of positioned points (points with coordinates)
+  typedef std::list<CurveCreator_PosPoint*> PosPointsList;
+  //! Map of sections with positioned points
+  typedef std::map<int,PosPointsList> SectionsMap;
 };
 
 #endif
index b4fa90ffc18256572ea28dc0c29cc38eccb34a45..e20705c46b2c779655a90a8df2a3e08dd893c831 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // Author:      Sergey KHROMOV
 
 #include "CurveCreator_Curve.hxx"
+
+#include "CurveCreator.hxx"
+#include "CurveCreator_PosPoint.hxx"
 #include "CurveCreator_Section.hxx"
-#include "CurveCreator_Listener.hxx"
+#include "CurveCreator_Displayer.hxx"
+#include "CurveCreator_Utils.hxx"
+
+#include <AIS_Shape.hxx>
+#include <AIS_InteractiveObject.hxx>
+#include <Geom_CartesianPoint.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Lin.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Wire.hxx>
 
 #include <stdio.h>
 
 // function: Constructor
 // purpose:
 //=======================================================================
-CurveCreator_Curve::CurveCreator_Curve
-                (const CurveCreator::Dimension theDimension)
-: CurveCreator_ICurve(theDimension)
+CurveCreator_Curve::CurveCreator_Curve( const CurveCreator::Dimension theDimension )
+: myIsLocked  (false),
+  myDimension (theDimension),
+  myDisplayer (NULL),
+  myAISShape  (NULL),
+  myNbUndos   (0),
+  myNbRedos   (0),
+  myUndoDepth (-1),
+  myOpLevel(0),
+  mySkipSorting(false)
+{
+}
+
+//=======================================================================
+// function: Destructor
+// purpose:
+//=======================================================================
+CurveCreator_Curve::~CurveCreator_Curve()
+{
+  // Delete all allocated data.
+  clear();
+}
+
+//=======================================================================
+// function: getDimension
+// purpose:
+//=======================================================================
+CurveCreator::Dimension CurveCreator_Curve::getDimension() const
+{
+  return myDimension;
+}
+
+//=======================================================================
+// function: getUniqSectionName
+// purpose: return unique section name
+//=======================================================================
+std::string CurveCreator_Curve::getUniqSectionName() const
+{
+    CurveCreator_Section* aSection;
+    for( int i = 0 ; i < 1000000 ; i++ ){
+        char aBuffer[255];
+        sprintf( aBuffer, "Section_%d", i+1 );
+        std::string aName(aBuffer);
+        int j;
+        for( j = 0 ; j < mySections.size() ; j++ ){
+            aSection = getSection( j );
+            if ( aSection && aSection->myName == aName )
+              break;
+        }
+        if( j == mySections.size() )
+            return aName;
+    }
+    return "";
+}
+
+//=======================================================================
+// function: setDisplayer
+// purpose: set curve changes Displayer
+//=======================================================================
+void CurveCreator_Curve::setDisplayer( CurveCreator_Displayer* theDisplayer )
+{
+  myDisplayer = theDisplayer;
+}
+
+//=======================================================================
+// function: getDisplayer
+// purpose: get curve changes Displayer
+//=======================================================================
+CurveCreator_Displayer* CurveCreator_Curve::getDisplayer()
+{
+  return myDisplayer;
+}
+
+//=======================================================================
+// function: removeDisplayer
+// purpose: remove the attached Displayer
+//=======================================================================
+void CurveCreator_Curve::removeDisplayer()
 {
+  myDisplayer = NULL;
 }
 
 //=======================================================================
-// function: addPoints
+// function: addDiff
 // purpose:
 //=======================================================================
-void CurveCreator_Curve::addPoints
-   (const CurveCreator::Coordinates &thePoints, const int theISection)
+bool CurveCreator_Curve::addEmptyDiff()
+{
+  bool isEnabled = false;
+
+  if (myUndoDepth != 0) {
+    // Forget all Redos after the current one.
+    if (myNbRedos > 0) {
+      myNbRedos = 0;
+      myListDiffs.erase(myCurrenPos, myListDiffs.end());
+    }
+
+    if (myUndoDepth == -1 || myNbUndos < myUndoDepth) {
+      // Increase the number of undos.
+      myNbUndos++;
+    } else {
+      // If there are too many differences, remove the first one.
+      myListDiffs.pop_front();
+    }
+
+    // Add new difference.
+    myListDiffs.push_back(CurveCreator_Diff());
+    myCurrenPos = myListDiffs.end();
+    isEnabled = true;
+  }
+
+  return isEnabled;
+}
+
+void CurveCreator_Curve::startOperation()
+{
+    myOpLevel++;
+}
+
+void CurveCreator_Curve::finishOperation()
+{
+   myOpLevel--;
+}
+
+//=======================================================================
+// function: toICoord
+// purpose:
+//=======================================================================
+int CurveCreator_Curve::toICoord(const int theIPnt) const
+{
+  return theIPnt * myDimension;
+}
+
+//=======================================================================
+// function: setUndoDepth
+// purpose:
+//=======================================================================
+void CurveCreator_Curve::setUndoDepth(const int theDepth)
+{
+  if (theDepth == 0) {
+    // Reset all undo/redo data.
+    myNbUndos = 0;
+    myNbRedos = 0;
+    myListDiffs.clear();
+    myCurrenPos = myListDiffs.end();
+    myUndoDepth = 0;
+  } else if (theDepth == -1) {
+    // There is nothing to do as the depth become unlimited.
+    myUndoDepth = -1;
+  } else if (theDepth > 0) {
+    // The new "real" depth is set.
+    if (theDepth < myNbRedos) {
+      // The new depth is less then number of redos. Remove the latest redos.
+      int aShift = (myNbRedos - theDepth);
+      ListDiff::iterator aFromPos = myListDiffs.end();
+
+      while (aShift--) {
+        aFromPos--;
+      }
+
+      myListDiffs.erase(aFromPos, myListDiffs.end());
+      myNbRedos = theDepth;
+    }
+
+    if (theDepth < myNbUndos + myNbRedos) {
+      // The new depth is less then the total number of differences.
+      // Remove the first undos.
+      int aShift = (myNbUndos + myNbRedos - theDepth);
+      ListDiff::iterator aToPos = myListDiffs.begin();
+
+      while (aShift--) {
+        aToPos++;
+      }
+
+      myListDiffs.erase(myListDiffs.begin(), aToPos);
+      myNbUndos = theDepth - myNbRedos;
+    }
+
+    myUndoDepth = theDepth;
+  }
+}
+
+//=======================================================================
+// function: getUndoDepth
+// purpose:
+//=======================================================================
+int CurveCreator_Curve::getUndoDepth() const
+{
+  return myUndoDepth;
+}
+
+void CurveCreator_Curve::getCoordinates( int theISection, int theIPoint, double& theX, double& theY, double& theZ ) const
+{
+  CurveCreator::Coordinates aCoords = getPoint( theISection, theIPoint );
+  theX = aCoords[0];
+  theY = aCoords[1];
+  theZ = 0.;
+  if( getDimension() == CurveCreator::Dim3d ){
+    theZ = aCoords[2];
+  }
+}
+
+void CurveCreator_Curve::redisplayCurve()
+{
+  if( myDisplayer ) {
+    myDisplayer->eraseAll( false );
+    myAISShape = NULL;
+
+    myDisplayer->display( getAISObject( true ), true );
+  }
+}
+
+//! For internal use only! Undo/Redo are not used here.
+bool CurveCreator_Curve::moveSectionInternal(const int theISection,
+                                             const int theNewIndex)
+{
+  bool res = false;
+  int aMovedSectionId = theISection >= 0 ? theISection : mySections.size()-1;
+
+  if (aMovedSectionId != theNewIndex) {
+    CurveCreator_Section* aSection = getSection( aMovedSectionId );
+
+    // Remove section
+    CurveCreator::Sections::iterator anIter = mySections.begin() + aMovedSectionId;
+
+    mySections.erase(anIter);
+
+    // Insert section.
+    anIter = mySections.begin() + theNewIndex;
+    mySections.insert(anIter, aSection);
+    res = true;
+  }
+  return res;
+}
+
+//=======================================================================
+// function: moveSection
+// purpose:
+//=======================================================================
+bool CurveCreator_Curve::moveSection(const int theISection,
+                                     const int theNewIndex)
+{
+  bool res = false;
+  // Set the difference.
+  startOperation();
+  if (addEmptyDiff()) {
+    myListDiffs.back().init(this, CurveCreator_Operation::MoveSection,
+                            theISection, theNewIndex);
+  }
+
+  // Update the curve.
+  res = moveSectionInternal(theISection, theNewIndex);
+  finishOperation();
+  return res;
+}
+
+/************   Implementation of INTERFACE methods   ************/
+
+/***********************************************/
+/***          Undo/Redo methods              ***/
+/***********************************************/
+
+//! Get number of available undo operations
+int CurveCreator_Curve::getNbUndo() const
+{
+  return myNbUndos;
+}
+
+//! Undo previous operation
+bool CurveCreator_Curve::undo()
+{
+  bool res = false;
+  if (myNbUndos > 0) {
+    myNbUndos--;
+    myNbRedos++;
+    myCurrenPos--;
+    myCurrenPos->applyUndo(this);
+    res = true;
+  }
+  return res;
+}
+
+//! Get number of available redo operations
+int CurveCreator_Curve::getNbRedo() const
+{
+  return myNbRedos;
+}
+
+//! Redo last previously "undone" operation
+bool CurveCreator_Curve::redo()
+{
+  bool res = false;
+  if (myNbRedos > 0) {
+    myCurrenPos->applyRedo(this);
+    myCurrenPos++;
+    myNbRedos--;
+    myNbUndos++;
+    res = true;
+  }
+  return res;
+}
+
+/***********************************************/
+/***           Section methods               ***/
+/***********************************************/
+//! For internal use only! Undo/Redo are not used here.
+bool CurveCreator_Curve::clearInternal()
+{
+  // erase curve from the viewer
+  if( myDisplayer ) {
+    myDisplayer->eraseAll( true );
+    myAISShape = NULL;
+  }
+  // Delete all allocated data.
+  int i = 0;
+  const int aNbSections = getNbSections();
+
+  CurveCreator_Section* aSection;
+  for (; i < aNbSections; i++) {
+    aSection = getSection( i );
+    if ( aSection )
+      delete aSection;
+  }
+
+  mySections.clear();
+  
+  return true;
+}
+
+//=======================================================================
+// function: clear
+// purpose:
+//=======================================================================
+bool CurveCreator_Curve::clear()
+{
+  bool res = false;
+  startOperation();
+  // Set the difference.
+  if (addEmptyDiff()) {
+    myListDiffs.back().init(this);
+  }
+  res = clearInternal();
+  finishOperation();
+  return res;
+}
+
+//! For internal use only! Undo/Redo are not used here.
+bool CurveCreator_Curve::joinInternal( const std::list<int>& theSections )
+{
+  bool res = false;
+  if ( theSections.empty() )
+    return res;
+
+  int anISectionMain = theSections.front();
+  CurveCreator_Section* aSectionMain = getSection( anISectionMain );
+
+  std::list <int> aSectionsToJoin = theSections;
+  aSectionsToJoin.erase( aSectionsToJoin.begin() ); // skip the main section
+  // it is important to sort and reverse the section ids in order to correctly remove them
+  aSectionsToJoin.sort();
+  aSectionsToJoin.reverse();
+
+  std::list<int>::const_iterator anIt = aSectionsToJoin.begin(), aLast = aSectionsToJoin.end();
+  CurveCreator_Section* aSection;
+  for (; anIt != aLast; anIt++) {
+    aSection = getSection( *anIt );
+    aSectionMain->myPoints.insert(aSectionMain->myPoints.end(), aSection->myPoints.begin(),
+                                  aSection->myPoints.end());
+    res = removeSectionInternal(*anIt);
+    if ( !res )
+      break;
+  }
+
+  redisplayCurve();
+  return res;
+}
+
+bool CurveCreator_Curve::join( const std::list<int>& theSections )
+{
+  bool res = false;
+
+  if ( !theSections.empty() )
+  {
+    startOperation();
+    if (addEmptyDiff())
+      myListDiffs.back().init(this, CurveCreator_Operation::Join, theSections);
+
+    res = joinInternal( theSections );
+
+    finishOperation();
+  }
+  return res;
+}
+
+//! Get number of sections
+int CurveCreator_Curve::getNbSections() const
+{
+  return mySections.size();
+}
+
+//! For internal use only! Undo/Redo are not used here.
+int CurveCreator_Curve::addSectionInternal
+        (const std::string& theName, const CurveCreator::SectionType theType,
+         const bool theIsClosed, const CurveCreator::Coordinates &thePoints)
+{
+  CurveCreator_Section *aSection = new CurveCreator_Section;
+
+  std::string aName = theName;
+  if( aName.empty() ){
+      aName = getUniqSectionName();
+  }
+  aSection->myName     = aName;
+  aSection->myType     = theType;
+  aSection->myIsClosed = theIsClosed;
+  aSection->myPoints   = thePoints;
+  mySections.push_back(aSection);
+  redisplayCurve();
+  return mySections.size()-1;
+}
+
+//=======================================================================
+// function: addSection
+// purpose: adds an empty section
+//=======================================================================
+int CurveCreator_Curve::addSection
+        (const std::string& theName, const CurveCreator::SectionType theType,
+         const bool theIsClosed)
+{
+  int resISection = -1;
+  // Set the difference.
+  startOperation();
+  CurveCreator::Coordinates aCoords; //empty list
+  if (addEmptyDiff()) {
+    myListDiffs.back().init(this, CurveCreator_Operation::AddSection,
+                            theName, aCoords, theType, theIsClosed);
+  }
+
+  resISection = addSectionInternal(theName, theType, theIsClosed, aCoords);
+
+  finishOperation();
+  return resISection;
+}
+//=======================================================================
+// function: addSection
+// purpose: adds a section with the given points
+//=======================================================================
+int CurveCreator_Curve::addSection
+        (const std::string& theName, const CurveCreator::SectionType theType,
+         const bool theIsClosed, const CurveCreator::Coordinates &thePoints)
+{
+  int resISection = -1;
+  // Set the difference.
+  startOperation();
+  if (addEmptyDiff()) {
+    myListDiffs.back().init(this, CurveCreator_Operation::AddSection,
+                            theName, thePoints, theType, theIsClosed);
+  }
+
+  resISection = addSectionInternal(theName, theType, theIsClosed, thePoints);
+
+  finishOperation();
+  return resISection;
+}
+
+//! For internal use only! Undo/Redo are not used here.
+bool CurveCreator_Curve::removeSectionInternal( const int theISection )
+{
+  if (theISection == -1) {
+    delete mySections.back();
+    mySections.pop_back();
+  } else {
+    CurveCreator::Sections::iterator anIterRm = mySections.begin() + theISection;
+
+    delete *anIterRm;
+    mySections.erase(anIterRm);
+  }
+  redisplayCurve();
+  return true;
+}
+  
+//! Removes the given sections.
+bool CurveCreator_Curve::removeSection( const int theISection )
+{
+  bool res = false;
+  // Set the difference.
+  startOperation();
+  if (addEmptyDiff())
+    myListDiffs.back().init(this, CurveCreator_Operation::RemoveSection, theISection);
+
+  res = removeSectionInternal( theISection );
+
+  finishOperation();
+  return res;
+}
+
+/**
+ *  Get number of points in specified section or (the total number of points
+ *  in Curve if theISection is equal to -1).
+ */
+int CurveCreator_Curve::getNbPoints( const int theISection ) const
+{
+  int aNbCoords = 0;
+
+  CurveCreator_Section* aSection;
+  if (theISection == -1) {
+    int i = 0;
+    const int aNbSections = getNbSections();
+
+    for (; i < aNbSections; i++) {
+      aSection = getSection( i );
+      if ( aSection )
+        aNbCoords += aSection->myPoints.size();
+    }
+  } else {
+    aSection = getSection( theISection );
+    if ( aSection )
+      aNbCoords = aSection->myPoints.size();
+  }
+
+  return aNbCoords/myDimension;
+}
+
+void CurveCreator_Curve::setSkipSorting( const bool theIsToSkip )
+{
+  mySkipSorting = theIsToSkip;
+}
+
+bool CurveCreator_Curve::canPointsBeSorted()
+{
+  return false;
+}
+
+/**
+ * Saves points coordinates difference.
+ * \param theOldCoords the old points coordinates
+ */
+void CurveCreator_Curve::saveCoordDiff( const SectionToPointCoordsList &theOldCoords )
+{
+  // Set the difference.
+  startOperation();
+  if (addEmptyDiff()) {
+    myListDiffs.back().init(this, theOldCoords);
+  }
+  finishOperation();
+}
+
+//! Get "closed" flag of the specified section
+bool CurveCreator_Curve::isClosed( const int theISection ) const
+{
+  CurveCreator_Section* aSection = getSection( theISection );
+  return aSection ? aSection->myIsClosed : false;
+}
+
+//! For internal use only! Undo/Redo are not used here.
+bool CurveCreator_Curve::setClosedInternal( const int theISection, 
+                                            const bool theIsClosed )
+{
+  CurveCreator_Section* aSection = 0;
+  if (theISection == -1) {
+    int aSize = mySections.size();
+    int i;
+
+    for (i = 0; i < aSize; i++) {
+      aSection = getSection( i );
+      if( aSection ) {
+        aSection->myIsClosed = theIsClosed;
+        redisplayCurve();
+      }
+    }
+  } else {
+    aSection = getSection( theISection );
+    if ( aSection ) {
+      aSection->myIsClosed = theIsClosed;
+      redisplayCurve();
+    }
+  }
+  return true;
+}
+
+/**
+ *  Set "closed" flag of the specified section (all sections if
+ *  \a theISection is -1).
+ */
+bool CurveCreator_Curve::setClosed( const int theISection, 
+                                    const bool theIsClosed )
+{
+  bool res = false;
+  // Set the difference.
+  startOperation();
+  if (addEmptyDiff()) {
+    myListDiffs.back().init(this, CurveCreator_Operation::SetClosed,
+                            theIsClosed, theISection);
+  }
+  res = setClosedInternal( theISection, theIsClosed );
+  finishOperation();
+  return res;
+}
+
+//! Returns specified section name
+std::string CurveCreator_Curve::getSectionName( const int theISection ) const
+{
+  CurveCreator_Section* aSection = getSection( theISection );
+  return aSection ? aSection->myName : "";
+}
+
+//! For internal use only! Undo/Redo are not used here.
+bool CurveCreator_Curve::setSectionNameInternal( const int theISection, 
+                                                 const std::string& theName )
+{
+  bool res = false;
+  CurveCreator_Section* aSection = getSection( theISection );
+  if( aSection ) {
+    aSection->myName = theName;
+    res = true;
+  }
+  return res;
+}
+
+/** Set name of the specified section */
+bool CurveCreator_Curve::setSectionName( const int theISection, 
+                                         const std::string& theName )
+{
+  bool res = false;
+  // Set the difference.
+  startOperation();
+  if (addEmptyDiff()) {
+    myListDiffs.back().init(this, CurveCreator_Operation::RenameSection,
+                            theName, theISection);
+  }
+  res = setSectionNameInternal( theISection, theName );
+  finishOperation();
+  return res;
+}
+
+//! Get type of the specified section
+CurveCreator::SectionType CurveCreator_Curve::getSectionType
+  ( const int theISection ) const
+{
+  CurveCreator_Section* aSection = getSection( theISection );
+  return aSection ? aSection->myType : CurveCreator::Polyline;
+}
+
+//! For internal use only! Undo/Redo are not used here.
+bool CurveCreator_Curve::setSectionTypeInternal( const int theISection, 
+                                                 const CurveCreator::SectionType theType )
+{
+  CurveCreator_Section* aSection;
+  if (theISection == -1) {
+    int i = 0;
+    const int aNbSections = getNbSections();
+
+    for (; i < aNbSections; i++) {
+      aSection = getSection( i );
+      if ( aSection )
+        aSection->myType = theType;
+    }
+    redisplayCurve();
+  } else {
+    aSection = getSection( theISection );
+    if ( aSection && aSection->myType != theType ){
+      aSection->myType = theType;
+      redisplayCurve();
+    }
+  }
+  return true;
+}
+
+/**
+ *  Set type of the specified section (or all sections
+ *  if \a theISection is -1).
+ */
+bool CurveCreator_Curve::setSectionType( const int theISection, 
+                                         const CurveCreator::SectionType theType )
+{
+  bool res = false;
+  startOperation();
+  // Set the difference.
+  if (addEmptyDiff()) {
+    myListDiffs.back().init(this, CurveCreator_Operation::SetType,
+                            theType, theISection);
+  }
+
+  res = setSectionTypeInternal( theISection, theType );
+
+  finishOperation();
+  return res;
+}
+
+
+/***********************************************/
+/***           Point methods                 ***/
+/***********************************************/
+
+//! For internal use only! Undo/Redo are not used here.
+bool CurveCreator_Curve::addPointsInternal( const CurveCreator::SectionsMap &theSectionsMap )
+{
+  bool res = false;
+  CurveCreator::SectionsMap::const_iterator anIt = theSectionsMap.begin();
+  CurveCreator_Section *aSection = 0;
+  for ( ; anIt != theSectionsMap.end(); anIt++ ) {
+    int anISection = anIt->first;
+    aSection = getSection( anISection );
+    if( aSection ) {
+      CurveCreator::PosPointsList aSectionPoints = anIt->second;
+      CurveCreator::PosPointsList::const_iterator aPntIt = aSectionPoints.begin();
+      for( ; aPntIt != aSectionPoints.end(); aPntIt++ ){
+        int anIPnt = (*aPntIt)->myID;
+        CurveCreator::Coordinates aCoords = (*aPntIt)->myCoords;
+        CurveCreator::Coordinates::iterator anIterPosition;
+        if(anIPnt == -1)
+          anIterPosition = aSection->myPoints.end();
+        else
+          anIterPosition = aSection->myPoints.begin() + toICoord(anIPnt);
+        CurveCreator::Coordinates::const_iterator aFirstPosition = 
+          aCoords.begin();
+        aSection->myPoints.insert(anIterPosition,
+                                  aCoords.begin(), aCoords.end());
+      }
+      res = true;
+    }
+  }
+  if(res)
+    redisplayCurve();
+  return res;
+}
+
+/**
+ *  Add one point to the specified section starting from the given theIPnt index
+ *  (or at the end of points if \a theIPnt is -1).
+ */
+bool CurveCreator_Curve::addPoints( const CurveCreator::Coordinates& theCoords,
+                                    const int theISection,
+                                    const int theIPnt )
+{
+  bool res = false;
+  CurveCreator::Coordinates aCoords = theCoords;
+  // Set the difference.
+  startOperation();
+  if (addEmptyDiff()) {
+    CurveCreator_ICurve::SectionToPointCoordsList aList;
+    aList.push_back(std::make_pair(std::make_pair(theISection, theIPnt), theCoords));
+    myListDiffs.back().init(this, CurveCreator_Operation::InsertPoints,
+                            aList);
+  }
+  CurveCreator::SectionsMap aSectionsMap;
+  CurveCreator::PosPointsList aPoints;
+  CurveCreator_PosPoint* aPosPoint = new CurveCreator_PosPoint( theIPnt, theCoords );
+  aPoints.push_back( aPosPoint );
+  aSectionsMap[theISection] = aPoints;
+
+  res = addPointsInternal( aSectionsMap );
+
+  finishOperation();
+  return res;
+}
+
+//! For internal use only! Undo/Redo are not used here.
+bool CurveCreator_Curve::setPointInternal( const CurveCreator::SectionsMap &theSectionsMap )
+{
+  bool res = false;
+  // Update the curve.
+  CurveCreator::SectionsMap::const_iterator anIt = theSectionsMap.begin();
+  CurveCreator_Section *aSection = 0;
+  for ( ; anIt != theSectionsMap.end(); anIt++ ) {
+    int anISection = anIt->first;
+    aSection = getSection( anISection );
+    if( aSection ) { 
+      CurveCreator::PosPointsList aSectionPoints = anIt->second;
+      CurveCreator::PosPointsList::const_iterator aPntIt = aSectionPoints.begin();
+      for( ; aPntIt != aSectionPoints.end(); aPntIt++ ){
+        int anIPnt = (*aPntIt)->myID;
+        CurveCreator::Coordinates aCoords = (*aPntIt)->myCoords;
+        for ( int i = 0; i < myDimension; i++)
+          aSection->myPoints.at(toICoord(anIPnt) + i) = aCoords[i];
+      }
+      res = true;
+    }
+  }
+  if(res)
+    redisplayCurve();
+  
+  return res;
+}
+
+//! Set coordinates of specified point
+bool CurveCreator_Curve::setPoint( const int theISection,
+                                   const int theIPnt,
+                                   const CurveCreator::Coordinates& theNewCoords )
+{
+  bool res = false;
+  // Set the difference.
+  startOperation();
+  if (addEmptyDiff()) {
+    CurveCreator_ICurve::SectionToPointCoordsList aList;
+    aList.push_back(std::make_pair(std::make_pair(theISection, theIPnt), theNewCoords));
+    myListDiffs.back().init(this, CurveCreator_Operation::SetCoordinates,
+                            aList);
+  }
+  CurveCreator::SectionsMap aSectionsMap;
+  CurveCreator::PosPointsList aPoints;
+  CurveCreator_PosPoint* aPosPoint = new CurveCreator_PosPoint( theIPnt, theNewCoords );
+  aPoints.push_back( aPosPoint );
+  aSectionsMap[theISection] = aPoints;
+
+  int aSize1 = getNbPoints( theISection );
+  res = setPointInternal( aSectionsMap );
+  int aSize2 = getNbPoints( theISection );
+
+  finishOperation();
+
+  return res; 
+}
+
+//! Set coordinates of specified points from different sections
+bool CurveCreator_Curve::setSeveralPoints( const SectionToPointCoordsList &theSectionToPntCoords,
+                                           const bool theIsToSaveDiff )
+{
+  bool res = false;
+  // Set the difference.
+  startOperation();
+  if (theIsToSaveDiff && addEmptyDiff()) {
+    myListDiffs.back().init(this, CurveCreator_Operation::SetCoordinates,
+                            theSectionToPntCoords);
+  }
+  CurveCreator::SectionsMap aSectionsMap;
+  CurveCreator::PosPointsList aPosPoints;
+  CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = 
+    theSectionToPntCoords.begin(), aLast = theSectionToPntCoords.end();
+  int aSectionId, aPointId;
+  for ( ; anIt != aLast; anIt++ ) {
+    aPosPoints.clear();
+    aSectionId = anIt->first.first;
+    aPointId = anIt->first.second;
+    CurveCreator::Coordinates aNewCoords = anIt->second;
+    CurveCreator_PosPoint* aPosPoint = 
+      new CurveCreator_PosPoint( aPointId, aNewCoords );
+    if( aSectionsMap.find(aSectionId) != aSectionsMap.end() )
+      aPosPoints = aSectionsMap[aSectionId];
+    aPosPoints.push_back( aPosPoint );
+    aSectionsMap[aSectionId] = aPosPoints;
+    
+  }
+  res = setPointInternal( aSectionsMap );
+  finishOperation();
+
+  return res; 
+}
+
+//! For internal use only! Undo/Redo are not used here.
+bool CurveCreator_Curve::removePointsInternal( const SectionToPointList &thePoints )
+{
+  bool aRes = false;
+  std::map<int, std::list<int> > aConvPoints;
+  convert( thePoints, aConvPoints );
+  std::map<int, std::list<int> >::const_iterator anIt = aConvPoints.begin(),
+                                          aLast = aConvPoints.end();
+  for ( ; anIt != aLast; anIt++ ) {
+    int aSectionId = anIt->first;
+    aRes = removeSectionPoints(aSectionId, anIt->second);
+  }
+  if( aRes)
+    redisplayCurve();
+
+  return aRes;
+}
+
+//! Remove point with given id
+bool CurveCreator_Curve::removePoint( const int theISection, const int theIPnt )
+{
+  bool res = false;
+  // Set the difference.
+  startOperation();
+  SectionToPointList aListOfSectionsToPoints;
+  aListOfSectionsToPoints.push_back(std::make_pair(theISection, theIPnt));
+  if (addEmptyDiff()) {
+    myListDiffs.back().init(this, CurveCreator_Operation::RemovePoints,
+                            aListOfSectionsToPoints);
+  }
+  res = removePointsInternal( aListOfSectionsToPoints );
+  finishOperation();
+  return res;
+}
+
+//! Remove several points from different sections with given ids
+bool CurveCreator_Curve::removeSeveralPoints( const SectionToPointList &theSectionToPntIDs)
+{
+  bool res = false;
+  // Set the difference.
+  startOperation();
+  if (addEmptyDiff()) {
+    myListDiffs.back().init(this, CurveCreator_Operation::RemovePoints,
+                            theSectionToPntIDs);
+  }
+  res = removePointsInternal( theSectionToPntIDs );
+  finishOperation();
+  return res;
+}
+
+  //=======================================================================
+// function: getCoordinates
+// purpose:
+//=======================================================================
+CurveCreator::Coordinates CurveCreator_Curve::getPoint( const int theISection,
+                                                        const int theIPnt) const
+{
+  CurveCreator_Section* aSection = getSection( theISection );
+  CurveCreator::Coordinates::const_iterator
+    anIter = aSection->myPoints.begin() + toICoord(theIPnt);
+  CurveCreator::Coordinates aResult(anIter, anIter + myDimension);
+
+  return aResult;
+}
+
+//=======================================================================
+// function: getPoints
+// purpose:
+//=======================================================================
+CurveCreator::Coordinates CurveCreator_Curve::getPoints( const int theISection ) const
+{
+  CurveCreator_Section* aSection = getSection( theISection );
+  return aSection ? aSection->myPoints : CurveCreator::Coordinates();
+}
+
+void CurveCreator_Curve::constructAISObject()
+{
+  TopoDS_Shape aShape;
+  CurveCreator_Utils::constructShape( this, aShape );
+
+  myAISShape = new AIS_Shape( aShape );
+}
+
+CurveCreator_Section* CurveCreator_Curve::getSection( const int theSectionId ) const
+{
+  CurveCreator_Section *aSection = 0;
+  if ( theSectionId >= 0 && theSectionId < mySections.size() )
+    aSection = mySections.at( theSectionId );
+
+  return aSection;
+}
+
+Handle(AIS_InteractiveObject) CurveCreator_Curve::getAISObject( const bool theNeedToBuild ) const
+{
+  if ( !myAISShape && theNeedToBuild ) {
+    CurveCreator_Curve* aCurve = (CurveCreator_Curve*)this;
+    aCurve->constructAISObject();
+  }
+  return myAISShape;
+}
+
+bool CurveCreator_Curve::removeSectionPoints( const int theSectionId,
+                                              const std::list<int>& thePointIds )
+{
+  bool aRes = false;
+
+  CurveCreator_Section* aSection = getSection( theSectionId );
+  if ( !aSection )
+    return aRes;
+
+  std::list<int> aSectionPoints = thePointIds;
+  aSectionPoints.sort();
+  std::list<int>::const_reverse_iterator aPntIt = aSectionPoints.rbegin();
+  for ( ; aPntIt != aSectionPoints.rend(); aPntIt++ ) {
+    int aPntIndx = *aPntIt;
+    CurveCreator::Coordinates::iterator aFirstPosition;
+    if ( aPntIndx == -1 )
+      aFirstPosition = aSection->myPoints.end() - getDimension();
+    else
+      aFirstPosition = aSection->myPoints.begin() + toICoord( aPntIndx );
+    aSection->myPoints.erase( aFirstPosition, aFirstPosition + getDimension() );
+    aRes = true;
+  }
+  return aRes;
+}
+
+void CurveCreator_Curve::convert( const SectionToPointList& thePoints,
+                                  std::map< int, std::list<int> >& theConvPoints )
 {
-  CurveCreator_Section *aSection =
-    (theISection == -1 ? mySections.back() : mySections.at(theISection));
+  theConvPoints.clear();
 
-  aSection->myPoints.insert(aSection->myPoints.end(),
-                            thePoints.begin(), thePoints.end());
-  if( myListener )
-    myListener->pointInserted( theISection, -1 );
+  SectionToPointList::const_iterator anIt = thePoints.begin(), aLast = thePoints.end();
+  std::list<int> aPoints;
+  int aSectionId, aPointId;
+  for ( ; anIt != aLast; anIt++ ) {
+    aSectionId = anIt->first;
+    aPointId = anIt->second;
+    aPoints.clear();
+    if ( theConvPoints.find( aSectionId ) != theConvPoints.end() )
+      aPoints = theConvPoints[aSectionId];
+    aPoints.push_back( aPointId );
+    theConvPoints[aSectionId] = aPoints;
+  }
 }
index 309d06a84cc9916355389544a84d68ce66c1a7df..adcfc87a8f6f8e21448d463583bfbcb14ae5597a 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #ifndef _CurveCreator_Curve_HeaderFile
 #define _CurveCreator_Curve_HeaderFile
 
-#include "CurveCreator.hxx"
 #include "CurveCreator_ICurve.hxx"
+
 #include "CurveCreator_Macro.hxx"
-#include "CurveCreator_Operation.hxx"
+#include "CurveCreator.hxx"
+#include "CurveCreator_Diff.hxx"
 
-class CurveCreator_Section;
-class CurveCreator_Listener;
+#include <list>
+#include <map>
+
+struct CurveCreator_Section;
+class CurveCreator_Displayer;
+class AIS_Shape;
+class Handle_AIS_InteractiveObject;
 
 /**
  *  The CurveCreator_Curve object is represented as one or more sets of
  *  connected points; thus CurveCreator_Curve object can contain several
  *  not connected curves (polylines or b-splines), each such curve has two
- *  only ends ï¿½ start and end points ï¿½ in other words non-manifold curves
+ *  only ends "start and end points" in other words non-manifold curves
  *  are not supported.
  */
 class CURVECREATOR_EXPORT CurveCreator_Curve : public CurveCreator_ICurve
 {
+protected:
+  typedef std::list<CurveCreator_Diff> ListDiff;
+
 public:
   //! Constructor of the curve.
   /** The dimension is explicitly specified in the constructor
@@ -47,15 +56,273 @@ public:
    */
   CurveCreator_Curve(const CurveCreator::Dimension theDimension);
 
-  /** Add points to the specified section (or last section
+  //! Destructor.
+  virtual ~CurveCreator_Curve();
+
+  //! Get the dimension.
+  virtual CurveCreator::Dimension getDimension() const;
+
+  //! Return unique section name
+  virtual std::string getUniqSectionName() const;
+
+  //! Set curve creator Displayer object
+  virtual void setDisplayer( CurveCreator_Displayer* theDisplayer );
+
+  //! Return curve creator Displayer object
+  CurveCreator_Displayer* getDisplayer();
+
+  //! Remove curve creator Displayer object
+  virtual void removeDisplayer();
+
+  /** Set depth of undo operations (unlimited if \a theDepth is -1
+   *  or disabled if \a theDepth is 0)
+   */
+  virtual void setUndoDepth(const int theDepth = -1);
+
+  //! Get depth of undo operations.
+  virtual int getUndoDepth() const;
+
+  virtual void startOperation();
+  virtual void finishOperation();
+
+  /**
+   * This method converts the point index to the index in
+   * an array of coordinates.
+   */
+  virtual int toICoord(const int theIPnt) const;
+
+  //! For internal use only! Undo/Redo are not used here.
+  virtual bool moveSectionInternal(const int theISection,
+                           const int theNewIndex);
+  //! Move section to new position in list
+  virtual bool moveSection(const int theISection,
+                   const int theNewIndex);
+
+protected:
+  /** This method updates all undo/redo information required to be updated
+   *  after curve modification operation. It returns false if undo/redo
+   *  is disabled and true otherwise.
+   */
+  virtual bool addEmptyDiff();
+
+public: // TODO: remove public
+  void getCoordinates( int theISection, int theIPoint, double& theX, double& theY, double& theZ ) const;
+protected:  // TODO: remove public
+  void redisplayCurve();
+
+public:
+  /************   Implementation of INTERFACE methods   ************/
+
+  /***********************************************/
+  /***          Undo/Redo methods              ***/
+  /***********************************************/
+
+  //! Get number of available undo operations
+  virtual int getNbUndo() const;
+
+  //! Undo previous operation
+  virtual bool undo();
+
+  //! Get number of available redo operations
+  virtual int getNbRedo() const;
+
+  //! Redo last previously "undone" operation
+  virtual bool redo();
+
+
+  /***********************************************/
+  /***           Section methods               ***/
+  /***********************************************/
+
+  //! For internal use only! Undo/Redo are not used here.
+  virtual bool clearInternal();
+  //! Clear the polyline (remove all sections)
+  virtual bool clear();
+
+  //! For internal use only! Undo/Redo are not used here.
+  virtual bool joinInternal( const std::list<int>& theSections );
+
+  //! Join list of sections to one section (join all if the list is empty)
+  // The first section in the list is a leader, another sections are joined to it
+  virtual bool join( const std::list<int>& theSections );
+
+  //! Get number of sections
+  virtual int getNbSections() const;
+
+  //! For internal use only! Undo/Redo are not used here.
+  virtual int addSectionInternal( const std::string &theName, 
+                                  const CurveCreator::SectionType theType,
+                                  const bool theIsClosed,
+                                  const CurveCreator::Coordinates &thePoints);
+  //! Add a new section.
+  virtual int addSection( const std::string &theName, 
+                           const CurveCreator::SectionType theType,
+                           const bool theIsClosed );
+  //! Add a new section.
+  virtual int addSection( const std::string &theName, 
+                           const CurveCreator::SectionType theType,
+                           const bool theIsClosed,
+                           const CurveCreator::Coordinates &thePoints);
+  
+  //! For internal use only! Undo/Redo are not used here.
+  virtual bool removeSectionInternal( const int theISection );
+  //! Removes the given sections.
+  virtual bool removeSection( const int theISection );
+
+  //! Get "closed" flag of the specified section
+  virtual bool isClosed( const int theISection ) const;
+
+  //! For internal use only! Undo/Redo are not used here.
+  virtual bool setClosedInternal( const int theISection, 
+                                  const bool theIsClosed );
+  /**
+   *  Set "closed" flag of the specified section (all sections if
+   *  \a theISection is -1).
+   */
+  virtual bool setClosed( const int theISection, 
+                          const bool theIsClosed );
+
+  //! Returns specifyed section name
+  virtual std::string getSectionName( const int theISection ) const;
+
+  //! For internal use only! Undo/Redo are not used here.
+  virtual bool setSectionNameInternal( const int theISection, 
+                                       const std::string& theName );
+  /** Set name of the specified section */
+  virtual bool setSectionName( const int theISection, 
+                               const std::string& theName );
+
+  //! Get type of the specified section
+  virtual CurveCreator::SectionType getSectionType( const int theISection ) const;
+
+  //! For internal use only! Undo/Redo are not used here.
+  virtual bool setSectionTypeInternal( const int theISection, 
+                                       const CurveCreator::SectionType theType );
+  /**
+   *  Set type of the specified section (or all sections
    *  if \a theISection is -1).
    */
-  virtual void addPoints
-    (const CurveCreator::Coordinates &thePoints, const int theISection = -1);
+  virtual bool setSectionType( const int theISection, 
+                               const CurveCreator::SectionType theType );
+
+
+  /***********************************************/
+  /***           Point methods                 ***/
+  /***********************************************/
+
+  //! For internal use only! Undo/Redo are not used here.
+  virtual bool addPointsInternal( const CurveCreator::SectionsMap &theSectionsMap );
+  /**
+   *  Add one point to the specified section starting from the given theIPnt index
+   *  (or at the end of points if \a theIPnt is -1).
+   */
+  virtual bool addPoints( const CurveCreator::Coordinates &theCoords,
+                          const int theISection,
+                          const int theIPnt = -1 );
+
+  //! For internal use only! Undo/Redo are not used here.
+  virtual bool setPointInternal( const CurveCreator::SectionsMap &theSectionsMap );
+   //! Set coordinates of specified point
+  virtual bool setPoint( const int theISection,
+                         const int theIPnt,
+                         const CurveCreator::Coordinates& theNewCoords );
+
+  //! Set coordinates of specified points from different sections
+  virtual bool setSeveralPoints( const SectionToPointCoordsList &theSectionToPntCoords,
+                                 const bool theIsToSaveDiff = true );
+
+  //! For internal use only! Undo/Redo are not used here.
+  virtual bool removePointsInternal( const SectionToPointList &thePoints );
+  /** Remove point with given id */
+  virtual bool removePoint( const int theISection, const int theIPnt = -1 );
+
+  //! Remove several points from different sections with given ids
+  virtual bool removeSeveralPoints( const SectionToPointList &theSectionToPntIDs);
+
+  //! Get coordinates of specified point
+  virtual CurveCreator::Coordinates getPoint( const int theISection, 
+                                              const int theIPnt ) const;
+
+  /**
+   * Get points of a section (the total points in Curve if theISection is equal to -1)..
+   */
+  virtual CurveCreator::Coordinates getPoints( const int theISection = -1 ) const;
+
+
+  /**
+   *  Get number of points in specified section or (the total number of points
+   *  in Curve if theISection is equal to -1).
+   */
+  virtual int getNbPoints( const int theISection ) const;
+
+   /**
+   * Set skip sorting flag. If the flag is true - points sorting will be skipped.
+   */
+  virtual void setSkipSorting( const bool theIsToSkip );
+
+  /**
+   * Indicates whether the points can be sorted.
+   */
+  virtual bool canPointsBeSorted();
+
+  /**
+   * Saves points coordinates difference.
+   * \param theOldCoords the old points coordinates
+   */
+  virtual void saveCoordDiff( const SectionToPointCoordsList &theOldCoords );
+
+  /***********************************************/
+  /***       Presentation methods              ***/
+  /***********************************************/
+  /**
+   *  Get the curve AIS object
+   */
+  virtual Handle_AIS_InteractiveObject getAISObject( const bool theNeedToBuild = false ) const;
+
+protected:
+  /**
+   *  Removes the points from the section. It sortes the points and remove them
+   * in the decreasing order
+   * \param theSectionId a section index
+   * \param thePointIds a list of section points
+   */
+  bool removeSectionPoints( const int theSectionId,
+                            const std::list<int>& thePointIds );
+  /**
+   * Converts the list of pairs of section to point into map of a section to list of points
+   * \param thePoints an source list
+   * \param theConvPoints a converted map
+   */
+  void convert( const SectionToPointList &thePoints,
+                std::map<int, std::list<int> > &theConvPoints );
+
+protected:
+  virtual void constructAISObject();
+  /**
+   * Returns the section by the section index or NULL if the index is out of the section
+   * list range
+   * \param theSectionId the section index
+   */
+  CurveCreator_Section* getSection( const int theSectionId ) const;
+
+protected:
+  bool                            mySkipSorting;
+
+public:
+  bool                            myIsLocked;
+  CurveCreator::Sections          mySections;   //!< curve data
+  CurveCreator::Dimension         myDimension;  //!< curve dimension
+  CurveCreator_Displayer*         myDisplayer;  //!< curve displayer
 
-  friend class CurveCreator_CurveEditor;
-  friend class CurveCreator_Operation;
+private:
 
+  int                             myNbUndos;
+  int                             myNbRedos;
+  ListDiff::iterator              myCurrenPos;
+  ListDiff                        myListDiffs;
+  int                             myUndoDepth;
+  int                             myOpLevel;
+  AIS_Shape*                      myAISShape;   //!< AIS shape
 };
 
 #endif
diff --git a/src/CurveCreator/CurveCreator_CurveEditor.cxx b/src/CurveCreator/CurveCreator_CurveEditor.cxx
deleted file mode 100644 (file)
index 559eabd..0000000
+++ /dev/null
@@ -1,511 +0,0 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-// File:        CurveCreator_CurveEditor.cxx
-// Author:      Sergey KHROMOV
-
-#include "CurveCreator_CurveEditor.hxx"
-
-//=======================================================================
-// function: Constructor
-// purpose:
-//=======================================================================
-CurveCreator_CurveEditor::CurveCreator_CurveEditor
-                                (CurveCreator_Curve* thePCurve)
- : myNbUndos   (0),
-   myNbRedos   (0),
-   myPCurve    (thePCurve),
-   myUndoDepth (-1),
-   myOpLevel(0)
-{
-  if (myPCurve != NULL) {
-    if (myPCurve->isLocked()) {
-      // This curve is locked by another editor. Invalid case.
-      myPCurve = NULL;
-    } else {
-      // Lock the curve.
-      myPCurve->myIsLocked = true;
-      myCurrenPos = myListDiffs.end();
-    }
-  }
-}
-
-//=======================================================================
-// function: Destructor
-// purpose:
-//=======================================================================
-CurveCreator_CurveEditor::~CurveCreator_CurveEditor()
-{
-  if (myPCurve != NULL) {
-    // Unlock the curve.
-    myPCurve->myIsLocked = false;
-  }
-}
-
-//=======================================================================
-// function: getCurve
-// purpose:
-//=======================================================================
-CurveCreator_Curve *CurveCreator_CurveEditor::getCurve() const
-{
-  return myPCurve;
-}
-
-//=======================================================================
-// function: isAttached
-// purpose:
-//=======================================================================
-bool CurveCreator_CurveEditor::isAttached() const
-{
-  return (myPCurve != NULL);
-}
-
-//=======================================================================
-// function: undo
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::undo()
-{
-  if (myNbUndos > 0) {
-    myNbUndos--;
-    myNbRedos++;
-    myCurrenPos--;
-    myCurrenPos->applyUndo(myPCurve);
-  }
-}
-
-//=======================================================================
-// function: redo
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::redo()
-{
-  if (myNbRedos > 0) {
-    myCurrenPos->applyRedo(myPCurve);
-    myCurrenPos++;
-    myNbRedos--;
-    myNbUndos++;
-  }
-}
-
-//=======================================================================
-// function: getNbUndo
-// purpose:
-//=======================================================================
-int CurveCreator_CurveEditor::getNbUndo() const
-{
-  return myNbUndos;
-}
-
-//=======================================================================
-// function: getNbRedo
-// purpose:
-//=======================================================================
-int CurveCreator_CurveEditor::getNbRedo() const
-{
-  return myNbRedos;
-}
-
-//=======================================================================
-// function: setUndoDepth
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::setUndoDepth(const int theDepth)
-{
-  if (theDepth == 0) {
-    // Reset all undo/redo data.
-    myNbUndos = 0;
-    myNbRedos = 0;
-    myListDiffs.clear();
-    myCurrenPos = myListDiffs.end();
-    myUndoDepth = 0;
-  } else if (theDepth == -1) {
-    // There is nothing to do as the depth become unlimited.
-    myUndoDepth = -1;
-  } else if (theDepth > 0) {
-    // The new "real" depth is set.
-    if (theDepth < myNbRedos) {
-      // The new depth is less then number of redos. Remove the latest redos.
-      int aShift = (myNbRedos - theDepth);
-      ListDiff::iterator aFromPos = myListDiffs.end();
-
-      while (aShift--) {
-        aFromPos--;
-      }
-
-      myListDiffs.erase(aFromPos, myListDiffs.end());
-      myNbRedos = theDepth;
-    }
-
-    if (theDepth < myNbUndos + myNbRedos) {
-      // The new depth is less then the total number of differences.
-      // Remove the first undos.
-      int aShift = (myNbUndos + myNbRedos - theDepth);
-      ListDiff::iterator aToPos = myListDiffs.begin();
-
-      while (aShift--) {
-        aToPos++;
-      }
-
-      myListDiffs.erase(myListDiffs.begin(), aToPos);
-      myNbUndos = theDepth - myNbRedos;
-    }
-
-    myUndoDepth = theDepth;
-  }
-}
-
-//=======================================================================
-// function: getUndoDepth
-// purpose:
-//=======================================================================
-int CurveCreator_CurveEditor::getUndoDepth() const
-{
-  return myUndoDepth;
-}
-
-//=======================================================================
-// function: setType
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::setType(const CurveCreator::Type theType,
-                                       const int theISection)
-{
-  if (myPCurve != NULL) {
-    startOperation();
-    // Set the difference.
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::SetType,
-                              theType, theISection);
-    }
-
-    // Update the curve.
-    myPCurve->setType(theType, theISection);
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: addPoints
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::addPoints
-                      (const CurveCreator::Coordinates &thePoints,
-                       const int theISection)
-{
-  if (myPCurve != NULL) {
-    // Set the difference.
-    startOperation();
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::AddPoints,
-                              thePoints, theISection);
-    }
-
-    // Update the curve.
-    myPCurve->addPoints(thePoints, theISection);
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: addSection
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::addSection
-        (const std::string& theName, const CurveCreator::Type theType,
-         const bool theIsClosed,
-         const CurveCreator::Coordinates &thePoints)
-{
-  if (myPCurve != NULL) {
-    // Set the difference.
-    startOperation();
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::AddSection,
-                              theName, thePoints, theType, theIsClosed);
-    }
-
-    // Update the curve.
-    myPCurve->addSection(theName, theType, theIsClosed, thePoints);
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: removeSection
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::removeSection(const int theISection)
-{
-  if (myPCurve != NULL) {
-    // Set the difference.
-    startOperation();
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::RemoveSection,
-                              theISection);
-    }
-
-    // Update the curve.
-    myPCurve->removeSection(theISection);
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: insertPoints
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::insertPoints
-        (const CurveCreator::Coordinates &thePoints,
-         const int theISection,
-         const int theIPnt)
-{
-  if (myPCurve != NULL) {
-    // Set the difference.
-    startOperation();
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::InsertPoints,
-                              thePoints, theISection, theIPnt);
-    }
-
-    // Update the curve.
-    myPCurve->insertPoints(thePoints, theISection, theIPnt);
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: movePoints
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::movePoint(const int theISection,
-                const int theOrigIPnt,
-                const int theNewIPnt )
-{
-    startOperation();
-    myPCurve->movePoint(theISection, theOrigIPnt, theNewIPnt);
-    finishOperation();
-}
-
-//=======================================================================
-// function: removePoints
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::removePoints
-              (const int theISection,
-               const int theIPnt,
-               const int theNbPoints)
-{
-  if (myPCurve != NULL) {
-    // Set the difference.
-    startOperation();
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::RemovePoints,
-                              theISection, theIPnt, theNbPoints);
-    }
-
-    // Update the curve.
-    myPCurve->removePoints(theISection, theIPnt, theNbPoints);
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: clear
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::clear()
-{
-  if (myPCurve != NULL) {
-    startOperation();
-    // Set the difference.
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::Clear);
-    }
-
-    // Update the curve.
-    myPCurve->clear();
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: setCoordinates
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::setCoordinates
-                     (const CurveCreator::Coordinates &theCoords,
-                      const int theISection,
-                      const int theIPnt)
-{
-  if (myPCurve != NULL) {
-    // Set the difference.
-    startOperation();
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::SetCoordinates,
-                              theCoords, theISection, theIPnt);
-    }
-
-    // Update the curve.
-    myPCurve->setCoordinates(theCoords, theISection, theIPnt);
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: setClosed
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::setClosed(const bool theIsClosed,
-                                         const int theISection)
-{
-  if (myPCurve != NULL) {
-    // Set the difference.
-    startOperation();
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::SetClosed,
-                              theIsClosed, theISection);
-    }
-
-    // Update the curve.
-    myPCurve->setClosed(theIsClosed, theISection);
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: setName
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::setName(const std::string& theName,
-                                         const int theISection)
-{
-    if (myPCurve != NULL) {
-      // Set the difference.
-      startOperation();
-      if (addEmptyDiff()) {
-        myListDiffs.back().init(myPCurve, CurveCreator_Operation::RenameSection,
-                                theName, theISection);
-      }
-      myPCurve->setName( theName, theISection );
-      finishOperation();
-    }
-}
-
-//=======================================================================
-// function: moveSection
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::moveSection(const int theISection,
-                                           const int theNewIndex)
-{
-  if (myPCurve != NULL) {
-    // Set the difference.
-    startOperation();
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::MoveSection,
-                              theISection, theNewIndex);
-    }
-
-    // Update the curve.
-    myPCurve->moveSection(theISection, theNewIndex);
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: join
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::join(const int theISectionTo,
-                                    const int theISectionFrom)
-{
-  if (myPCurve != NULL) {
-    // Set the difference.
-    startOperation();
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::Join,
-                              theISectionTo, theISectionFrom);
-    }
-
-    // Update the curve.
-    myPCurve->join(theISectionTo, theISectionFrom);
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: join
-// purpose:
-//=======================================================================
-void CurveCreator_CurveEditor::join()
-{
-  if (myPCurve != NULL) {
-    // Set the difference.
-    startOperation();
-    if (addEmptyDiff()) {
-      myListDiffs.back().init(myPCurve, CurveCreator_Operation::Join);
-    }
-
-    // Update the curve.
-    myPCurve->join();
-    finishOperation();
-  }
-}
-
-//=======================================================================
-// function: addDiff
-// purpose:
-//=======================================================================
-bool CurveCreator_CurveEditor::addEmptyDiff()
-{
-  bool isEnabled = false;
-
-  if (myUndoDepth != 0) {
-    // Forget all Redos after the current one.
-    if (myNbRedos > 0) {
-      myNbRedos = 0;
-      myListDiffs.erase(myCurrenPos, myListDiffs.end());
-    }
-
-    if (myUndoDepth == -1 || myNbUndos < myUndoDepth) {
-      // Increase the number of undos.
-      myNbUndos++;
-    } else {
-      // If there are too many differences, remove the first one.
-      myListDiffs.pop_front();
-    }
-
-    // Add new difference.
-    myListDiffs.push_back(CurveCreator_Diff());
-    myCurrenPos = myListDiffs.end();
-    isEnabled = true;
-  }
-
-  return isEnabled;
-}
-
-void CurveCreator_CurveEditor::startOperation()
-{
-    myOpLevel++;
-}
-
-void CurveCreator_CurveEditor::finishOperation()
-{
-   myOpLevel--;
-}
diff --git a/src/CurveCreator/CurveCreator_CurveEditor.hxx b/src/CurveCreator/CurveCreator_CurveEditor.hxx
deleted file mode 100644 (file)
index 32aa009..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-// File:        CurveCreator_CurveEditor.hxx
-// Author:      Sergey KHROMOV
-
-#ifndef _CurveCreator_CurveEditor_HeaderFile
-#define _CurveCreator_CurveEditor_HeaderFile
-
-#include "CurveCreator_Diff.hxx"
-#include "CurveCreator_Curve.hxx"
-
-#include <list>
-
-/**
- *  The CurveCreator_CurveEditor is designed to manage of
- *  editing operations of CurveCreator_Curve class.
- */
-class CURVECREATOR_EXPORT CurveCreator_CurveEditor
-{
-
-private:
-
-  typedef std::list<CurveCreator_Diff> ListDiff;
-
-public:
-
-  //! Constuctor, initialized by the curve object
-  CurveCreator_CurveEditor(CurveCreator_Curve* thePCurve);
-
-  //! Destructor, detaches from the Curve
-  ~CurveCreator_CurveEditor();
-
-  //! Returns the curve.
-  CurveCreator_Curve *getCurve() const;
-
-  //! This method returns true if this editor is attached to a valid curve.
-  bool isAttached() const;
-
-  //! Undo previous operation
-  void undo();
-
-  //! Redo last previously ï¿½undoed� operation
-  void redo();
-
-  //! Get number of available undo operations
-  int getNbUndo() const;
-
-  //! Get number of available redo operations
-  int getNbRedo() const;
-
-  //! Set depth of undo operations (unlimited if \a theDepth is -1
-  //  or disabled if \a theDepth is 0)
-  void setUndoDepth(const int theDepth = -1);
-
-  //! Get depth of undo operations.
-  int getUndoDepth() const;
-
-  /** Set type of the specified section (or all sections
-   *  if \a theISection is -1).
-   */
-  void setType(const CurveCreator::Type theType, const int theISection = -1);
-
-  /** Set section closed (or all sections
-   *  if \a theISection is -1).
-   */
-  void setClosed(const bool theIsClosed, const int theISection);
-
-  /** Set section name (if theISection is invalid it is ignored).
-   */
-  void setName(const std::string& theName, const int theISection);
-
-  /** Add points to the specified section (or last section
-   *  if \a theISection is -1).
-   */
-  void addPoints(const CurveCreator::Coordinates &thePoints,
-                 const int theISection = -1);
-
-  //! Add a new section.
-  void addSection(const std::string &theName, const CurveCreator::Type theType,
-                  const bool theIsClosed,
-                  const CurveCreator::Coordinates &thePoints);
-
-  //! Removes the section. If theISection equals -1, removes the last section.
-  void removeSection(const int theISection = -1);
-
-  /** Insert points in the given position (add to the end of list
-   *  if \a theIPnt parameter is -1) of the specified section
-   *  (or last section if \a theISection parameter is -1).
-   */
-  void insertPoints(const CurveCreator::Coordinates &thePoints,
-                    const int theISection = -1,
-                    const int theIPnt = -1);
-
-  /** Remove \a nbPoints points from given \a theISection,
-   *  starting from given \a theIPnt (of all points up to the end of
-   *  section if \a theNbPoints is -1).
-   */
-  void removePoints(const int theISection,
-                    const int theIPnt,
-                    const int theNbPoints = -1);
-
-  /** Mobe point in \a theISection from given position \a theOrigIPnt
-   *  to new position \a theNewIPnt.
-   */
-  void movePoint(const int theISection,
-                  const int theOrigIPnt,
-                  const int theNewIPnt );
-
-  //! Remove all sections.
-  void clear();
-
-  //! Set coordinates of specified point
-  void setCoordinates(const CurveCreator::Coordinates &theCoords,
-                      const int theISection,
-                      const int theIPnt);
-
-  /** Move specified \a theISection to the specified position
-   *  in the sections list.
-   */
-  void moveSection(const int theISection, const int theNewIndex);
-
-  //! Join two sections to one section
-  void join(const int theISectionTo, const int theISectionFrom);
-
-  //! Join all sections to the single curve
-  void join();
-
-  void startOperation();
-  void finishOperation();
-private:
-
-  /** This method updates all undo/redo information required to be updated
-   *  after curve modification operation. It returns false if undo/redo
-   *  is disabled and true otherwise.
-   */
-  bool addEmptyDiff();
-
-private:
-
-  int myNbUndos;
-  int myNbRedos;
-  ListDiff::iterator myCurrenPos;
-  ListDiff myListDiffs;
-  CurveCreator_Curve* myPCurve;
-  int myUndoDepth;
-  int myOpLevel;
-};
-
-#endif
index 22f099e118ea5e01d1f8455f411b1fed74c94422..d1a7dc3222e43426504b79b637fea80197b35ce0 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -49,9 +49,9 @@ CurveCreator_Diff::~CurveCreator_Diff()
 // function: init
 // purpose:
 //=======================================================================
-bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
-                             const CurveCreator_Operation::Type theType)
+bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve)
 {
+  CurveCreator_Operation::Type aType = CurveCreator_Operation::Clear;
   bool isOK = false;
 
   if (theCurve != NULL) {
@@ -60,36 +60,18 @@ bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
     // Set redo.
     myPRedo = new CurveCreator_Operation;
 
-    if (myPRedo->init(theType)) {
+    if (myPRedo->init(aType)) {
       isOK = true;
 
       const int aNbSections = theCurve->getNbSections();
 
-      if (theType == CurveCreator_Operation::Clear) {
-        // Construct undo for Clear command.
-        if (aNbSections > 0) {
-          setNbUndos(aNbSections);
+      // Construct undo for Clear command.
+      if (aNbSections > 0) {
+        setNbUndos(aNbSections);
 
-          for (int i = 0; i < aNbSections && isOK; i++) {
-            // Add AddSection command.
-            isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
-          }
-        }
-      } else { // theType == CurveCreator_Operation::Join
-        // Construct undo for Join command.
-        if (aNbSections > 1) {
-          // Add the RemovePoints command to remove points of
-          // the second section fron the first one.
-          const int aNbPoints = theCurve->getNbPoints(0);
-
-          setNbUndos(aNbSections);
-          isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
-                                 0, aNbPoints, -1);
-
-          for (int i = 1; i < aNbSections && isOK; i++) {
-            // Add AddSection command.
-            isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
-          }
+        for (int i = 0; i < aNbSections && isOK; i++) {
+          // Add AddSection command.
+          isOK = addSectionToUndo(theCurve, i, myPUndo[i]);
         }
       }
     }
@@ -176,33 +158,6 @@ bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
           setNbUndos(1);
           isOK = myPUndo[0].init(theType, theIntParam2, theIntParam1);
           break;
-        case CurveCreator_Operation::Join:
-          {
-            // If the last section is removed, one AddSection command is
-            // enough. If not last section is removed, two commands are
-            // requred: AddSection and MoveSection.
-            const int aLastIndex = theCurve->getNbSections() - 1;
-            const int aNbPoints  = theCurve->getNbPoints(theIntParam1);
-
-            if (theIntParam2 == aLastIndex) {
-              setNbUndos(2);
-            } else {
-              setNbUndos(3);
-            }
-
-            isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
-                                   theIntParam1, aNbPoints, -1);
-
-            if (isOK) {
-              isOK = addSectionToUndo(theCurve, theIntParam2, myPUndo[1]);
-
-              if (isOK && theIntParam2 != aLastIndex) {
-                isOK = myPUndo[2].init(CurveCreator_Operation::MoveSection,
-                                       aLastIndex, theIntParam2);
-              }
-            }
-          }
-          break;
         default:
           break;
       }
@@ -222,77 +177,68 @@ bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
 //=======================================================================
 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
                              const CurveCreator_Operation::Type theType,
-                             const int theIntParam1,
-                             const int theIntParam2,
-                             const int theIntParam3)
+                             const std::list<int>& theParams)
 {
   bool isOK = false;
 
-  if (theCurve != NULL) {
+  if (theCurve != NULL || theParams.empty()) {
     clear();
 
     // Set redo.
     myPRedo = new CurveCreator_Operation;
 
-    if (myPRedo->init(theType, theIntParam1, theIntParam2, theIntParam3)) {
-      // Construct undo for RemovePoints command.
-      const CurveCreator::Dimension aDim = theCurve->getDimension();
-      const CurveCreator::Coordinates &aPoints =
-              theCurve->getPoints(theIntParam1);
-      CurveCreator::Coordinates::const_iterator anIterBegin =
-          aPoints.begin() + (aDim*theIntParam2);
-      CurveCreator::Coordinates::const_iterator anIterEnd;
-
-      if (theIntParam3 == -1) {
-        anIterEnd = aPoints.end();
-      } else {
-        anIterEnd = anIterBegin + (aDim*theIntParam3);
-      }
-
-      CurveCreator::Coordinates aPointsToAdd;
-
-      setNbUndos(1);
-      aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
-      isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
-                             aPointsToAdd, theIntParam1, theIntParam2);
-    }
-
-    if (!isOK) {
-      clear();
-    }
-  }
-
-  return isOK;
-}
-
-//=======================================================================
-// function: init
-// purpose:
-//=======================================================================
-bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
-                             const CurveCreator_Operation::Type theType,
-                             const CurveCreator::Coordinates &theCoords,
-                             const int theIntParam)
-{
-  bool isOK = false;
-
-  if (theCurve != NULL) {
-    clear();
-
-    // Set redo.
-    myPRedo = new CurveCreator_Operation;
+    if (myPRedo->init(theType, theParams)) {
+      // Construct undo for different commands.
+      switch (theType) {
+        case CurveCreator_Operation::Join:
+          {
+            int aSectionMain = theParams.front();
+            const int aNbPointsMain  = theCurve->getNbPoints(aSectionMain);
+
+            std::list<int> aSectionsToJoin = theParams;
+            aSectionsToJoin.erase( aSectionsToJoin.begin() );
+            // it is important to sort the section indices in order to correct perform undo
+            // for the move sections to the previous positions
+            aSectionsToJoin.sort();
+            // 1rst undo for remove points from the main and n-1 undoes to contain joined sections
+            int aSectionsToJoinNb = aSectionsToJoin.size();
+            int aNbUndos = 2*aSectionsToJoinNb + 1;
+            setNbUndos( aNbUndos );
+
+            // Add joined sections to undo
+            std::list<int>::const_iterator anIt = aSectionsToJoin.begin(),
+                                           aLast = aSectionsToJoin.end();
+            anIt = aSectionsToJoin.begin();
+            int aLastSectionId = -1;
+            for (int i = 0; anIt != aLast && i < aSectionsToJoinNb; anIt++, i++) {
+              int anISection = *anIt;
+              isOK = addSectionToUndo( theCurve, anISection, myPUndo[i*2] );
+              if (isOK) {
+                isOK = myPUndo[i*2+1].init(CurveCreator_Operation::MoveSection,
+                                           aLastSectionId, anISection);
+                if (!isOK)
+                  break;
+              }
+            }
+            // Construct undo for RemovePoints command.
+            if (isOK) {
+              int aNbPointsInJoined = 0;
+              anIt = aSectionsToJoin.begin();
+              for ( ; anIt != aLast; anIt++ )
+                aNbPointsInJoined += theCurve->getNbPoints( *anIt );
 
-    if (myPRedo->init(theType, theCoords, theIntParam)) {
-      // Construct undo for AddPoints command.
-      const int aSectionInd = getSectionIndex(theCurve, theIntParam);
-      const CurveCreator::Dimension aDim = theCurve->getDimension();
-      const CurveCreator::Coordinates &aPoints =
-              theCurve->getPoints(aSectionInd);
-      const int aNbPoints = (aPoints.size()/aDim);
+              int aJoinedSize = aNbPointsMain + aNbPointsInJoined;
+              CurveCreator_ICurve::SectionToPointList aSectionToPointList;
+              for (int anIPoint = aNbPointsMain; anIPoint < aJoinedSize; anIPoint++)
+                aSectionToPointList.push_back(std::make_pair(aSectionMain, anIPoint));
 
-      setNbUndos(1);
-      isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
-                             aSectionInd, aNbPoints, -1);
+              isOK = myPUndo[aNbUndos-1].init(CurveCreator_Operation::RemovePoints, aSectionToPointList);
+            }
+          }
+          break;
+        default:
+          break;
+      }
     }
 
     if (!isOK) {
@@ -337,15 +283,33 @@ bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
     return isOK;
 }
 
-//=======================================================================
-// function: init
-// purpose:
-//=======================================================================
 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
                              const CurveCreator_Operation::Type theType,
-                             const CurveCreator::Coordinates &theCoords,
-                             const int theIntParam1,
-                             const int theIntParam2)
+                             const std::string &theName,
+                             const int theIntParam1 )
+{
+  bool isOK = false;
+  myPRedo = new CurveCreator_Operation;
+
+  if (myPRedo->init(theType, theName, theIntParam1 )) {
+    // Construct undo for different commands.
+    switch (theType) {
+      case CurveCreator_Operation::RenameSection:
+        setNbUndos(1);
+        isOK = myPUndo[0].init(CurveCreator_Operation::RenameSection,
+                               theCurve->getSectionName(theIntParam1), theIntParam1);
+        break;
+    }
+  }
+  if( !isOK ){
+    clear();
+  }
+  return isOK;
+}
+
+bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
+                             const CurveCreator_Operation::Type theType,
+                             const CurveCreator_ICurve::SectionToPointList &theParamList1)
 {
   bool isOK = false;
 
@@ -355,35 +319,90 @@ bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
     // Set redo.
     myPRedo = new CurveCreator_Operation;
 
-    if (myPRedo->init(theType, theCoords, theIntParam1, theIntParam2)) {
+    if (myPRedo->init(theType, theParamList1)) {
       // Construct undo for different commands.
       switch (theType) {
-        case CurveCreator_Operation::InsertPoints:
+        case CurveCreator_Operation::RemovePoints:
           {
+            // Construct undo for RemovePoints command.
+            CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointCoords;
+            CurveCreator::Coordinates aPointsToAdd;
             const CurveCreator::Dimension aDim = theCurve->getDimension();
-            const int aNbPoints = (theCoords.size()/aDim);
-            const int aSectionInd = getSectionIndex(theCurve, theIntParam1);
-            int aPointInd;
-
-            if (theIntParam2 == -1) {
-              aPointInd = theCurve->getNbPoints(aSectionInd);
-            } else {
-              aPointInd = theIntParam2;
+            CurveCreator_ICurve::SectionToPointList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
+            std::list<int> aPoints;
+            int aSectionId, aPointId;
+            for ( ; anIt != aLast; anIt++ ) {
+              aPointsToAdd.clear();
+              aSectionId = anIt->first;
+              aPointId = anIt->second;
+              const CurveCreator::Coordinates &aPoints =
+                      theCurve->getPoints(aSectionId);
+              CurveCreator::Coordinates::const_iterator anIterBegin =
+                  aPoints.begin() + (aDim*aPointId);
+              CurveCreator::Coordinates::const_iterator anIterEnd = 
+                anIterBegin + aDim;
+              aPointsToAdd.insert(aPointsToAdd.end(), anIterBegin, anIterEnd);
+              aSectionToPointCoords.push_back(std::make_pair(*anIt, aPointsToAdd));
             }
+            setNbUndos(1);
+            isOK = myPUndo[0].init(CurveCreator_Operation::InsertPoints,
+                                   aSectionToPointCoords);
+          }
+          break;
+        default:
+          break;
+      }
+    }
+
+    if (!isOK) {
+      clear();
+    }
+  }
 
+  return isOK;
+}
+
+bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
+                             const CurveCreator_Operation::Type theType,
+                             const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1)
+{
+  bool isOK = false;
+
+  if (theCurve != NULL) {
+    clear();
+
+    // Set redo.
+    myPRedo = new CurveCreator_Operation;
+
+    if (myPRedo->init(theType, theParamList1)) {
+      // Construct undo for different commands.
+      switch (theType) {
+        case CurveCreator_Operation::InsertPoints:
+          {
+            // Construct undo for RemovePoints command.
+            CurveCreator_ICurve::SectionToPointList aSectionToPointList;
+            CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
+            for ( ; anIt != aLast; anIt++ ) {
+              aSectionToPointList.push_back(anIt->first);
+            }
             setNbUndos(1);
             isOK = myPUndo[0].init(CurveCreator_Operation::RemovePoints,
-                                   aSectionInd, aPointInd, aNbPoints);
+                                   aSectionToPointList);
           }
           break;
         case CurveCreator_Operation::SetCoordinates:
           {
-            const CurveCreator::Coordinates anOldCoords =
-              theCurve->getCoordinates(theIntParam1, theIntParam2);
+            // Construct undo for SetCoordinates command.
+            CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointOldCoords;
+            CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = theParamList1.begin(), aLast = theParamList1.end();
+            for ( ; anIt != aLast; anIt++ ) {
+              CurveCreator::Coordinates anOldCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
+              aSectionToPointOldCoords.push_back(std::make_pair(anIt->first, anOldCoords));
+            }
 
             setNbUndos(1);
             isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
-                                   anOldCoords, theIntParam1, theIntParam2);
+                                   aSectionToPointOldCoords);
           }
           break;
         default:
@@ -400,26 +419,37 @@ bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
 }
 
 bool CurveCreator_Diff::init(const CurveCreator_Curve *theCurve,
-                             const CurveCreator_Operation::Type theType,
-                             const std::string &theName,
-                             const int theIntParam1 )
+                             const CurveCreator_ICurve::SectionToPointCoordsList &theOldParamList)
 {
   bool isOK = false;
-  myPRedo = new CurveCreator_Operation;
 
-  if (myPRedo->init(theType, theName, theIntParam1 )) {
-    // Construct undo for different commands.
-    switch (theType) {
-      case CurveCreator_Operation::RenameSection:
-        setNbUndos(1);
-        isOK = myPUndo[0].init(CurveCreator_Operation::RenameSection,
-                               theCurve->getSectionName(theIntParam1), theIntParam1);
-        break;
-    }
-  }
-  if( !isOK ){
+  if (theCurve != NULL && theOldParamList.size() > 0) {
     clear();
+
+    // Set redo.
+    myPRedo = new CurveCreator_Operation;
+
+    // Construct redo for SetCoordinates command.
+    CurveCreator_ICurve::SectionToPointCoordsList aSectionToPointActualCoords;
+    CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = 
+      theOldParamList.begin(), aLast = theOldParamList.end();
+    for ( ; anIt != aLast; anIt++ ) {
+      CurveCreator::Coordinates anActualCoords = theCurve->getPoint(anIt->first.first, anIt->first.second);
+      aSectionToPointActualCoords.push_back(std::make_pair(anIt->first, anActualCoords));
+    }
+
+    if (myPRedo->init(CurveCreator_Operation::SetCoordinates, aSectionToPointActualCoords)) {
+      // Undo for SetCoordinates command.
+      setNbUndos(1);
+      isOK = myPUndo[0].init(CurveCreator_Operation::SetCoordinates,
+                             theOldParamList);
+    }
+
+    if (!isOK) {
+      clear();
+    }
   }
+
   return isOK;
 }
 
@@ -495,12 +525,13 @@ bool CurveCreator_Diff::addSectionToUndo
                        const int theIndex,
                        CurveCreator_Operation &theOperation) const
 {
+  const std::string aName = theCurve->getSectionName(theIndex);
   const CurveCreator::Coordinates &aPnts = theCurve->getPoints(theIndex);
-  const CurveCreator::Type aType = theCurve->getType(theIndex);
+  const CurveCreator::SectionType aType = theCurve->getSectionType(theIndex);
   const bool isClosed = theCurve->isClosed(theIndex);
 
   bool isOK = theOperation.init(CurveCreator_Operation::AddSection,
-                                aPnts, aType, isClosed);
+                                aName, aPnts, aType, isClosed);
 
   return isOK;
 }
@@ -533,7 +564,7 @@ bool CurveCreator_Diff::setTypeOrClosedToUndo
       // Get sections to be modified.
       for (i = 0; i < aNbSections; i++) {
         if (isSetType) {
-          aValue = theCurve->getType(i);
+          aValue = theCurve->getSectionType(i);
         } else {
           aValue = theCurve->isClosed(i);
         }
@@ -556,7 +587,7 @@ bool CurveCreator_Diff::setTypeOrClosedToUndo
     // There is only particular section modified.
     // Check if there is a real modification required.
     if (isSetType) {
-      aValue = theCurve->getType(theIntParam2);
+      aValue = theCurve->getSectionType(theIntParam2);
     } else {
       aValue = theCurve->isClosed(theIntParam2);
     }
@@ -572,7 +603,7 @@ bool CurveCreator_Diff::setTypeOrClosedToUndo
     std::list<int>::iterator anIter = aListOfInd.begin();
 
     if (isSetType) {
-      aValue = theCurve->getType(*anIter);
+      aValue = theCurve->getSectionType(*anIter);
     } else {
       aValue = theCurve->isClosed(*anIter);
     }
index e56b294f2b7f6deb4ba9fabaf99cb889aca63ad5..f55f5306ff18f9133319d6985cf110cad6687dcb 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -56,11 +56,9 @@ public:
    * parameters. It is applicable to the following operations:
    * <UL>
    *   <LI>Clear</LI>
-   *   <LI>Join (without arguments)</LI>
    * </UL>
    */
-  bool init(const CurveCreator_Curve *theCurve,
-            const CurveCreator_Operation::Type theType);
+  bool init(const CurveCreator_Curve *theCurve);
 
   /**
    * This method initializes the difference with an operation with one integer
@@ -80,7 +78,6 @@ public:
    *   <LI>SetType</LI>
    *   <LI>SetClosed</LI>
    *   <LI>MoveSection</LI>
-   *   <LI>Join (with 2 int arguments)</LI>
    * </UL>
    */
   bool init(const CurveCreator_Curve *theCurve,
@@ -88,74 +85,77 @@ public:
             const int theIntParam1,
             const int theIntParam2);
 
-  /**
-   * This method initializes the difference with an operation with three
-   * integer parameters. It is applicable to the following operations:
+    /**
+   * This method initializes the difference with an operation with two integer
+   * parameters. It is applicable to the following operations:
    * <UL>
-   *   <LI>RemovePoints</LI>
+   *   <LI>Join (with a list of int arguments)</LI>
    * </UL>
    */
   bool init(const CurveCreator_Curve *theCurve,
             const CurveCreator_Operation::Type theType,
-            const int theIntParam1,
-            const int theIntParam2,
-            const int theIntParam3);
+            const std::list<int>& theParams);
 
   /**
    * This method initializes the difference with an operation with one
-   * CurveCreator::Coordinates parameter and one integer parameter.
+   * Name, one CurveCreator::Coordinates parameter and two integer parameters.
    * It is applicable to the following operations:
    * <UL>
-   *   <LI>AddPoints</LI>
+   *   <LI>AddSection</LI>
    * </UL>
    */
   bool init(const CurveCreator_Curve *theCurve,
             const CurveCreator_Operation::Type theType,
+            const std::string& theName,
             const CurveCreator::Coordinates &theCoords,
-            const int theIntParam);
+            const int theIntParam1,
+            const int theIntParam2);
 
   /**
    * This method initializes the difference with an operation with one
-   * CurveCreator::Coordinates parameter and two integer parameters.
+   * string and one integer parameters.
    * It is applicable to the following operations:
    * <UL>
-   *   <LI>InsertPoints</LI>
-   *   <LI>SetCoordinates</LI>
+   *   <LI>RenameSection</LI>
    * </UL>
    */
   bool init(const CurveCreator_Curve *theCurve,
             const CurveCreator_Operation::Type theType,
-            const CurveCreator::Coordinates &theCoords,
-            const int theIntParam1,
-            const int theIntParam2);
+            const std::string &theName,
+            const int theIntParam1 );
 
   /**
-   * This method initializes the difference with an operation with one
-   * Name, one CurveCreator::Coordinates parameter and two integer parameters.
+   * This method initializes the difference with an operation with 
+   * list of pairs of integer parameters.
    * It is applicable to the following operations:
    * <UL>
-   *   <LI>AddSection</LI>
+   *   <LI>RemovePoints</LI>
    * </UL>
    */
   bool init(const CurveCreator_Curve *theCurve,
             const CurveCreator_Operation::Type theType,
-            const std::string& theName,
-            const CurveCreator::Coordinates &theCoords,
-            const int theIntParam1,
-            const int theIntParam2);
+            const CurveCreator_ICurve::SectionToPointList &theParamList);
 
   /**
-   * This method initializes the difference with an operation with one
-   * string and one integer parameters.
+   * This method initializes the difference with an operation with 
+   * list of pairs of integer parameters with point coordinates.
    * It is applicable to the following operations:
    * <UL>
-   *   <LI>RenameSection</LI>
+   *   <LI>RemovePoints</LI>
    * </UL>
    */
   bool init(const CurveCreator_Curve *theCurve,
             const CurveCreator_Operation::Type theType,
-            const std::string &theName,
-            const int theIntParam1 );
+            const CurveCreator_ICurve::SectionToPointCoordsList &theParamList);
+
+  /**
+   * This method initializes the difference with an operation with 
+   * list of pairs of integer parameters with point coordinates.
+   * \param theCurve the modified curve
+   * \param theOldParamList the old parameters (to be saved for undo)
+   */
+  bool init(const CurveCreator_Curve *theCurve,
+            const CurveCreator_ICurve::SectionToPointCoordsList &theOldParamList);
 
   /**
    * This method applies undo operation to theCurve.
diff --git a/src/CurveCreator/CurveCreator_Displayer.cxx b/src/CurveCreator/CurveCreator_Displayer.cxx
new file mode 100644 (file)
index 0000000..22ae399
--- /dev/null
@@ -0,0 +1,64 @@
+#include "CurveCreator_Displayer.hxx"
+
+CurveCreator_Displayer::CurveCreator_Displayer( Handle_AIS_InteractiveContext theContext,
+                                                const int theZLayer ) :
+  myContext( theContext ), myZLayer( theZLayer )
+{
+  myObjects.clear();
+}
+
+CurveCreator_Displayer::~CurveCreator_Displayer(void)
+{
+  eraseAll( true );
+  for( int i = 0 ; i < myObjects.size() ; i++ ){
+    myObjects[i].Nullify();
+  }
+  myObjects.clear();
+}
+
+void CurveCreator_Displayer::display( const Handle(AIS_InteractiveObject)& theObject, bool isUpdate )
+{
+  if ( theObject.IsNull() )
+    return;
+
+  myObjects.push_back( theObject );
+  myContext->Display( theObject, Standard_False );
+
+  if ( myZLayer >= 0 )
+    myContext->SetZLayer( theObject, myZLayer );
+
+  if( isUpdate )
+    myContext->UpdateCurrentViewer();
+}
+
+void CurveCreator_Displayer::eraseAll( bool isUpdate )
+{
+  if(myObjects.empty())
+    return;
+  for( int i = 0 ; i < myObjects.size() ; i++ ){
+    myContext->Erase(myObjects[i], Standard_False);
+  }
+  myObjects.clear();
+  if( isUpdate )
+    myContext->UpdateCurrentViewer();
+}
+
+Quantity_Color CurveCreator_Displayer::getActiveColor( bool isHL )
+{
+  if( isHL ){
+    return Quantity_Color( 1., 0., 0., Quantity_TOC_RGB );
+  }
+  return Quantity_Color( 0., 1., 0., Quantity_TOC_RGB );
+}
+
+/*void CurveCreator_Displayer::highlight( const AISObjectsList& theObjects, bool isHL )
+{
+  return;
+  //TODO:
+  Quantity_Color aColor = getActiveColor( isHL );
+  for( int i = 0 ; i < theObjects.size() ; i++ ){
+    theObjects[i]->SetColor(aColor);
+    myContext->Display(theObjects[i], Standard_False);
+  }
+  myContext->UpdateCurrentViewer();
+}*/
diff --git a/src/CurveCreator/CurveCreator_Displayer.hxx b/src/CurveCreator/CurveCreator_Displayer.hxx
new file mode 100644 (file)
index 0000000..f65e9d2
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef CURVECREATOR_DISPLAYER_H
+#define CURVECREATOR_DISPLAYER_H
+
+#include "CurveCreator_Macro.hxx"
+
+#include <AIS_InteractiveObject.hxx>
+#include <AIS_InteractiveContext.hxx>
+
+#include <vector>
+
+class CURVECREATOR_EXPORT CurveCreator_Displayer
+{
+typedef std::vector<Handle_AIS_InteractiveObject> AISObjectsList;
+
+public:
+  CurveCreator_Displayer( Handle_AIS_InteractiveContext theContext,
+                          const int theZLayer = -1 );
+  ~CurveCreator_Displayer(void);
+
+  void display( const Handle_AIS_InteractiveObject& theObject, bool isUpdate );
+  void eraseAll( bool isUpdate );
+  //void highlight( const AISObjectsList& theObjects, bool isHL );
+
+protected:
+  Quantity_Color getActiveColor( bool isHL );
+
+private:
+  Handle_AIS_InteractiveContext myContext;
+  AISObjectsList                myObjects;
+  int                           myZLayer;
+};
+
+#endif
diff --git a/src/CurveCreator/CurveCreator_ICurve.cxx b/src/CurveCreator/CurveCreator_ICurve.cxx
deleted file mode 100644 (file)
index fc73f56..0000000
+++ /dev/null
@@ -1,459 +0,0 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-// File:        CurveCreator_ICurve.cxx
-// Author:      Sergey KHROMOV
-
-#include "CurveCreator_ICurve.hxx"
-#include "CurveCreator_Section.hxx"
-#include "CurveCreator_Listener.hxx"
-
-#include <stdio.h>
-
-//=======================================================================
-// function: Constructor
-// purpose:
-//=======================================================================
-CurveCreator_ICurve::CurveCreator_ICurve
-                (const CurveCreator::Dimension theDimension)
-: myIsLocked  (false),
-  myDimension (theDimension),
-  myListener(NULL)
-{
-}
-
-//=======================================================================
-// function: Destructor
-// purpose:
-//=======================================================================
-CurveCreator_ICurve::~CurveCreator_ICurve()
-{
-  // Delete all allocated data.
-  clear();
-}
-
-//=======================================================================
-// function: isLocked
-// purpose:
-//=======================================================================
-bool CurveCreator_ICurve::isLocked() const
-{
-  return myIsLocked;
-}
-
-//=======================================================================
-// function: getDimension
-// purpose:
-//=======================================================================
-CurveCreator::Dimension CurveCreator_ICurve::getDimension() const
-{
-  return myDimension;
-}
-
-//=======================================================================
-// function: getNbPoints
-// purpose:
-//=======================================================================
-int CurveCreator_ICurve::getNbPoints(const int theISection) const
-{
-  int aNbCoords = 0;
-
-  if (theISection == -1) {
-    int i = 0;
-    const int aNbSections = getNbSections();
-
-    for (; i < aNbSections; i++) {
-      aNbCoords += mySections[i]->myPoints.size();
-    }
-  } else {
-    aNbCoords = mySections.at(theISection)->myPoints.size();
-  }
-
-  return aNbCoords/myDimension;
-}
-
-//=======================================================================
-// function: getNbSections
-// purpose:
-//=======================================================================
-int CurveCreator_ICurve::getNbSections() const
-{
-  return mySections.size();
-}
-
-//=======================================================================
-// function: getCoordinates
-// purpose:
-//=======================================================================
-CurveCreator::Coordinates CurveCreator_ICurve::getCoordinates
-                            (const int theISection, const int theIPnt) const
-{
-  CurveCreator_Section *aSection = mySections.at(theISection);
-  CurveCreator::Coordinates::const_iterator
-    anIter = aSection->myPoints.begin() + toICoord(theIPnt);
-  CurveCreator::Coordinates aResult(anIter, anIter + myDimension);
-
-  return aResult;
-}
-
-//=======================================================================
-// function: getType
-// purpose:
-//=======================================================================
-CurveCreator::Type CurveCreator_ICurve::getType(const int theISection) const
-{
-  return mySections.at(theISection)->myType;
-}
-
-//=======================================================================
-// function: getPoints
-// purpose:
-//=======================================================================
-const CurveCreator::Coordinates &CurveCreator_ICurve::getPoints
-                  (const int theISection) const
-{
-  return mySections.at(theISection)->myPoints;
-}
-
-//=======================================================================
-// function: isClosed
-// purpose:
-//=======================================================================
-bool CurveCreator_ICurve::isClosed(const int theISection) const
-{
-  return mySections.at(theISection)->myIsClosed;
-}
-
-std::string CurveCreator_ICurve::getSectionName(const int theISection) const
-{
-    return mySections.at(theISection)->myName;
-}
-
-//=======================================================================
-// function: setType
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::setType
-    (const CurveCreator::Type theType, const int theISection)
-{
-  if (theISection == -1) {
-    int i = 0;
-    const int aNbSections = getNbSections();
-
-    for (; i < aNbSections; i++) {
-      mySections[i]->myType = theType;
-    }
-    if( myListener )
-      myListener->curveChanged();
-  } else {
-    if( mySections.at(theISection)->myType != theType ){
-      mySections.at(theISection)->myType = theType;
-      if( myListener )
-        myListener->sectionTypeChanged(theISection);
-    }
-  }
-}
-
-//=======================================================================
-// function: addSection
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::addSection
-                  (const std::string& theName,
-                   const CurveCreator::Type theType,
-                   const bool theIsClosed,
-                   const CurveCreator::Coordinates &thePoints)
-{
-  CurveCreator_Section *aSection = new CurveCreator_Section;
-
-  std::string aName = theName;
-  if( aName.empty() ){
-      aName = getUnicSectionName();
-  }
-  aSection->myName     = aName;
-  aSection->myType     = theType;
-  aSection->myIsClosed = theIsClosed;
-  aSection->myPoints   = thePoints;
-  mySections.push_back(aSection);
-  if( myListener )
-    myListener->sectionAdded( -1 );
-}
-
-//=======================================================================
-// function: removeSection
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::removeSection(const int theISection)
-{
-  if (theISection == -1) {
-    delete mySections.back();
-    mySections.pop_back();
-  } else {
-    Sections::iterator anIterRm = mySections.begin() + theISection;
-
-    delete *anIterRm;
-    mySections.erase(anIterRm);
-  }
-  if( myListener )
-    myListener->sectionRemoved(theISection);
-}
-
-//=======================================================================
-// function: insertPoints
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::insertPoints
-                   (const CurveCreator::Coordinates &thePoints,
-                    const int theISection,
-                    const int theIPnt)
-{
-  if (theIPnt == -1) {
-    // Add points to the end of section points.
-    addPoints(thePoints, theISection);
-  } else {
-    CurveCreator_Section *aSection =
-      (theISection == -1 ? mySections.back() : mySections.at(theISection));
-
-    aSection->myPoints.insert(aSection->myPoints.begin() + toICoord(theIPnt),
-                             thePoints.begin(), thePoints.end());
-    if( myListener )
-      myListener->pointInserted( theISection, theIPnt );
-  }
-}
-
-void CurveCreator_ICurve::movePoint(const int theISection, const int theIPointFrom, const int theNewIndex)
-{
-    CurveCreator::Coordinates aCoords = getCoordinates(theISection, theIPointFrom );
-    insertPoints(aCoords, theISection, theNewIndex+1);
-    int aRemPntIndx = theIPointFrom;
-    if( theNewIndex < theIPointFrom )
-        aRemPntIndx++;
-    removePoints(theISection, aRemPntIndx, 1 );
-}
-
-//=======================================================================
-// function: removePoints
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::removePoints(const int theISection,
-                                      const int theIPnt,
-                                      const int theNbPoints)
-{
-  CurveCreator_Section *aSection = mySections.at(theISection);
-  CurveCreator::Coordinates::iterator anIterBegin =
-    aSection->myPoints.begin() + toICoord(theIPnt);
-  CurveCreator::Coordinates::iterator anIterEnd =
-    (theNbPoints == -1 ?
-    aSection->myPoints.end() : anIterBegin + toICoord(theNbPoints));
-
-  aSection->myPoints.erase(anIterBegin, anIterEnd);
-  if( myListener )
-    myListener->pointRemoved(theISection, theIPnt, theNbPoints );
-}
-
-//=======================================================================
-// function: clear
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::clear()
-{
-  // Delete all allocated data.
-  int i = 0;
-  const int aNbSections = getNbSections();
-
-  for (; i < aNbSections; i++) {
-    delete mySections[i];
-  }
-
-  mySections.clear();
-  if( myListener )
-    myListener->curveChanged();
-}
-
-//=======================================================================
-// function: setCoordinates
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::setCoordinates
-                     (const CurveCreator::Coordinates &theCoords,
-                      const int theISection,
-                      const int theIPnt)
-{
-  if (theCoords.size() == myDimension) {
-    CurveCreator_Section *aSection = mySections.at(theISection);
-    int i;
-
-    for (i = 0; i < myDimension; i++) {
-      aSection->myPoints.at(toICoord(theIPnt) + i) = theCoords[i];
-    }
-
-    if( myListener )
-      myListener->pointChanged( theISection, theIPnt );
-  }
-}
-
-//=======================================================================
-// function: setClosed
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::setClosed(const bool theIsClosed,
-                                   const int theISection)
-{
-  if (theISection == -1) {
-    int aSize = mySections.size();
-    int i;
-
-    for (i = 0; i < aSize; i++) {
-      mySections[i]->myIsClosed = theIsClosed;
-      if( myListener ){
-        myListener->sectionClosed( theISection, theIsClosed );
-      }
-    }
-  } else {
-    mySections.at(theISection)->myIsClosed = theIsClosed;
-    if( myListener ){
-      myListener->sectionClosed( theISection, theIsClosed );
-    }
-  }
-}
-
-/** Set name of the specified section.
- */
-void CurveCreator_ICurve::setName( const std::string& theName, const int theISection )
-{
-    if( ( theISection >= 0 ) && ( theISection < mySections.size() )){
-        mySections.at(theISection)->myName = theName;
-    }
-}
-
-//=======================================================================
-// function: moveSection
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::moveSection(const int theISection,
-                                     const int theNewIndex)
-{
-  if (theISection != theNewIndex) {
-    CurveCreator_Section *aSection = mySections.at(theISection);
-
-    // Remove section
-    Sections::iterator anIter = mySections.begin() + theISection;
-
-    mySections.erase(anIter);
-
-    // Insert section.
-    anIter = mySections.begin() + theNewIndex;
-    mySections.insert(anIter, aSection);
-  }
-}
-
-//=======================================================================
-// function: join
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::join(const int theISectionTo,
-                              const int theISectionFrom)
-{
-  if (theISectionTo != theISectionFrom) {
-    CurveCreator_Section *aSection1 = mySections.at(theISectionTo);
-    CurveCreator_Section *aSection2 = mySections.at(theISectionFrom);
-
-    aSection1->myPoints.insert(aSection1->myPoints.end(),
-    aSection2->myPoints.begin(), aSection2->myPoints.end());
-
-    removeSection(theISectionFrom);
-    if( myListener )
-      myListener->curveChanged();
-  }
-}
-
-//=======================================================================
-// function: join
-// purpose:
-//=======================================================================
-void CurveCreator_ICurve::join()
-{
-  const int aSize = mySections.size();
-
-  if (aSize > 1) {
-    CurveCreator_Section *aSection1 = mySections[0];
-    int i;
-
-    for (i = 1; i < aSize; i++) {
-      CurveCreator_Section *aSection2 = mySections[i];
-
-      aSection1->myPoints.insert(aSection1->myPoints.end(),
-        aSection2->myPoints.begin(), aSection2->myPoints.end());
-      delete aSection2;
-    }
-
-    // Just erace section pointers as they were deleted before.
-    mySections.erase(mySections.begin() + 1, mySections.end());
-    if( myListener )
-      myListener->curveChanged();
-  }
-}
-
-//=======================================================================
-// function: toICoord
-// purpose:
-//=======================================================================
-int CurveCreator_ICurve::toICoord(const int theIPnt) const
-{
-  return theIPnt*myDimension;
-}
-
-//=======================================================================
-// function: getUnicSectionName
-// purpose: return unic section name
-//=======================================================================
-std::string CurveCreator_ICurve::getUnicSectionName()
-{
-    for( int i = 0 ; i < 1000000 ; i++ ){
-        char aBuffer[255];
-        sprintf( aBuffer, "Section_%d", i+1 );
-        std::string aName(aBuffer);
-        int j;
-        for( j = 0 ; j < mySections.size() ; j++ ){
-            if( mySections[j]->myName == aName )
-              break;
-        }
-        if( j == mySections.size() )
-            return aName;
-    }
-    return "";
-}
-
-//=======================================================================
-// function: setListener
-// purpose: set curve changes listener
-//=======================================================================
-void CurveCreator_ICurve::setListener( CurveCreator_Listener*   theListener )
-{
-  myListener = theListener;
-}
-
-//=======================================================================
-// function: setListener
-// purpose: set curve changes listener
-//=======================================================================
-void CurveCreator_ICurve::removeListener()
-{
-  myListener = NULL;
-}
index ca662be1de7c46c1a61b8e043621a9ddd062b8f9..9effa478a0db3ef2ae5107ac27d1a389a7d7e8c6 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-// File:        CurveCreator_Curve.hxx
-// Author:      Sergey KHROMOV
+// File:        CurveCreator_ICurve.hxx
+// Author:      Alexander KOVALEV and Alexander SOLOVYOV
 
 #ifndef _CurveCreator_ICurve_HeaderFile
 #define _CurveCreator_ICurve_HeaderFile
 
-#include "CurveCreator.hxx"
 #include "CurveCreator_Macro.hxx"
-#include "CurveCreator_Operation.hxx"
+#include <deque>
+#include <vector>
+#include <string>
+#include <list>
 
-class CurveCreator_Section;
-class CurveCreator_Listener;
+class Handle_AIS_InteractiveObject;
+
+namespace CurveCreator
+{
+  //! Type of the section
+  enum SectionType
+  {
+    Polyline,
+    Spline,
+  };
+
+  //! Dimension of the curve
+  enum Dimension
+  {
+    Dim2d = 2,
+    Dim3d = 3
+  };
+
+};
 
 /**
  *  The CurveCreator_ICurve object is represented as one or more sets of
  *  connected points; thus CurveCreator_ICurve object can contain several
  *  not connected curves (polylines or b-splines), each such curve has two
- *  only ends ï¿½ start and end points ï¿½ in other words non-manifold curves
+ *  only ends "start and end points" in other words non-manifold curves
  *  are not supported.
  */
 class CURVECREATOR_EXPORT CurveCreator_ICurve
 {
+public:
+  typedef std::pair<int,int> SectionToPoint;
+  typedef std::deque<SectionToPoint> SectionToPointList;
 
-  //! List of curves
-  typedef std::deque<CurveCreator_Section *> Sections;
+  typedef std::deque< std::pair< SectionToPoint,std::deque< float > > > SectionToPointCoordsList;
 
 public:
-  //! Constructor of the curve.
-  /** The dimension is explicitly specified in the constructor
-   *  and cannot be changed later.
-   */
-  CurveCreator_ICurve(const CurveCreator::Dimension theDimension);
+  /***********************************************/
+  /***          Undo/Redo methods              ***/
+  /***********************************************/
 
-  //! Destructor.
-  virtual ~CurveCreator_ICurve();
+  //! Get number of available undo operations
+  virtual int getNbUndo() const = 0;
 
-  //! Returns true if this curve is locked by a curve editor.
-  virtual bool isLocked() const;
+  //! Undo previous operation
+  virtual bool undo() = 0;
 
-  //! Get the dimension.
-  virtual CurveCreator::Dimension getDimension() const;
+  //! Get number of available redo operations
+  virtual int getNbRedo() const = 0;
 
-  //! Get number of sections.
-  virtual int getNbSections() const;
+  //! Redo last previously "undone" operation
+  virtual bool redo() = 0;
 
-  /** Get number of points in specified section or (the total number of points
-   *  in Curve if theISection is equal to -1).
-   */
-  virtual int getNbPoints(const int theISection = -1) const;
 
-  //! Get coordinates of specified point
-  virtual CurveCreator::Coordinates getCoordinates
-                  (const int theISection, const int theIPnt) const;
+  /***********************************************/
+  /***           Section methods               ***/
+  /***********************************************/
 
-  //! Get points of a section.
-  virtual const CurveCreator::Coordinates &getPoints(const int theISection) const;
+  //! Clear the polyline (remove all sections)
+  virtual bool clear() = 0;
 
-  //! Get type of the specified section
-  virtual CurveCreator::Type getType(const int theISection) const;
+  //! Join list of sections to one section (join all if the list is empty)
+  // The first section in the list is a leader, another sections are joined to it
+  virtual bool join( const std::list<int>& theSections ) = 0;
 
-  //! Get ï¿½closed� flag of the specified section
-  virtual bool isClosed(const int theISection) const;
+  //! Get number of sections
+  virtual int getNbSections() const = 0;
 
-  //! Returns specifyed section name
-  virtual std::string   getSectionName(const int theISection) const;
+  //! Add a new section.
+  virtual int addSection( const std::string& theName, 
+                           const CurveCreator::SectionType theType,
+                           const bool theIsClosed ) = 0;
 
-  /**
-   * Return unic section name
-   */
-  virtual std::string getUnicSectionName();
+  //! Removes the given sections.
+  virtual bool removeSection( const int theISection ) = 0;
 
-  /**
-   * Set curve creator listener object
-   */
-  virtual void setListener( CurveCreator_Listener*   myWatcher );
+  //! Get "closed" flag of the specified section
+  virtual bool isClosed( const int theISection ) const = 0;
 
   /**
-   * Remove curve creator listener object
+   *  Set "closed" flag of the specified section (all sections if
+   *  \a theISection is -1).
    */
-  virtual void removeListener();
+  virtual bool setClosed( const int theISection, 
+                          const bool theIsClosed ) = 0;
 
-protected:
+  //! Returns specifyed section name
+  virtual std::string getSectionName( const int theISection ) const = 0;
 
-  /** Set type of the specified section (or all sections
-   *  if \a theISection is -1).
-   */
-  virtual void setType(const CurveCreator::Type theType, const int theISection = -1);
+  /** Set name of the specified section */
+  virtual bool setSectionName( const int theISection, 
+                               const std::string& theName ) = 0;
 
-  /** Add points to the specified section (or last section
+  //! Get type of the specified section
+  virtual CurveCreator::SectionType getSectionType( const int theISection ) const = 0;
+
+  /**
+   *  Set type of the specified section (or all sections
    *  if \a theISection is -1).
    */
-  virtual void addPoints
-    (const CurveCreator::Coordinates &thePoints, const int theISection = -1) = 0;
-
-  //! Add a new section.
-  virtual void addSection (const std::string &theName, const CurveCreator::Type theType,
-                   const bool theIsClosed,
-                   const CurveCreator::Coordinates &thePoints);
+  virtual bool setSectionType( const int theISection, 
+                               const CurveCreator::SectionType theType ) = 0;
 
-  //! Removes the section. If theISection equals -1, removes the last section.
-  virtual void removeSection(const int theISection = -1);
 
-  /** Insert points in the given position (add to the end of list
-   *  if \a theIPnt parameter is -1) of the specified section
-   *  (or last section if \a theISection parameter is -1).
-   */
-  virtual void insertPoints(const CurveCreator::Coordinates &thePoints,
-                    const int theISection = -1,
-                    const int theIPnt = -1);
+  /***********************************************/
+  /***           Point methods                 ***/
+  /***********************************************/
 
-  /** Remove \a nbPoints points from given \a theISection,
-   *  starting from given \a theIPnt (of all points up to the end of
-   *  section if \a theNbPoints is -1).
-   */
-  virtual void removePoints(const int theISection,
-                    const int theIPnt,
-                    const int theNbPoints = -1);
+  //! Get the dimension.
+  virtual CurveCreator::Dimension getDimension() const = 0;
 
-  /** Move specified  point within section to new position
+  /**
+   *  Insert one or several points to the specified section starting from the given theIPnt index
+   *  (or add these at the end of section points if \a theIPnt is -1).
    */
-  virtual void movePoint(const int theISection,
-                 const int theIPointFrom,
-                 const int theNewIndex);
-
-  //! Remove all sections.
-  virtual void clear();
+  virtual bool addPoints( const std::deque<float>& theCoords,
+                          const int theISection,
+                          const int theIPnt = -1 ) = 0;
 
   //! Set coordinates of specified point
-  virtual void setCoordinates(const CurveCreator::Coordinates &theCoords,
-                      const int theISection,
-                      const int theIPnt);
+  virtual bool setPoint( const int theISection,
+                         const int theIPnt,
+                         const std::deque<float>& theNewCoords ) = 0;
+  
+  //! Set coordinates of specified points from different sections
+  virtual bool setSeveralPoints( const SectionToPointCoordsList &theSectionToPntCoords,
+                                 const bool theIsToSaveDiff = true ) = 0;
+
+  //! Remove point with given id
+  virtual bool removePoint( const int theISection, const int theIPnt = -1 ) = 0;
+  //! Remove several points from different sections
+  virtual bool removeSeveralPoints( const SectionToPointList &theSectionToPntIDs) = 0;
 
-  /** Set ï¿½closed� flag of the specified section (all sections if
-   *  \a theISection is -1).
-   */
-  virtual void setClosed(const bool theIsClosed, const int theISection = -1);
+  //! Get coordinates of specified point
+  virtual std::deque<float> getPoint( const int theISection, 
+                                      const int theIPnt ) const = 0;
 
-  /** Set name of the specified section.
+  /**
+   * Get points of a section (the total points in Curve if theISection is equal to -1)..
    */
-  virtual void setName( const std::string& theName, const int theISection );
+  virtual std::deque<float> getPoints( const int theISection = -1 ) const = 0;
 
-  /** Move specified \a theISection to the specified position
-   *  in the sections list.
+  /**
+   *  Get number of points in specified section or (the total number of points
+   *  in Curve if theISection is equal to -1).
    */
-  virtual void moveSection(const int theISection, const int theNewIndex);
+  virtual int getNbPoints( const int theISection ) const = 0;
 
-  //! Join two sections to one section
-  virtual void join(const int theISectionTo, const int theISectionFrom);
+  /**
+   * Set skip sorting flag. If the flag is true - points sorting will be skipped.
+   */
+  virtual void setSkipSorting( const bool ) = 0;
 
-  //! Join all sections to the single curve
-  virtual void join();
+  /**
+   * Indicates whether the points can be sorted.
+   */
+  virtual bool canPointsBeSorted() = 0;
 
   /**
-   * This method converts the point index to the index in
-   * an array of coordinates.
+   * Saves points coordinates difference.
+   * \param theOldCoords the old points coordinates
    */
-  virtual int toICoord(const int theIPnt) const;
+  virtual void saveCoordDiff( const SectionToPointCoordsList &theOldCoords ) = 0;
 
-public:
+  /***********************************************/
+  /***       Presentation methods              ***/
+  /***********************************************/
 
-  bool                    myIsLocked;
-  Sections                mySections;   //!< curve data
-  CurveCreator::Dimension myDimension;  //!< curve dimension
-  CurveCreator_Listener*  myListener;   //!< listener
+  virtual Handle_AIS_InteractiveObject getAISObject( const bool theNeedToBuild = false ) const = 0;
+
+protected:
+  virtual void constructAISObject() = 0;
 
 };
 
diff --git a/src/CurveCreator/CurveCreator_Listener.hxx b/src/CurveCreator/CurveCreator_Listener.hxx
deleted file mode 100755 (executable)
index 4fd4a29..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-#ifndef CURVE_CREATOR_LISTENER_HXX
-#define CURVE_CREATOR_LISTENER_HXX
-
-class CurveCreator_Listener
-{
-public:
-  CurveCreator_Listener(void){};
-  virtual ~CurveCreator_Listener(void){};
-
-  virtual void pointChanged( int theSection, int thePoint ){}
-  virtual void pointRemoved( int theSection, int theFirstPoint, int thePointCnt ){}
-  virtual void pointInserted( int theSection, int theIndx ){}
-
-  virtual void sectionClosed( int theSection, bool isClosed ){}
-  virtual void sectionAdded( int theSection ){}
-  virtual void sectionRemoved( int theSection ){}
-  virtual void sectionTypeChanged( int theSection ){}
-
-  virtual void curveChanged(){}
-};
-
-#endif
\ No newline at end of file
index 9e6c31c682cad1c471ded20571844724470a6438..ec814eb49a51c5854b1bc5a6170d796264a32bbf 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/src/CurveCreator/CurveCreator_NewPointDlg.cxx b/src/CurveCreator/CurveCreator_NewPointDlg.cxx
deleted file mode 100755 (executable)
index bb15571..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-#include "CurveCreator_NewPointDlg.h"
-
-#include <QGridLayout>
-#include <QVBoxLayout>
-#include <QLabel>
-#include <QDoubleSpinBox>
-#include <QDialogButtonBox>
-#include <QDoubleValidator>
-#include <QRegExpValidator>
-#include <QAbstractButton>
-#include <QPushButton>
-#include <QLocale>
-
-CurveCreator_NewPointDlg::CurveCreator_NewPointDlg(CurveCreator::Dimension theDim, QWidget *parent) :
-  QWidget(parent), myX(NULL), myY(NULL), myZ(NULL), myIsEdit(false), myDim(theDim),
-  myIsInstantSketchingEnabled(false)
-{
-  QString aTitle = QString(tr("ADD_NEW_POINT"));
-  setWindowTitle(aTitle);
-
-  QFrame* aFrame = new QFrame( this );
-  QVBoxLayout* aLayout = new QVBoxLayout( aFrame );
-
-  QFrame* aCoordFrame = new QFrame( aFrame );
-  QGridLayout* aCoordLayout = new QGridLayout( aCoordFrame );
-
-  QLabel* aLbl = new QLabel( tr("X_COORD"), this);
-  myX = new QDoubleSpinBox(this);
-  aCoordLayout->addWidget(aLbl, 0, 0);
-  aCoordLayout->addWidget(myX, 0, 1 );
-
-  aLbl = new QLabel( tr("Y_COORD"), this);
-  myY = new QDoubleSpinBox(this);
-  aCoordLayout->addWidget(aLbl, 1, 0 );
-  aCoordLayout->addWidget(myY, 1, 1 );
-
-  myZLabel = new QLabel( tr("Z_COORD"), this);
-  myZ = new QDoubleSpinBox(this);
-  aCoordLayout->addWidget(myZLabel, 2,0 );
-  aCoordLayout->addWidget(myZ, 2,1 );
-
-  if( theDim != CurveCreator::Dim3d ){
-    myZ->hide();
-    myZLabel->hide();
-  }
-
-  myBtnFrame = new QFrame( aFrame );
-  QHBoxLayout* aBtnsLayout = new QHBoxLayout( myBtnFrame );
-
-  myAddBtn = new QPushButton( tr( "ADD_BTN" ), myBtnFrame );
-  myCancelBtn = new QPushButton( tr( "CANCEL" ), myBtnFrame );
-
-  connect( myCancelBtn, SIGNAL( clicked() ), this, SIGNAL( cancelPoint() ) );
-
-  aBtnsLayout->addWidget( myAddBtn );
-  aBtnsLayout->addStretch( 1 );
-  aBtnsLayout->addWidget( myCancelBtn );
-
-  aLayout->addWidget( aCoordFrame, 0 );
-  aLayout->addWidget( myBtnFrame, 1 );
-
-  clear();
-  updateTitle();
-}
-
-void CurveCreator_NewPointDlg::setSectionName( const QString& theName )
-{
-  mySectionName = theName;
-  updateTitle();
-}
-
-void CurveCreator_NewPointDlg::setEditMode( bool isEdit )
-{
-  myIsEdit = isEdit;
-  if( myIsEdit ){
-    myAddBtn->setText(tr("OK"));
-    myAddBtn->disconnect( SIGNAL( clicked() ) );
-    connect( myAddBtn, SIGNAL( clicked() ), this, SIGNAL( modifyPoint() ) );
-  }
-  else{
-    myAddBtn->setText(tr("ADD_BTN"));
-    myAddBtn->disconnect( SIGNAL( clicked() ) );
-    connect( myAddBtn, SIGNAL( clicked() ), this, SIGNAL( addPoint() ) );
-  }
-  updateTitle();
-}
-
-void CurveCreator_NewPointDlg::updateTitle()
-{
-  QString aTitle;
-  if( !myIsEdit ){
-    if( mySectionName.isEmpty() ){
-      aTitle = tr("ADD_NEW_POINT");
-    }
-    else{
-      aTitle = QString(tr("ADD_NEW_POINT_TO_%1")).arg(mySectionName);
-    }
-  }
-  else{
-    aTitle = tr("SET_POINT_COORDINATES");
-  }
-  setWindowTitle(aTitle);
-}
-
-CurveCreator::Coordinates CurveCreator_NewPointDlg::getCoordinates() const
-{
-  CurveCreator::Coordinates aCoords;
-  double anX = myX->value();
-  aCoords.push_back(anX);
-  double anY = myY->value();
-  aCoords.push_back(anY);
-  if( myDim == CurveCreator::Dim3d ){
-    double aZ = myZ->value();
-    aCoords.push_back(aZ);
-  }
-  return aCoords;
-}
-
-void CurveCreator_NewPointDlg::clear()
-{
-  initSpinBox(myX);
-  initSpinBox(myY);
-  initSpinBox(myZ);
-}
-
-void CurveCreator_NewPointDlg::setDimension(CurveCreator::Dimension theDim)
-{
-  if( theDim == CurveCreator::Dim2d ){
-    myZ->hide();
-    myZLabel->hide();
-  }
-  else{
-    myZ->show();
-    myZLabel->show();
-  }
-}
-
-void CurveCreator_NewPointDlg::setCoordinates( const CurveCreator::Coordinates& theCoords )
-{
-  double anX = theCoords[0];
-  myX->setValue(anX);
-  double anY = theCoords[1];
-  myY->setValue(anY);
-  if( theCoords.size() == 3 ){
-    double aZ = theCoords[2];
-    myZ->setValue(aZ);
-  }
-  if( isInstantSketchingEnabled() )
-    emit addPoint();
-}
-
-bool CurveCreator_NewPointDlg::isInstantSketchingEnabled() const
-{
-  return myIsInstantSketchingEnabled;
-}
-
-void CurveCreator_NewPointDlg::setInstantSketchingEnabled( const bool theState )
-{
-  myIsInstantSketchingEnabled = theState;
-}
-
-//=======================================================================
-// function: initSpinBox
-// purpose:
-//=======================================================================
-void CurveCreator_NewPointDlg::initSpinBox(QDoubleSpinBox *theSpinBox)
-{
-  const double aCoordMin  = -1.e+15;
-  const double aCoordMax  = 1.e+15;
-  const double aStep      = 10;
-  const int    aPrecision = 6;
-
-  theSpinBox->setDecimals( qAbs( aPrecision ) );
-  theSpinBox->setRange(aCoordMin, aCoordMax);
-  theSpinBox->setSingleStep(aStep);
-  theSpinBox->setValue(0.0);
-}
diff --git a/src/CurveCreator/CurveCreator_NewPointDlg.h b/src/CurveCreator/CurveCreator_NewPointDlg.h
deleted file mode 100755 (executable)
index a86189e..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-#ifndef CURVECREATOR_NEWPOINTDLG_H
-#define CURVECREATOR_NEWPOINTDLG_H
-
-#include "CurveCreator.hxx"
-
-#include <QDockWidget>
-
-class QDoubleSpinBox;
-class QDialogButtonBox;
-class QAbstractButton;
-class QPushButton;
-class QLabel;
-class QFrame;
-
-class CurveCreator_NewPointDlg : public QWidget
-{
-  Q_OBJECT
-public:
-  explicit CurveCreator_NewPointDlg(CurveCreator::Dimension theDim, QWidget *parent = 0);
-  CurveCreator::Coordinates getCoordinates() const;
-  void clear();
-  void setSectionName( const QString& theName );
-  void setEditMode( bool isEdit );
-  void setCoordinates( const CurveCreator::Coordinates& theCoords );
-  void setDimension(CurveCreator::Dimension theDim);
-  bool isInstantSketchingEnabled() const;
-  void setInstantSketchingEnabled( const bool theState );
-signals:
-  void addPoint();
-  void modifyPoint();
-  void cancelPoint();
-public slots:
-protected slots:
-protected:
-  void updateTitle();
-  void initSpinBox(QDoubleSpinBox *theSpinBox);
-private:
-  QFrame*                 myBtnFrame;
-  CurveCreator::Dimension myDim;
-  QDoubleSpinBox*         myX;
-  QDoubleSpinBox*         myY;
-  QDoubleSpinBox*         myZ;
-  QLabel*                 myZLabel;
-  QPushButton*            myAddBtn;
-  QPushButton*            myCancelBtn;
-  bool                    myIsEdit;
-  QString                 mySectionName;
-  bool                    myIsInstantSketchingEnabled;
-};
-
-#endif // CURVECREATOR_NEWPOINTDLG_H
old mode 100755 (executable)
new mode 100644 (file)
index 275a946..f5f602a
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,7 +18,7 @@
 //
 
 #include "CurveCreator_NewSectionDlg.h"
-#include "CurveCreator_Curve.hxx"
+//#include "CurveCreator_Curve.hxx"
 
 #include <SUIT_Session.h>
 #include <SUIT_ResourceMgr.h>
 #include <QDialogButtonBox>
 #include <QPushButton>
 
-CurveCreator_NewSectionDlg::CurveCreator_NewSectionDlg( QWidget *parent ) :
-  QWidget(parent)
+CurveCreator_NewSectionDlg::CurveCreator_NewSectionDlg( QWidget *parent, bool enableClosed ) :
+  QWidget(parent), myIsEnableClosed( enableClosed )
 {
+  QVBoxLayout* aMainLayout = new QVBoxLayout( this );
+  aMainLayout->setMargin( 0 );
+
   QFrame* aFrame = new QFrame( this );
+  aMainLayout->addWidget( aFrame );
+
   QVBoxLayout* aLayout = new QVBoxLayout( aFrame );
+  aLayout->setMargin( 0 );
 
   QFrame* aCoordFrame = new QFrame( aFrame );
   QGridLayout* aCoordLayout = new QGridLayout( aCoordFrame );
 
-  QLabel* aLbl = new QLabel(tr("NAME"), this);
+  QLabel* aLbl = new QLabel(tr("SECTION_NAME"), this);
   myName = new QLineEdit(this);
   aCoordLayout->addWidget(aLbl, 0, 0);
   aCoordLayout->addWidget(myName, 0 , 1);
 
-  aLbl = new QLabel(tr("LINE_TYPE"));
+  aLbl = new QLabel(tr("SECTION_LINE_TYPE"));
   myLineType = new QComboBox(this);
 
   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
@@ -54,22 +60,26 @@ CurveCreator_NewSectionDlg::CurveCreator_NewSectionDlg( QWidget *parent ) :
 
 //  QPixmap aPolylinePixmap = QPixmap(tr(":images/ICON_POLYLINE"));
 //  QPixmap aSplinePixmap = QPixmap(tr(":images/ICON_SPLINE"));
-  myLineType->addItem(aPolylinePixmap, tr("POLYLINE_TYPE"));
-  myLineType->addItem(aSplinePixmap, tr("SPLINE_TYPE"));
+  myLineType->addItem(aPolylinePixmap, tr("SECTION_POLYLINE_TYPE"));
+  myLineType->addItem(aSplinePixmap, tr("SECTION_SPLINE_TYPE"));
   myLineType->setCurrentIndex(0);
   aCoordLayout->addWidget(aLbl, 1, 0);
   aCoordLayout->addWidget(myLineType, 1 , 1);
 
-  aLbl = new QLabel(tr("LINE_CLOSED"));
+  aLbl = new QLabel(tr("SECTION_LINE_CLOSED"));
   myIsClosed = new QCheckBox(this);
   aCoordLayout->addWidget(aLbl, 2, 0);
   aCoordLayout->addWidget(myIsClosed, 2, 1);
+  if ( !myIsEnableClosed ) {
+    aLbl->hide();
+    myIsClosed->hide();
+  }
 
   myBtnFrame = new QFrame( aFrame );
   QHBoxLayout* aBtnsLayout = new QHBoxLayout( myBtnFrame );
 
-  myAddBtn = new QPushButton( tr( "ADD_BTN" ), myBtnFrame );
-  myCancelBtn = new QPushButton( tr( "CANCEL" ), myBtnFrame );
+  myAddBtn = new QPushButton( tr( "SECTION_ADD_BTN" ), myBtnFrame );
+  myCancelBtn = new QPushButton( tr( "SECTION_CANCEL_BTN" ), myBtnFrame );
 
   connect( myAddBtn,  SIGNAL( clicked() ), this, SIGNAL( addSection() ) );
   connect( myCancelBtn, SIGNAL( clicked() ), this, SIGNAL( cancelSection() ) );
@@ -82,7 +92,7 @@ CurveCreator_NewSectionDlg::CurveCreator_NewSectionDlg( QWidget *parent ) :
   aLayout->addWidget( myBtnFrame, 1 );
 }
 
-void CurveCreator_NewSectionDlg::setSectionParameters( const QString& theName, bool isClosed, CurveCreator::Type theType )
+void CurveCreator_NewSectionDlg::setSectionParameters( const QString& theName, bool isClosed, CurveCreator::SectionType theType )
 {
   myName->setText(theName);
   myIsClosed->setChecked(isClosed);
@@ -103,12 +113,12 @@ void CurveCreator_NewSectionDlg::setEditMode( bool isEdit )
 {
   myIsEdit = isEdit;
   if( myIsEdit ){
-    myAddBtn->setText(tr("OK"));
+    myAddBtn->setText(tr("SECTION_OK_BTN"));
     myAddBtn->disconnect( SIGNAL( clicked() ) );
     connect( myAddBtn, SIGNAL( clicked() ), this, SIGNAL( modifySection() ) );
   }
   else{
-    myAddBtn->setText(tr("ADD_BTN"));
+    myAddBtn->setText(tr("SECTION_ADD_BTN"));
     myAddBtn->disconnect( SIGNAL( clicked() ) );
     connect( myAddBtn, SIGNAL( clicked() ), this, SIGNAL( addSection() ) );
   }
@@ -125,12 +135,12 @@ bool CurveCreator_NewSectionDlg::isClosed() const
   return myIsClosed->isChecked();
 }
 
-CurveCreator::Type CurveCreator_NewSectionDlg::getSectionType() const
+CurveCreator::SectionType CurveCreator_NewSectionDlg::getSectionType() const
 {
   if( myLineType->currentIndex() == 0 )
     return CurveCreator::Polyline;
   else
-    return CurveCreator::BSpline;
+    return CurveCreator::Spline;
 }
 
 void CurveCreator_NewSectionDlg::updateTitle()
old mode 100755 (executable)
new mode 100644 (file)
index 7f028f2..d37ed11
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #define CURVECREATOR_NEWSECTION_H
 
 #include "CurveCreator.hxx"
+#include "CurveCreator_ICurve.hxx"
 
 #include <QDockWidget>
 
-class CurveCreator_Curve;
+//class CurveCreator_Curve;
 
 class QLineEdit;
 class QComboBox;
@@ -38,16 +39,17 @@ class CurveCreator_NewSectionDlg : public QWidget
 {
   Q_OBJECT
 public:
-  explicit CurveCreator_NewSectionDlg(QWidget *parent = 0);
+  explicit CurveCreator_NewSectionDlg(QWidget *parent = 0, bool enableClosed = true );
 
   QString getName() const;
   bool    isClosed() const;
-  CurveCreator::Type getSectionType() const;
+  CurveCreator::SectionType getSectionType() const;
 
-  void    setSectionParameters( const QString& theName, bool isClosed, CurveCreator::Type theType );
+  void    setSectionParameters( const QString& theName, bool isClosed, CurveCreator::SectionType theType );
   void    setSectionName(const QString& theName );
   void    clear();
   void    setEditMode( bool isEdit );
+  bool    isEnableClosed() const { return myIsEnableClosed; }
 
 signals:
   void    addSection();
@@ -63,6 +65,7 @@ private:
   QComboBox*          myLineType;
   QCheckBox*          myIsClosed;
   bool                myIsEdit;
+  bool                myIsEnableClosed;
   QPushButton*        myAddBtn;
   QPushButton*        myCancelBtn;
 };
index 2e4b6416ad77ecc39542be1a92f6bc39dee7604c..173e1c8817fdcabd8c6ebf84940c751accafbd22 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,6 +22,7 @@
 
 #include "CurveCreator_Operation.hxx"
 #include "CurveCreator_Curve.hxx"
+#include "CurveCreator.hxx"
 
 #include <string>
 #include <stdlib.h>
@@ -46,6 +47,11 @@ CurveCreator_Operation::~CurveCreator_Operation()
   clear();
 }
 
+bool compId(CurveCreator_PosPoint* p1, CurveCreator_PosPoint* p2)
+{
+  return p1->myID < p2->myID;
+}
+
 //=======================================================================
 // function: Constructor
 // purpose:
@@ -54,8 +60,7 @@ bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType)
 {
   bool isOK = false;
 
-  if (theType == CurveCreator_Operation::Clear ||
-      theType == CurveCreator_Operation::Join) {
+  if (theType == CurveCreator_Operation::Clear) {
     clear();
     myType = theType;
     isOK   = true;
@@ -113,56 +118,28 @@ bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
 // function: Constructor
 // purpose:
 //=======================================================================
-bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
-                                  const int theIntParam1,
-                                  const int theIntParam2,
-                                  const int theIntParam3)
+bool CurveCreator_Operation::init(const Type theType, const std::list<int> theParamList)
 {
   bool isOK = false;
 
-  if (theType == CurveCreator_Operation::RemovePoints) {
-    int *pData = (int *)allocate(3*sizeof(int));
-
-    pData[0] = theIntParam1;
-    pData[1] = theIntParam2;
-    pData[2] = theIntParam3;
-    myType   = theType;
-    isOK     = true;
-  }
-
-  return isOK;
-}
-
-//=======================================================================
-// function: Constructor
-// purpose:
-//=======================================================================
-bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
-                                  const CurveCreator::Coordinates &theCoords,
-                                  const int theIntParam)
-{
-  bool isOK = false;
+  if (theType == CurveCreator_Operation::Join)
+  {
+    const int aNbPoints = theParamList.size();
 
-  if (theType == CurveCreator_Operation::AddPoints) {
-    const int aNbCoords = theCoords.size();
     const size_t aSize =
-      2*sizeof(theIntParam) + aNbCoords*sizeof(CurveCreator::TypeCoord);
-    int *pIntData = (int *)allocate(aSize);
-
-    *pIntData++ = theIntParam;
-    *pIntData++ = aNbCoords;
+      sizeof(aNbPoints) +
+      aNbPoints * (sizeof(int));
 
-    CurveCreator::TypeCoord *pRealData = (CurveCreator::TypeCoord *)pIntData;
-    int i = 0;
+    int *pIntData = (int *)allocate(aSize);
 
-    for (; i < aNbCoords; i++) {
-      *pRealData++ = theCoords[i];
-    }
+    *pIntData++ = aNbPoints;
+    std::list<int>::const_iterator anIt = theParamList.begin(), aLast = theParamList.end();
+    for ( ; anIt != aLast; anIt++ )
+      *pIntData++ = *anIt;
 
-    myType = theType;
+    myType   = theType;
     isOK   = true;
   }
-
   return isOK;
 }
 
@@ -172,21 +149,17 @@ bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
 //=======================================================================
 bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
                                   const CurveCreator::Coordinates &theCoords,
-                                  const int theIntParam1,
-                                  const int theIntParam2)
+                                  const int theIntParam)
 {
   bool isOK = false;
 
-  if (theType == CurveCreator_Operation::AddSection   ||
-      theType == CurveCreator_Operation::InsertPoints ||
-      theType == CurveCreator_Operation::SetCoordinates) {
+  if (theType == CurveCreator_Operation::AddPoints) {
     const int aNbCoords = theCoords.size();
     const size_t aSize =
-      3*sizeof(theIntParam1) + aNbCoords*sizeof(CurveCreator::TypeCoord);
+      2*sizeof(theIntParam) + aNbCoords*sizeof(CurveCreator::TypeCoord);
     int *pIntData = (int *)allocate(aSize);
 
-    *pIntData++ = theIntParam1;
-    *pIntData++ = theIntParam2;
+    *pIntData++ = theIntParam;
     *pIntData++ = aNbCoords;
 
     CurveCreator::TypeCoord *pRealData = (CurveCreator::TypeCoord *)pIntData;
@@ -234,7 +207,7 @@ bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
     pIntData = (int*)aStrPtr;
     *pIntData++ = aNbCoords;
 
-    CurveCreator::TypeCoord *pRealData = (CurveCreator::TypeCoord *)aStrPtr;
+    CurveCreator::TypeCoord *pRealData = (CurveCreator::TypeCoord *)pIntData;
     int i = 0;
 
     for (; i < aNbCoords; i++) {
@@ -269,6 +242,84 @@ bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
     return false;
 }
 
+bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
+                                  const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1)
+{
+  bool isOK = false;
+
+  if (theType == CurveCreator_Operation::InsertPoints ||
+      theType == CurveCreator_Operation::SetCoordinates ) {
+
+    const int aNbPoints = theParamList1.size();
+
+    CurveCreator_ICurve::SectionToPointCoordsList::const_iterator anIt = 
+      theParamList1.begin();
+    const int aNbCoords = anIt->second.size();
+
+    const size_t aSize =
+      sizeof(aNbPoints) + sizeof(aNbCoords) + 
+      aNbPoints * (3*sizeof(int) + aNbCoords*sizeof(CurveCreator::TypeCoord));
+    int *pIntData = (int *)allocate(aSize);
+
+    *pIntData++ = aNbPoints;
+    *pIntData++ = aNbCoords;
+    int aSectionId, aPointId;
+    for ( ; anIt != theParamList1.end(); anIt++ ) {
+      aSectionId = anIt->first.first;
+      aPointId = anIt->first.second;
+
+      *pIntData++ = aSectionId;
+      *pIntData++ = aPointId;
+      *pIntData++ = aNbCoords;
+
+      const CurveCreator::Coordinates &aCoords = anIt->second;
+      CurveCreator::TypeCoord *pRealData = (CurveCreator::TypeCoord *)pIntData;
+      for (int i = 0; i < aNbCoords; i++) {
+        *pRealData++ = aCoords[i];
+      }
+      pIntData = (int *)pRealData;
+    }
+
+    myType = theType;
+    isOK   = true;
+  }
+
+  return isOK;
+}
+
+bool CurveCreator_Operation::init(const CurveCreator_Operation::Type theType,
+                                  const CurveCreator_ICurve::SectionToPointList &theParamList1)
+{
+  bool isOK = false;
+
+  if (theType == CurveCreator_Operation::RemovePoints) {
+    const int aNbPoints = theParamList1.size();
+
+    CurveCreator_ICurve::SectionToPointList::const_iterator anIt = 
+      theParamList1.begin();
+
+    const size_t aSize =
+      sizeof(aNbPoints) +
+      aNbPoints * (2*sizeof(int));
+    int *pIntData = (int *)allocate(aSize);
+
+    *pIntData++ = aNbPoints;
+    int aSectionId, aPointId;
+    for ( ; anIt != theParamList1.end(); anIt++ ) {
+      aSectionId = anIt->first;
+      aPointId = anIt->second;
+
+      *pIntData++ = aSectionId;
+      *pIntData++ = aPointId;
+    }
+
+    myType = theType;
+    isOK   = true;
+  }
+
+  return isOK;
+}
+
 //=======================================================================
 // function: apply
 // purpose:
@@ -280,58 +331,81 @@ void CurveCreator_Operation::apply(CurveCreator_Curve *theCurve)
 
     switch (myType) {
       case CurveCreator_Operation::AddPoints:
+      case CurveCreator_Operation::InsertPoints:
+      case CurveCreator_Operation::SetCoordinates:
         {
+          int aSectionId, aPointId;
+          CurveCreator::SectionsMap aSectionsMap;
+          CurveCreator::PosPointsList aPoints;
           CurveCreator::Coordinates aCoords;
 
-          getCoords(&pInt[1], aCoords);
-          theCurve->addPoints(aCoords, pInt[0]);
+          int nbPoints = pInt[0];
+          int nbCoords = pInt[1];
+          int nbParams = 3+nbCoords;
+          for (int i = 0; i < nbPoints*nbParams; i=i+nbParams) {
+            aCoords.clear();
+            aPoints.clear();
+            getCoords(&pInt[4+i], aCoords);
+            aSectionId = pInt[2+i];
+            aPointId = pInt[3+i];
+            if ( aSectionsMap.find( aSectionId ) != aSectionsMap.end() )
+              aPoints = aSectionsMap[aSectionId];
+            CurveCreator_PosPoint* aPosPoint = new CurveCreator_PosPoint( aPointId, aCoords );
+            aPoints.push_back( aPosPoint );
+            aPoints.sort(compId);
+            aSectionsMap[aSectionId] = aPoints;
+          }
+          switch (myType) {
+            case CurveCreator_Operation::AddPoints:
+            case CurveCreator_Operation::InsertPoints:
+              theCurve->addPointsInternal( aSectionsMap );
+              break;
+            case CurveCreator_Operation::SetCoordinates:
+              theCurve->setPointInternal( aSectionsMap );
+              break;
+          }
         }
         break;
       case CurveCreator_Operation::RemovePoints:
-        theCurve->removePoints(pInt[0], pInt[1], pInt[2]);
-        break;
-      case CurveCreator_Operation::InsertPoints:
         {
-          CurveCreator::Coordinates aCoords;
-
-          getCoords(&pInt[2], aCoords);
-          theCurve->insertPoints(aCoords, pInt[0], pInt[1]);
+          CurveCreator_ICurve::SectionToPointList aListOfSectionsToPoints;
+          int nbPoints = pInt[0];
+          for (int i = 1; i < nbPoints*2; i=i+2) {
+            aListOfSectionsToPoints.push_back(std::make_pair(pInt[i], pInt[i+1]));
+          }
+          theCurve->removePointsInternal(aListOfSectionsToPoints);
         }
         break;
       case CurveCreator_Operation::SetType:
         {
-          const CurveCreator::Type aType = (CurveCreator::Type) pInt[0];
+          const CurveCreator::SectionType aType = (CurveCreator::SectionType) pInt[0];
 
-          theCurve->setType(aType, pInt[1]);
+          theCurve->setSectionTypeInternal( pInt[1], aType );
         }
         break;
       case CurveCreator_Operation::Clear:
-        theCurve->clear();
-        break;
-      case CurveCreator_Operation::SetCoordinates:
-        {
-          CurveCreator::Coordinates aCoords;
-
-          getCoords(&pInt[2], aCoords);
-          theCurve->setCoordinates(aCoords, pInt[0], pInt[1]);
-        }
+        theCurve->clearInternal();
         break;
       case CurveCreator_Operation::SetClosed:
-        theCurve->setClosed((pInt[0] != 0), pInt[1]);
+        theCurve->setClosedInternal(pInt[1], (pInt[0] != 0));
         break;
       case CurveCreator_Operation::MoveSection:
-        theCurve->moveSection(pInt[0], pInt[1]);
+        theCurve->moveSectionInternal(pInt[0], pInt[1]);
         break;
       case CurveCreator_Operation::Join:
-        if (myPData == NULL) {
-          theCurve->join();
-        } else {
-          theCurve->join(pInt[0], pInt[1]);
+        if (myPData != NULL)
+        {
+          std::list<int> aListOfSections;
+          int nbSections = pInt[0];
+          for (int i = 1; i < nbSections+1; i++) {
+            aListOfSections.push_back(pInt[i]);
+          }
+          theCurve->joinInternal(aListOfSections);
         }
         break;
       case CurveCreator_Operation::AddSection:
         {
-          const CurveCreator::Type aType = (CurveCreator::Type) pInt[0];
+          const CurveCreator::SectionType aType = (CurveCreator::SectionType) pInt[0];
 
           std::string aName = std::string((char*)&pInt[2]);
 
@@ -340,16 +414,16 @@ void CurveCreator_Operation::apply(CurveCreator_Curve *theCurve)
           char* aPtr =  ((char*)&pInt[2]);
           aPtr += (aName.length()) + 1;
           getCoords((int*)aPtr, aCoords);
-          theCurve->addSection(aName, aType, (pInt[1] != 0), aCoords);
+          theCurve->addSectionInternal(aName, aType, (pInt[1] != 0), aCoords);
         }
         break;
       case CurveCreator_Operation::RemoveSection:
-        theCurve->removeSection(pInt[0]);
+        theCurve->removeSectionInternal(pInt[0]);
         break;
       case CurveCreator_Operation::RenameSection:
         {
             std::string aName = std::string((char*)&pInt[1]);
-            theCurve->setName(aName, pInt[0]);
+            theCurve->setSectionNameInternal(pInt[0], aName);
         }
         break;
       default:
index a74ac19ca10bb2a10cbfe785047d3c488d5a76ae..855d0da2a33e0abec6e601c9de97c14a7f743bc5 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #define _CurveCreator_Operation_HeaderFile
 
 #include "CurveCreator.hxx"
+#include "CurveCreator_ICurve.hxx"
+#include "CurveCreator_PosPoint.hxx"
 
 #include <string>
+#include <vector>
 
 class CurveCreator_Curve;
 
@@ -74,7 +77,6 @@ public:
    * It is applicable to the following operations:
    * <UL>
    *   <LI>Clear</LI>
-   *   <LI>Join (without arguments)</LI>
    * </UL>
    * @return true in case of success; false otherwise.
    */
@@ -105,15 +107,26 @@ public:
             const int theIntParam2);
 
   /**
-   * This method initializes the object with an operation with three integer
+   * This method initializes the object with an operation with two integer
    * parameters. It is applicable to the following operations:
    * <UL>
+   *   <LI>Join (with a list of int arguments)</LI>
+   * </UL>
+   * @return true in case of success; false otherwise.
+   */
+  bool init(const Type theType, const std::list<int> theParamList);
+
+  /**
+   * This method initializes the object with an operation with 
+   * list of pairs of integer parameters. 
+   * It is applicable to the following operations:
+   * <UL>
    *   <LI>RemovePoints</LI>
    * </UL>
    * @return true in case of success; false otherwise.
    */
-  bool init(const Type theType, const int theIntParam1,
-            const int theIntParam2, const int theIntParam3);
+  bool init(const Type theType, 
+    const CurveCreator_ICurve::SectionToPointList &theParamList1);
 
   /**
    * This method initializes the object with an operation with one
@@ -128,18 +141,16 @@ public:
             const int theIntParam);
 
   /**
-   * This method initializes the object with an operation with one
-   * CurveCreator::Coordinates parameter and two integer parameters.
+   * This method initializes the object with an operation with
+   * list of pairs of integer parameters and CurveCreator::Coordinates parameters.
    * It is applicable to the following operations:
    * <UL>
-   *   <LI>AddSection</LI>
    *   <LI>InsertPoints</LI>
-   *   <LI>SetCoordinates</LI>
    * </UL>
    * @return true in case of success; false otherwise.
    */
-  bool init(const Type theType, const CurveCreator::Coordinates &theCoords,
-            const int theIntParam1, const int theIntParam2);
+  bool init(const Type theType, 
+            const CurveCreator_ICurve::SectionToPointCoordsList &theParamList1);
 
   /**
    * This method initializes the object with an operation with one
diff --git a/src/CurveCreator/CurveCreator_PosPoint.hxx b/src/CurveCreator/CurveCreator_PosPoint.hxx
new file mode 100644 (file)
index 0000000..2301374
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File:        CurveCreator_PosPoint.hxx
+// Author:      Alexander KOVALEV
+
+#ifndef _CurveCreator_PosPoint_HeaderFile
+#define _CurveCreator_PosPoint_HeaderFile
+
+#include "CurveCreator.hxx"
+
+struct CurveCreator_PosPoint
+{
+public:
+  CurveCreator_PosPoint( int theID, CurveCreator::Coordinates theCoords ) 
+    : myID( theID ), myCoords( theCoords )
+  { };
+
+  ////! Overloaded operator to use sorting.
+  //bool operator < (CurveCreator_PosPoint const & thePosPoint) const 
+  //{
+  //  return myID < thePosPoint.myID;
+  //}
+
+  int                       myID;     // point ID
+  CurveCreator::Coordinates myCoords; // point coordinates
+
+};
+
+#endif
index 0eafa06292b85cb8c2441999288e760e6012e936..68b03aaa7e01ba0f75ca82bd9ad1fcecf0cfb6fc 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -36,7 +36,7 @@ struct CurveCreator_Section
 
   std::string               myName; //!< section name
   CurveCreator::Coordinates myPoints;   //!< points coordinates
-  CurveCreator::Type        myType;     //!< type of the section
+  CurveCreator::SectionType myType;     //!< type of the section
   bool                      myIsClosed; //!< closed or not
 
 };
diff --git a/src/CurveCreator/CurveCreator_TableView.cxx b/src/CurveCreator/CurveCreator_TableView.cxx
new file mode 100644 (file)
index 0000000..b407605
--- /dev/null
@@ -0,0 +1,178 @@
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "CurveCreator_TableView.h"
+#include "CurveCreator_UtilsICurve.hxx"
+
+#include <gp_Pnt.hxx>
+
+#include <QTableWidget>
+#include <QTableWidgetItem>
+
+#include <QtxDoubleSpinBox.h>
+
+const double DBL_MINIMUM = -10000000.;
+const double DBL_MAXIMUM = 10000000.;
+
+const int SECTION_NAME_COLUMN_WIDTH = 75;
+const int POINT_INDEX_COLUMN_WIDTH = 40;
+
+const double LOCAL_SELECTION_TOLERANCE = 0.0001;
+
+CurveCreator_TableItemDelegate::CurveCreator_TableItemDelegate( QObject* theParent )
+: QItemDelegate( theParent )
+{
+}
+
+/**
+ * Creates an editor for the cell
+ */
+QWidget* CurveCreator_TableItemDelegate::createEditor( QWidget* theParent,
+                                                       const QStyleOptionViewItem& theOption,
+                                                       const QModelIndex& theIndex ) const
+{
+  QWidget* anEditor = 0;
+
+  int aColumnId = theIndex.column();
+  if ( aColumnId == 2 || aColumnId == 3 ) {
+    QDoubleSpinBox* aSpin = new QtxDoubleSpinBox( theParent );
+    aSpin->setDecimals( 2 );
+    aSpin->setRange( DBL_MINIMUM, DBL_MAXIMUM );
+    anEditor = aSpin;
+  }
+  else
+    anEditor = QItemDelegate::createEditor( theParent, theOption, theIndex );
+
+  return anEditor;
+}
+
+void CurveCreator_TableItemDelegate::setEditorData( QWidget* theEditor,
+                                                    const QModelIndex& theIndex ) const
+{
+  int aColumnId = theIndex.column();
+  if ( aColumnId == 2 || aColumnId == 3 ) {
+    QDoubleSpinBox* aDblSpin = dynamic_cast<QDoubleSpinBox*>( theEditor );
+    if ( aDblSpin ) {
+      double aValue = theIndex.model()->data( theIndex, Qt::EditRole ).toDouble();
+      aDblSpin->setValue( aValue );
+    }
+  }
+  else
+   QItemDelegate::setEditorData( theEditor, theIndex );
+}
+
+void CurveCreator_TableItemDelegate::setModelData( QWidget* theEditor,
+                                                   QAbstractItemModel* theModel,
+                                                   const QModelIndex& theIndex ) const
+{
+  int aColumnId = theIndex.column();
+  if ( aColumnId == 2 || aColumnId == 3 ) {
+    QDoubleSpinBox* aDblSpin = dynamic_cast<QDoubleSpinBox*>( theEditor );
+    if ( aDblSpin ) {
+      double aValue = aDblSpin->value();
+      theModel->setData( theIndex, aValue, Qt::UserRole);
+    }
+  }
+  else
+    QItemDelegate::setModelData( theEditor, theModel, theIndex );
+}
+
+CurveCreator_TableView::CurveCreator_TableView( CurveCreator_ICurve* theCurve,
+                                                QWidget* theParent,
+                                                const QStringList& theCoordTitles )
+: QTableWidget( theParent ), myCurve( theCurve )
+{
+  setItemDelegate( new CurveCreator_TableItemDelegate( this ) );
+  setVisible( false );
+  setColumnCount( 4 );
+  setColumnWidth( 0, SECTION_NAME_COLUMN_WIDTH );
+  setColumnWidth( 1, POINT_INDEX_COLUMN_WIDTH );
+  QStringList aLabels;
+  QString aCoord1 = theCoordTitles.size() > 0 ? theCoordTitles[0] : tr( "TABLE_X" ); // tr( "X_POSITION_LBL" )
+  QString aCoord2 = theCoordTitles.size() > 1 ? theCoordTitles[1] : tr( "TABLE_Y" ); // tr( "Y_POSITION_LBL" )
+  //aLabels << tr( "SECTION_LABEL" ) << tr( "IDENTIFIER_LABEL" ) << aCoord1 << aCoord2;
+  aLabels << tr( "TABLE_SECTION" ) << tr("TABLE_INDEX") << aCoord1 << aCoord2;
+  setHorizontalHeaderLabels( aLabels );
+}
+
+void CurveCreator_TableView::setCurve( CurveCreator_ICurve* theCurve )
+{
+  myCurve = theCurve;
+}
+
+void CurveCreator_TableView::setLocalPointsToTable(
+  const CurveCreator_ICurve::SectionToPointList& thePoints )
+{
+  setRowCount( thePoints.size() );
+
+  int aRowId = 0;
+  CurveCreator_ICurve::SectionToPointList::const_iterator anIt = thePoints.begin(),
+                                                          aLast = thePoints.end();
+  for ( ; anIt != aLast; anIt++ ) {
+    CurveCreator_ICurve::SectionToPoint aSPoint = *anIt;
+    int anISection = aSPoint.first;
+    int anIPoint = aSPoint.second;
+
+    QTableWidgetItem* anItem;
+    anItem = new QTableWidgetItem( myCurve->getSectionName( anISection ).c_str() );
+    anItem->setFlags( anItem->flags() & ~Qt::ItemIsEnabled );
+    anItem->setData( Qt::UserRole, anISection );
+    setItem( aRowId, 0, anItem );
+
+    anItem = new QTableWidgetItem( QString::number( anIPoint + 1 ) );
+    anItem->setFlags( anItem->flags() & ~Qt::ItemIsEnabled );
+    anItem->setData( Qt::UserRole, anIPoint );
+    setItem( aRowId, 1, anItem );
+
+    gp_Pnt aPoint;
+    CurveCreator_UtilsICurve::getPoint( myCurve, anISection, anIPoint, aPoint );
+
+    anItem = item( aRowId, 2 );
+    if ( !anItem ) {
+      anItem = new QTableWidgetItem();
+      setItem( aRowId, 2, anItem );
+    }
+    anItem->setData( Qt::UserRole, aPoint.X() );
+    anItem->setData( Qt::DisplayRole, QString::number( aPoint.X(), 'f', 2 ) );
+
+    anItem = item( aRowId, 3 );
+    if ( !anItem ) {
+      anItem = new QTableWidgetItem();
+      setItem( aRowId, 3, anItem );
+    }
+    anItem->setData( Qt::UserRole, aPoint.Y() );
+    anItem->setData( Qt::DisplayRole, QString::number( aPoint.Y(), 'f', 2 ) );
+
+    aRowId++;
+  }
+}
+
+int CurveCreator_TableView::getSectionId( const int theRowId ) const
+{
+  return item( theRowId, 0 )->data( Qt::UserRole ).toInt();
+}
+
+/**
+ * Returns a point index from the table
+ * \param theRowId a table row
+ */
+int CurveCreator_TableView::getPointId( const int theRowId ) const
+{
+  return item( theRowId, 1 )->data( Qt::UserRole ).toInt();
+}
diff --git a/src/CurveCreator/CurveCreator_TableView.h b/src/CurveCreator/CurveCreator_TableView.h
new file mode 100644 (file)
index 0000000..4565ab5
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef CURVECREATOR_TABLEVIEW_H
+#define CURVECREATOR_TABLEVIEW_H
+
+#include "CurveCreator_ICurve.hxx"
+
+#include <QItemDelegate>
+#include <QTableWidget>
+
+class CurveCreator_TableItemDelegate : public QItemDelegate
+{
+public:
+  CurveCreator_TableItemDelegate( QObject* theParent );
+  ~CurveCreator_TableItemDelegate() {}
+
+  virtual QWidget* createEditor( QWidget* theParent,
+                                 const QStyleOptionViewItem& theOption,
+                                 const QModelIndex& theIndex ) const;
+  virtual void setEditorData( QWidget* theEditor, const QModelIndex& theIndex ) const;
+  virtual void setModelData( QWidget* theEditor, QAbstractItemModel* theModel,
+                                 const QModelIndex& theIndex ) const;
+};
+
+class CurveCreator_TableView : public QTableWidget
+{
+public:
+  CurveCreator_TableView( CurveCreator_ICurve* theCurve, QWidget* theParent = 0,
+                          const QStringList& theCoordTitles = QStringList() );
+  ~CurveCreator_TableView() {};
+
+  void setCurve( CurveCreator_ICurve* theCurve );
+
+  void setLocalPointsToTable( const CurveCreator_ICurve::SectionToPointList& thePoints );
+
+  /**
+   * Returns a section index from the table
+   * \param theRowId a table row
+   */
+  int getSectionId( const int theRowId ) const;
+  /**
+   * Returns a point index from the table
+   * \param theRowId a table row
+   */
+  int getPointId( const int theRowId ) const;
+
+private:
+  CurveCreator_ICurve* myCurve;
+
+};
+
+#endif // CURVECREATOR_TABLEVIEW_H
old mode 100755 (executable)
new mode 100644 (file)
index 1b7fa95..36d1dfc
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,7 +18,7 @@
 //
 
 #include "CurveCreator_TreeView.h"
-#include "CurveCreator_Curve.hxx"
+#include "CurveCreator_ICurve.hxx"
 
 #include <SUIT_Session.h>
 #include <SUIT_ResourceMgr.h>
@@ -28,7 +28,7 @@
 
 #define ID_SECTION -1
 
-CurveCreator_TreeViewModel::CurveCreator_TreeViewModel( CurveCreator_Curve* theCurve, QObject* parent ) :
+CurveCreator_TreeViewModel::CurveCreator_TreeViewModel( CurveCreator_ICurve* theCurve, QObject* parent ) :
   QAbstractItemModel(parent), myCurve(theCurve)
 {
   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
@@ -86,7 +86,7 @@ QVariant      CurveCreator_TreeViewModel::data(const QModelIndex & index, int role )
       }
       else if( role == Qt::DecorationRole ){
         if( aColumn == 0 ){
-          CurveCreator::Type aSectionType = myCurve->getType(aRow);
+          CurveCreator::SectionType aSectionType = myCurve->getSectionType(aRow);
           if( aSectionType == CurveCreator::Polyline ){
             if( myCurve->isClosed(aRow) ){
               return myCachedIcons[ICON_CLOSED_POLYLINE];
@@ -161,12 +161,12 @@ int       CurveCreator_TreeViewModel::rowCount(const QModelIndex & parent ) const
   int aRowCnt = 0;
   if( myCurve != NULL ){
     if( !parent.isValid() ){
-      //Points level
+      //Section level
       aRowCnt =  myCurve->getNbSections();
     }
     else{
-      //Section level
       if( parent.internalId() == ID_SECTION ){
+        //Points level
         aRowCnt = myCurve->getNbPoints(parent.row());
       }
     }
@@ -210,14 +210,14 @@ int CurveCreator_TreeViewModel::getPoint( const QModelIndex& theIndx ) const
   return theIndx.row();
 }
 
-void CurveCreator_TreeViewModel::setCurve( CurveCreator_Curve* theCurve )
+void CurveCreator_TreeViewModel::setCurve( CurveCreator_ICurve* theCurve )
 {
   myCurve = theCurve;
   reset();
 }
 
 /*****************************************************************************************/
-CurveCreator_TreeView::CurveCreator_TreeView( CurveCreator_Curve* theCurve, QWidget *parent) :
+CurveCreator_TreeView::CurveCreator_TreeView( CurveCreator_ICurve* theCurve, QWidget *parent) :
   QTreeView(parent)
 {
   header()->hide();
@@ -249,7 +249,6 @@ QList<int> CurveCreator_TreeView::getSelectedSections() const
       aSect << aModel->getSection( anIndxs[i] );
     }
   }
-  qSort(aSect.begin(), aSect.end());
   return aSect;
 }
 
@@ -290,7 +289,11 @@ void CurveCreator_TreeView::sectionAdded( int theSection )
 {
   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
   if( aModel ){
-    rowsInserted(QModelIndex(), theSection, theSection );
+    int nbRows = aModel->rowCount();
+    int aSection = (theSection == -1 ? (nbRows==0 ? 0 : nbRows-1) : theSection);
+    rowsInserted(QModelIndex(), aSection, aSection );
+    QModelIndex aSectIndx = aModel->sectionIndex(aSection);
+    selectionModel()->select(aSectIndx, QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect);
   }
 }
 
@@ -361,16 +364,6 @@ void CurveCreator_TreeView::sectionsSwapped( int theSection, int theOffset )
   }
 }
 
-void CurveCreator_TreeView::pointsSwapped( int theSection, int thePointNum, int theOffset )
-{
-  CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
-  if( aModel ){
-    QModelIndex aFirstIndex = aModel->pointIndex( theSection, thePointNum );
-    QModelIndex aSecondIndex = aModel->pointIndex( theSection, thePointNum + theOffset );
-    swapIndexes( aFirstIndex, aSecondIndex );
-  }
-}
-
 void CurveCreator_TreeView::setSelectedSections( const QList<int>& theList )
 {
   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
@@ -378,19 +371,7 @@ void CurveCreator_TreeView::setSelectedSections( const QList<int>& theList )
     selectionModel()->clearSelection();
     for( int i = 0 ; i < theList.size() ; i++ ){
       QModelIndex aSectIndx = aModel->sectionIndex(theList[i]);
-      selectionModel()->select(aSectIndx, QItemSelectionModel::Select );
-    }
-  }
-}
-
-void CurveCreator_TreeView::setSelectedPoints( const QList< QPair<int, int> >& thePointsList )
-{
-  CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
-  if( aModel ){
-    selectionModel()->clearSelection();
-    for( int i = 0 ; i < thePointsList.size() ; i++ ){
-      QModelIndex aSectIndx = aModel->pointIndex( thePointsList[i].first, thePointsList[i].second );
-      selectionModel()->select(aSectIndx, QItemSelectionModel::Select );
+      selectionModel()->select(aSectIndx, QItemSelectionModel::Select | QItemSelectionModel::Rows );
     }
   }
 }
@@ -404,25 +385,6 @@ bool pointLessThan(const QPair<int,int> &s1, const QPair<int,int> &s2)
   return s1.second < s2.second;
 }
 
-QList< QPair< int, int > > CurveCreator_TreeView::getSelectedPoints() const
-{
-  QList< QPair< int, int > > aPoints;
-  CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
-  if( !aModel )
-    return aPoints;
-  QModelIndexList anIndxs = selectionModel()->selectedIndexes();
-  for( int i = 0 ; i < anIndxs.size() ; i++ ){
-    if( !aModel->isSection( anIndxs[i] ) ){
-      int aSect = aModel->getSection(anIndxs[i]);
-      int aPointNum = aModel->getPoint(anIndxs[i]);
-      QPair< int, int > aPoint = QPair<int,int>( aSect, aPointNum );
-      aPoints.push_back( aPoint );
-    }
-  }
-  qSort( aPoints.begin(), aPoints.end(), pointLessThan );
-  return aPoints;
-}
-
 CurveCreator_TreeView::SelectionType CurveCreator_TreeView::getSelectionType() const
 {
   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
@@ -470,16 +432,20 @@ void CurveCreator_TreeView::onActivated( QModelIndex theIndx )
   int aSect = aModel->getSection(theIndx);
   if( aModel->isSection(theIndx) ){
     emit sectionEntered( aSect );
-    return;
   }
-  int aPointNum = aModel->getPoint( theIndx );
-  emit pointEntered( aSect, aPointNum );
 }
 
-void CurveCreator_TreeView::setCurve( CurveCreator_Curve* theCurve )
+void CurveCreator_TreeView::setCurve( CurveCreator_ICurve* theCurve )
 {
   CurveCreator_TreeViewModel* aModel = dynamic_cast<CurveCreator_TreeViewModel*>(model());
   if( aModel )
     aModel->setCurve(theCurve);
   reset();
 }
+
+void CurveCreator_TreeView::reset()
+{
+  QList<int> aSelSections = getSelectedSections();
+  QTreeView::reset();
+  setSelectedSections(aSelSections);
+}
old mode 100755 (executable)
new mode 100644 (file)
index 09929bf..be00a75
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #include <QTreeView>
 #include <QAbstractItemModel>
 
-class CurveCreator_Curve;
+class CurveCreator_ICurve;
 
 class CurveCreator_TreeViewModel : public QAbstractItemModel
 {
 public:
-  CurveCreator_TreeViewModel( CurveCreator_Curve* theCurve, QObject* parent );
+  CurveCreator_TreeViewModel( CurveCreator_ICurve* theCurve, QObject* parent );
   virtual int  columnCount(const QModelIndex & parent = QModelIndex()) const;
   virtual int  rowCount(const QModelIndex & parent = QModelIndex()) const;
   virtual QVariant     data(const QModelIndex & index, int role = Qt::DisplayRole) const;
@@ -44,12 +44,12 @@ public:
   int     getSection( const QModelIndex& theIndx ) const;
   int     getPoint( const QModelIndex& theIndx ) const;
 
-  void    setCurve( CurveCreator_Curve* theCurve );
+  void    setCurve( CurveCreator_ICurve* theCurve );
 
 private:
   enum IconType{ ICON_POLYLINE, ICON_SPLINE, ICON_CLOSED_SPLINE, ICON_CLOSED_POLYLINE, ICON_POINT };
 private:
-  CurveCreator_Curve*          myCurve;
+  CurveCreator_ICurve*          myCurve;
   QMap<IconType, QPixmap>      myCachedIcons;
 };
 
@@ -59,15 +59,13 @@ class CurveCreator_TreeView : public QTreeView
 public:
   enum SelectionType{ ST_NOSEL, ST_POINTS, ST_POINTS_ONE_SECTION, ST_SECTIONS, ST_MIXED };
 public:
-  explicit CurveCreator_TreeView( CurveCreator_Curve* theCurve, QWidget *parent = 0);
+  explicit CurveCreator_TreeView( CurveCreator_ICurve* theCurve, QWidget *parent = 0);
   SelectionType getSelectionType() const;
   QList<int> getSelectedSections() const;
-  QList< QPair< int, int > > getSelectedPoints() const;
 
   void    pointsAdded( int theSection, int thePoint, int thePointsCnt=1 );
   void    pointDataChanged( int theSection, int thePoint );
   void    pointsRemoved(int theSection, int thePoint, int thePointsCnt=1 );
-  void    pointsSwapped( int theSection, int thePointNum, int theOffset );
 
   void    sectionAdded( int theSection );
   void    sectionChanged(int theSection , int aSectCnt = 1);
@@ -75,15 +73,15 @@ public:
   void    sectionsSwapped( int theSection, int theOffset );
 
   void    setSelectedSections( const QList<int>& theList );
-  void    setSelectedPoints( const QList< QPair<int, int> >& thePointsList );
 
-  void    setCurve( CurveCreator_Curve* theCurve );
+  void    setCurve( CurveCreator_ICurve* theCurve );
+
+  void    reset();
 
 signals:
   void    selectionChanged();
   void    sectionEntered(int);
-  void    pointEntered(int,int);
-public slots:
+
 protected slots:
   void onActivated( QModelIndex theIndx );
 protected:
diff --git a/src/CurveCreator/CurveCreator_UndoOptsDlg.cxx b/src/CurveCreator/CurveCreator_UndoOptsDlg.cxx
deleted file mode 100644 (file)
index ec8fd58..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-// File:        CurveCreator_UndoOptsDlg.cxx
-// Author:      Sergey KHROMOV
-
-#include "CurveCreator_UndoOptsDlg.h"
-
-#include <QButtonGroup>
-#include <QGridLayout>
-#include <QGroupBox>
-#include <QIntValidator>
-#include <QLineEdit>
-#include <QPushButton>
-#include <QRadioButton>
-
-#define UNDO_DEPTH_UNLIMITED  0
-#define UNDO_DEPTH_DISABLED   1
-#define UNDO_DEPTH_FIX_SIZE   2
-
-//=======================================================================
-// function: Constructor
-// purpose:
-//=======================================================================
-CurveCreator_UndoOptsDlg::CurveCreator_UndoOptsDlg(QWidget* parent)
-  : QDialog          (parent),
-    myUndoDepth      (UNDO_DEPTH_UNLIMITED),
-    myOptsBtnGrp     (NULL),
-    myBufferSizeEdit (NULL),
-    myOkBtn          (NULL),
-    myCancelBtn      (NULL)
-{
-  setWindowTitle(tr("CC_UNDO_OPTIONS_TITLE"));
-
-  // Set Undo/Redo options group
-  QGroupBox    *anUndoOptsGrp  =
-            new QGroupBox(tr("CC_UNDO_OPTIONS_MODIFY"));
-  QGridLayout  *anUndoOptsLO   = new QGridLayout(anUndoOptsGrp);
-  QRadioButton *aDisabledRdBtn =
-            new QRadioButton(tr("CC_UNDO_OPTIONS_DISABLED"), anUndoOptsGrp);
-  QRadioButton *aFixSizeRdBtn  =
-            new QRadioButton(tr("CC_UNDO_OPTIONS_FIXED_SIZE"), anUndoOptsGrp);
-  QRadioButton *anUnlimRdBtn   =
-            new QRadioButton(tr("CC_UNDO_OPTIONS_UNLIMITED"), anUndoOptsGrp);
-
-  myOptsBtnGrp     = new QButtonGroup(anUndoOptsGrp);
-  myBufferSizeEdit = new QLineEdit(anUndoOptsGrp);
-  anUndoOptsLO->setMargin(9);
-  anUndoOptsLO->setSpacing(6);
-  anUndoOptsLO->addWidget(aDisabledRdBtn,   0, 0);
-  anUndoOptsLO->addWidget(aFixSizeRdBtn,    1, 0);
-  anUndoOptsLO->addWidget(anUnlimRdBtn,     2, 0);
-  anUndoOptsLO->addWidget(myBufferSizeEdit, 1, 1);
-  myOptsBtnGrp->addButton(anUnlimRdBtn,   UNDO_DEPTH_UNLIMITED);
-  myOptsBtnGrp->addButton(aDisabledRdBtn, UNDO_DEPTH_DISABLED);
-  myOptsBtnGrp->addButton(aFixSizeRdBtn,  UNDO_DEPTH_FIX_SIZE);
-
-  // Set OK/Cancel buttons group
-  QGroupBox   *anOkCancelGrp  = new QGroupBox;
-  QGridLayout *anOkCancelLO   = new QGridLayout(anOkCancelGrp);
-
-  myOkBtn     = new QPushButton(tr("GEOM_BUT_OK"), anOkCancelGrp);
-  myCancelBtn = new QPushButton(tr("GEOM_BUT_CANCEL"), anOkCancelGrp);
-  anOkCancelLO->setMargin(9);
-  anOkCancelLO->setSpacing(6);
-  anOkCancelLO->addWidget(myOkBtn,     0, 0);
-  anOkCancelLO->addWidget(myCancelBtn, 0, 1);
-
-  // Set main group
-  QGroupBox   *aMainGrp = new QGroupBox;
-  QVBoxLayout *aMainLO = new QVBoxLayout(aMainGrp);
-
-  aMainLO->addWidget(anUndoOptsGrp);
-  aMainLO->addWidget(anOkCancelGrp);
-
-  setLayout(aMainLO);
-
-  init();
-}
-
-//=======================================================================
-// function: Destructor
-// purpose:
-//=======================================================================
-CurveCreator_UndoOptsDlg::~CurveCreator_UndoOptsDlg()
-{
-}
-
-//=======================================================================
-// function: setUndoDepth
-// purpose:
-//=======================================================================
-void CurveCreator_UndoOptsDlg::setUndoDepth(const int theDepth)
-{
-  myUndoDepth = theDepth;
-
-  const int aDepthId = myUndoDepth + 1;
-  int       anId     = UNDO_DEPTH_FIX_SIZE;
-
-  if (aDepthId == UNDO_DEPTH_UNLIMITED ||
-      aDepthId == UNDO_DEPTH_DISABLED) {
-    anId = aDepthId;
-  } else if (myUndoDepth > 0) {
-    myBufferSizeEdit->setText(QString::number(myUndoDepth));
-  }
-
-  myOptsBtnGrp->button(anId)->setChecked(true);
-  optionChanged(anId);
-}
-
-//=======================================================================
-// function: getUndoDepth
-// purpose:
-//=======================================================================
-int CurveCreator_UndoOptsDlg::getUndoDepth() const
-{
-  return myUndoDepth;
-}
-
-//=======================================================================
-// function: isEnabled
-// purpose:
-//=======================================================================
-bool CurveCreator_UndoOptsDlg::isEnabled() const
-{
-  return (myUndoDepth + 1 != UNDO_DEPTH_DISABLED);
-}
-
-//=======================================================================
-// function: isUnlimited
-// purpose:
-//=======================================================================
-bool CurveCreator_UndoOptsDlg::isUnlimited() const
-{
-  return (myUndoDepth + 1 == UNDO_DEPTH_UNLIMITED);
-}
-
-//=======================================================================
-// function: init
-// purpose:
-//=======================================================================
-void CurveCreator_UndoOptsDlg::init()
-{
-  // Initialize sections group.
-  myOptsBtnGrp->setExclusive(true);
-  myOptsBtnGrp->button(UNDO_DEPTH_UNLIMITED)->setChecked(true);
-  connect(myOptsBtnGrp, SIGNAL(buttonClicked(int)),
-          this, SLOT(optionChanged(int)));
-
-  // Initialize line edit.
-  QIntValidator *aValidator = new QIntValidator(myBufferSizeEdit);
-
-  aValidator->setBottom(1);
-  myBufferSizeEdit->setValidator(aValidator);
-  optionChanged(UNDO_DEPTH_UNLIMITED);
-
-  // Init buttons.
-  myOkBtn->setDefault(true);
-
-  connect(myOkBtn,     SIGNAL(clicked()), this, SLOT(accept()));
-  connect(myCancelBtn, SIGNAL(clicked()), this, SLOT(reject()));
-
-  setTabOrder();
-}
-
-//=======================================================================
-// function: setTabOrder
-// purpose:
-//=======================================================================
-void CurveCreator_UndoOptsDlg::setTabOrder()
-{
-  QWidget::setTabOrder(myOptsBtnGrp->button(UNDO_DEPTH_DISABLED),
-                       myOptsBtnGrp->button(UNDO_DEPTH_FIX_SIZE));
-  QWidget::setTabOrder(myOptsBtnGrp->button(UNDO_DEPTH_FIX_SIZE),
-                       myBufferSizeEdit);
-  QWidget::setTabOrder(myBufferSizeEdit,
-                       myOptsBtnGrp->button(UNDO_DEPTH_UNLIMITED));
-  QWidget::setTabOrder(myOptsBtnGrp->button(UNDO_DEPTH_UNLIMITED), myOkBtn);
-  QWidget::setTabOrder(myOkBtn, myCancelBtn);
-}
-
-//=======================================================================
-// function: optionChanged
-// purpose:
-//=======================================================================
-void CurveCreator_UndoOptsDlg::optionChanged(int theId)
-{
-  switch (theId) {
-    case UNDO_DEPTH_FIX_SIZE:
-      myBufferSizeEdit->setEnabled(true);
-      break;
-    case UNDO_DEPTH_UNLIMITED:
-    case UNDO_DEPTH_DISABLED:
-    default:
-      myBufferSizeEdit->setEnabled(false);
-      break;
-  }
-}
-
-//=======================================================================
-// function: accept
-// purpose:
-//=======================================================================
-void CurveCreator_UndoOptsDlg::accept()
-{
-  const int anId = myOptsBtnGrp->checkedId();
-
-  switch (anId) {
-    case UNDO_DEPTH_FIX_SIZE:
-      myUndoDepth = myBufferSizeEdit->text().toInt();
-      break;
-    case UNDO_DEPTH_UNLIMITED:
-    case UNDO_DEPTH_DISABLED:
-      myUndoDepth = anId - 1;
-      break;
-    default:
-      break;
-  }
-
-  QDialog::accept();
-}
diff --git a/src/CurveCreator/CurveCreator_UndoOptsDlg.h b/src/CurveCreator/CurveCreator_UndoOptsDlg.h
deleted file mode 100644 (file)
index 86aa87a..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-// File:        CurveCreator_UndoOptsDlg.h
-// Author:      Sergey KHROMOV
-
-#ifndef _CurveCreator_UndoOptsDlg_HeaderFile
-#define _CurveCreator_UndoOptsDlg_HeaderFile
-
-#include <QDialog>
-
-class QButtonGroup;
-class QLineEdit;
-class QPushButton;
-
-
-class CurveCreator_UndoOptsDlg : public QDialog
-{
-  Q_OBJECT
-
-public:
-
-  CurveCreator_UndoOptsDlg(QWidget* parent);
-
-  ~CurveCreator_UndoOptsDlg();
-
-  void setUndoDepth(const int theDepth);
-
-  int getUndoDepth() const;
-
-  bool isEnabled() const;
-
-  bool isUnlimited() const;
-
-private:
-
-  void init();
-
-  void setTabOrder();
-
-private slots:
-
-  void optionChanged(int theId);
-
-  void accept();
-
-protected:
-
-  int           myUndoDepth;
-  QButtonGroup *myOptsBtnGrp;
-  QLineEdit    *myBufferSizeEdit;
-  QPushButton  *myOkBtn;
-  QPushButton  *myCancelBtn;
-
-};
-
-#endif
diff --git a/src/CurveCreator/CurveCreator_Utils.cxx b/src/CurveCreator/CurveCreator_Utils.cxx
new file mode 100644 (file)
index 0000000..146676c
--- /dev/null
@@ -0,0 +1,994 @@
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "CurveCreator_Utils.hxx"
+#include "CurveCreator.hxx"
+#include "CurveCreator_Curve.hxx"
+#include "CurveCreator_UtilsICurve.hxx"
+
+#include <GEOMUtils.hxx>
+
+#include <gp_Pln.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Compound.hxx>
+
+#include <AIS_ListOfInteractive.hxx>
+#include <AIS_ListIteratorOfListOfInteractive.hxx>
+#include <AIS_Shape.hxx>
+#include <AIS_Line.hxx>
+#include <AIS_Trihedron.hxx>
+#include <AIS_LocalContext.hxx>
+
+#include <Geom_Point.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_TrimmedCurve.hxx>
+
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <Select3D_SensitivePoint.hxx>
+
+#include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepTools_WireExplorer.hxx>
+
+#include <TColgp_HArray1OfPnt.hxx>
+#include <TColStd_HArray1OfBoolean.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColgp_Array1OfVec.hxx>
+#include <GeomAPI_Interpolate.hxx>
+
+#include <ProjLib.hxx>
+#include <ElSLib.hxx>
+
+#include <math.h>
+
+#include "CurveCreator_ICurve.hxx"
+
+const double LOCAL_SELECTION_TOLERANCE = 0.0001;
+const int    SCENE_PIXEL_PROJECTION_TOLERANCE = 10;
+const int    SCENE_PIXEL_POINT_TOLERANCE = 5;
+
+#define PLN_FREE   0
+#define PLN_ORIGIN 1
+#define PLN_OX     2
+#define PLN_FIXED  3
+
+/**
+ * This static function returns the curve of original type from the edge.
+ *
+ * \param theEdge the edge
+ * \return the curve of original type. Can be null handle.
+ */
+static Handle(Geom_Curve) GetCurve(const TopoDS_Edge &theEdge)
+{
+  Handle(Geom_Curve) aResult;
+
+  if (theEdge.IsNull()) {
+    return aResult;
+  }
+
+  Standard_Real aF;
+  Standard_Real aL;
+
+  aResult = BRep_Tool::Curve(theEdge, aF, aL);
+
+  if (aResult.IsNull()) {
+    return aResult;
+  }
+
+  // Get the curve of original type
+  Handle(Standard_Type) aType = aResult->DynamicType();
+
+  while (aType == STANDARD_TYPE(Geom_TrimmedCurve)) {
+    Handle(Geom_TrimmedCurve) aTrCurve =
+      Handle(Geom_TrimmedCurve)::DownCast(aResult);
+
+    aResult = aTrCurve->BasisCurve();
+    aType  = aResult->DynamicType();
+  }
+
+  return aResult;
+}
+
+//=======================================================================
+// function : ConvertClickToPoint()
+// purpose  : Returns the point clicked in 3D view
+//=======================================================================
+void CurveCreator_Utils::ConvertPointToClick( const gp_Pnt& thePoint,
+                                              Handle(V3d_View) theView,
+                                              int& x, int& y )
+{
+  theView->Convert(thePoint.X(), thePoint.Y(), thePoint.Z(), x, y );
+}
+
+
+//=======================================================================
+// function : ConvertClickToPoint()
+// purpose  : Returns the point clicked in 3D view
+//=======================================================================
+gp_Pnt CurveCreator_Utils::ConvertClickToPoint( int x, int y, Handle(V3d_View) aView )
+{
+  // the 3D point, that is a projection of the pixels to the XYZ view plane
+  //return GEOMUtils::ConvertClickToPoint( x, y, aView );
+
+  // we need the projection to the XOY plane
+  // 1. find a point in the plane of the eye and the normal to the plane
+  Standard_Real X, Y, Z;
+  Quantity_Parameter Vx, Vy, Vz;
+  aView->ConvertWithProj( x, y, X, Y, Z, Vx, Vy, Vz );
+
+  // 2. build a ray from the point by the normal to the XOY plane and intersect it
+  // The ray equation is the following : p(x,y,z) = p0(x,y,z) + t*V(x,y,z)
+  // X,Y,Z - defines p0(x,y,z), Vx,Vy,Vz - defines V(x,y,z)
+  // p(x,y,z) - is a searched point, t - should to be calculated by the condition of XOY plane
+  // The system of equations is the following:
+  // p(x) = p0(x)+t*V(x)
+  // p(y) = p0(y)+t*V(y)
+  // p(z) = p0(z)+t*V(z)
+  // p(z) = 0
+
+  Standard_Real aXp, aYp, aZp;
+  //It is not possible to use Precision::Confusion(), because it is e-0.8, but V is sometimes e-6
+  Standard_Real aPrec = LOCAL_SELECTION_TOLERANCE;
+  if ( fabs( Vz ) > aPrec ) {
+    Standard_Real aT = -Z/Vz;
+    aXp = X + aT*Vx;
+    aYp = Y + aT*Vy;
+    aZp = Z + aT*Vz;
+  }
+  else { // Vz = 0 - the eyed plane is orthogonal to Z plane - XOZ, or YOZ
+    aXp = aYp = aZp = 0;
+    if ( fabs( Vy ) < aPrec ) // Vy = 0 - the YOZ plane
+      aYp = Y;
+    else if ( fabs( Vx ) < aPrec ) // Vx = 0 - the XOZ plane
+      aXp = X;
+  }
+  /*std::cout << "ConvertClickToPoint: " << std::endl
+            << "XYZ1 = (" << X << ", " << Y << ", " << Z << "); " << std::endl
+            << "Vxyz = (" << Vx << ", " << Vy << ", " << Vz << "); " << std::endl
+            << "Resp = (" << aXp << ", " << aYp << ", " << aZp << "); " << std::endl;*/
+
+  gp_Pnt ResultPoint( aXp, aYp, aZp );
+  return ResultPoint;
+}
+
+void CurveCreator_Utils::constructShape( const CurveCreator_ICurve* theCurve,
+                                         TopoDS_Shape& theShape )
+{
+  BRep_Builder aBuilder;
+  TopoDS_Compound aComp;
+  aBuilder.MakeCompound( aComp );
+  for( int iSection = 0 ; iSection < theCurve->getNbSections() ; iSection++ )
+  {
+    int theISection = iSection;
+
+    CurveCreator::SectionType aSectType = theCurve->getSectionType( theISection );
+    int aPointSize = theCurve->getNbPoints( theISection );
+    if ( aPointSize == 0 )
+      continue;
+
+    bool aSectIsClosed = theCurve->isClosed( theISection );
+    bool isPolyline = aSectType == CurveCreator::Polyline;
+
+    int iPoint = 0;
+    gp_Pnt aPrevPoint, aPoint;
+    // filters the curve points to skip equal points
+    std::vector<gp_Pnt> aPoints;
+    CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPoint );
+    aPoints.push_back( aPoint );
+    aPrevPoint = aPoint;
+    iPoint++;
+    for( ; iPoint < aPointSize; iPoint++ ) {
+      CurveCreator_UtilsICurve::getPoint( theCurve, theISection, iPoint, aPoint );
+      if ( !isEqualPoints( aPrevPoint, aPoint ) )
+        aPoints.push_back( aPoint );
+      aPrevPoint = aPoint;
+    }
+    int aNbPoints = aPoints.size();
+
+    if ( aNbPoints == 1 ) {
+      aPoint = aPoints.front();
+      TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex();
+      aBuilder.Add( aComp, aVertex );
+    }
+    else if ( aNbPoints > 1 ) {
+      Handle(TColgp_HArray1OfPnt) aHCurvePoints = new TColgp_HArray1OfPnt(1, aNbPoints);
+      TColgp_Array1OfVec aTangents(1, aNbPoints);
+      Handle(TColStd_HArray1OfBoolean) aTangentFlags = new TColStd_HArray1OfBoolean(1, aNbPoints);
+      gp_Vec aNullVec(0, 0, 0);
+
+      TopoDS_Edge aPointEdge;
+      TopoDS_Vertex aVertex;
+
+      std::vector<gp_Pnt>::const_iterator aPointIt = aPoints.begin(), aPointLast = aPoints.end();
+      aPoint = *aPointIt;
+
+      int aHIndex = 1;
+      aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex();
+      aBuilder.Add( aComp, aVertex );
+      if ( !isPolyline ) {
+        aHCurvePoints->SetValue( aHIndex, aPoint );
+        aTangents.SetValue( aHIndex, aNullVec );
+        aTangentFlags->SetValue( aHIndex, Standard_False );
+        aHIndex++;
+      }
+
+      aPrevPoint = aPoint;
+      aPointIt++;
+      for( ; aPointIt != aPointLast; aPointIt++ ) {
+        aPoint = *aPointIt;
+        aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex();
+        aBuilder.Add( aComp, aVertex );
+        if ( isPolyline ) {
+          TopoDS_Edge aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge();
+          aBuilder.Add( aComp, aPointEdge );
+        }
+        else {
+          aHCurvePoints->SetValue( aHIndex, aPoint );
+          aTangents.SetValue( aHIndex, aNullVec );
+          aTangentFlags->SetValue( aHIndex, Standard_False );
+          aHIndex++;
+        }
+        aPrevPoint = aPoint;
+      }
+      if( aSectIsClosed && ( aNbPoints > 2 ) ) {
+        aPoint = aPoints.front();
+        aVertex = BRepBuilderAPI_MakeVertex( aPoint ).Vertex();
+        aBuilder.Add( aComp, aVertex );
+        if ( isPolyline ) {
+          aPointEdge = BRepBuilderAPI_MakeEdge( aPrevPoint, aPoint ).Edge();
+          aBuilder.Add( aComp, aPointEdge );
+        }
+      }
+      if( !isPolyline ) {
+        // compute BSpline
+        Handle(Geom_BSplineCurve) aBSplineCurve;
+        GeomAPI_Interpolate aGBC(aHCurvePoints, aSectIsClosed, gp::Resolution());
+        // correct the spline degree to be as 3 for non-periodic spline if number of points
+        // less than 3. It is need to have a knot in each spline point. This knots are used
+        // to found a neighbour points when a new point is inserted between two existing.
+        if (!aSectIsClosed ) {
+          if (aHCurvePoints->Length() == 3)
+            aGBC.Load(aTangents, aTangentFlags);
+        }
+
+        aGBC.Perform();
+        if ( aGBC.IsDone() )
+          aBSplineCurve = aGBC.Curve();
+        TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge( aBSplineCurve ).Edge();
+        TopoDS_Wire aWire = BRepBuilderAPI_MakeWire( anEdge ).Wire();
+        aBuilder.Add( aComp, aWire );
+      }
+    }
+  }
+  theShape = aComp;
+}
+
+/**
+ * This is an intermediate structure for curve construction.
+ */
+struct Section3D
+{
+  Section3D() : myIsClosed(false), myIsBSpline(false)
+  { }
+
+  bool                        myIsClosed;
+  bool                        myIsBSpline;
+  Handle(TColgp_HArray1OfPnt) myPoints;
+};
+
+//=======================================================================
+// function : constructCurve
+// purpose  : 
+//=======================================================================
+bool CurveCreator_Utils::constructCurve
+                      (const TopoDS_Shape        theShape,
+                             CurveCreator_Curve *theCurve,
+                             gp_Ax3             &theLocalCS)
+{
+  if (theShape.IsNull()) {
+    return false;
+  }
+
+  // Collect wires or vertices from shape.
+  TopTools_ListOfShape aWOrV;
+  TopAbs_ShapeEnum     aType = theShape.ShapeType();
+
+  if (aType == TopAbs_WIRE || aType == TopAbs_VERTEX) {
+    aWOrV.Append(theShape);
+  } else if (aType == TopAbs_COMPOUND) {
+    TopoDS_Iterator aShIter(theShape);
+
+    for (; aShIter.More(); aShIter.Next()) {
+      const TopoDS_Shape &aSubShape = aShIter.Value();
+
+      aType = aSubShape.ShapeType();
+
+      if (aType == TopAbs_WIRE || aType == TopAbs_VERTEX) {
+        aWOrV.Append(aSubShape);
+      } else {
+        // Only subshapes of types wire or vertex are supported.
+        return false;
+      }
+    }
+  } else {
+    // Only wire (vertex) or compound of wires (vertices) are supported.
+    return false;
+  }
+
+  // Treat each wire or vertex. Get points, compute the working plane.
+  gp_Pln                             aPlane;
+  Standard_Integer                   aPlaneStatus = PLN_FREE;
+  TopTools_ListIteratorOfListOfShape anIter(aWOrV);
+  std::list<Section3D>               aListSec;
+
+  for (; anIter.More(); anIter.Next()) {
+    Section3D aSec3D;
+
+    aSec3D.myPoints = CurveCreator_Utils::getPoints
+      (anIter.Value(), aSec3D.myIsClosed, aSec3D.myIsBSpline);
+
+    if (aSec3D.myPoints.IsNull()) {
+      return false;
+    }
+
+    aListSec.push_back(aSec3D);
+
+    if (aPlaneStatus != PLN_FIXED) {
+      // Compute plane
+      CurveCreator_Utils::FindPlane(aSec3D.myPoints, aPlane, aPlaneStatus);
+    }
+  }
+
+  // Check if it is possible to change a computed coordinate system by
+  // XOY, XOZ or YOZ or parallel to them.
+  gp_Pnt        aO(0., 0., 0.);
+  gp_Dir        aNDir(0., 0., 1.);
+  gp_Dir        aXDir(1., 0., 0.);
+  gp_Ax3        anAxis;
+  Standard_Real aTolAng = Precision::Confusion(); // Angular() is too small.
+
+  switch (aPlaneStatus) {
+    case PLN_ORIGIN:
+      {
+        // Change the location.
+        aO.SetZ(aPlane.Location().Z());
+        anAxis.SetLocation(aO);
+        aPlane.SetPosition(anAxis);
+      }
+      break;
+    case PLN_OX:
+      {
+        // Fixed origin + OX axis
+        const gp_Dir &aPlnX = aPlane.Position().XDirection();
+
+        if (Abs(aPlnX.Z()) <= aTolAng) {
+          // Make a coordinate system parallel to XOY.
+          aO.SetZ(aPlane.Location().Z());
+          anAxis.SetLocation(aO);
+          aPlane.SetPosition(anAxis);
+        } else if (Abs(aPlnX.Y()) <= aTolAng) {
+          // Make a coordinate system parallel to XOZ.
+          aO.SetY(aPlane.Location().Y());
+          aNDir.SetCoord(0., 1., 0.);
+          aXDir.SetCoord(0., 0., 1.);
+          anAxis = gp_Ax3(aO, aNDir, aXDir);
+          aPlane.SetPosition(anAxis);
+        } else if (Abs(aPlnX.X()) <= aTolAng) {
+          // Make a coordinate system parallel to YOZ.
+          aO.SetX(aPlane.Location().X());
+          aNDir.SetCoord(1., 0., 0.);
+          aXDir.SetCoord(0., 1., 0.);
+          anAxis = gp_Ax3(aO, aNDir, aXDir);
+          aPlane.SetPosition(anAxis);
+        }
+      }
+      break;
+    case PLN_FIXED:
+      {
+        const gp_Dir &aPlnN = aPlane.Position().Direction();
+        gp_Dir        aYDir(0., 1., 0.);
+
+        if (aPlnN.IsParallel(aNDir, aTolAng)) {
+          // Make a coordinate system parallel to XOY.
+          aO.SetZ(aPlane.Location().Z());
+          anAxis.SetLocation(aO);
+          aPlane.SetPosition(anAxis);
+        } else if (aPlnN.IsParallel(aYDir, aTolAng)) {
+          // Make a coordinate system parallel to XOZ.
+          aO.SetY(aPlane.Location().Y());
+          aNDir.SetCoord(0., 1., 0.);
+          aXDir.SetCoord(0., 0., 1.);
+          anAxis = gp_Ax3(aO, aNDir, aXDir);
+          aPlane.SetPosition(anAxis);
+        } else if (aPlnN.IsParallel(aXDir, aTolAng)) {
+          // Make a coordinate system parallel to YOZ.
+          aO.SetX(aPlane.Location().X());
+          aNDir.SetCoord(1., 0., 0.);
+          aXDir.SetCoord(0., 1., 0.);
+          anAxis = gp_Ax3(aO, aNDir, aXDir);
+          aPlane.SetPosition(anAxis);
+        }
+      }
+      break;
+    case PLN_FREE:
+    default:
+      // Use XOY plane.
+      aPlane.SetPosition(anAxis);
+      break;
+  }
+
+  // Compute 2d points.
+  std::list<Section3D>::const_iterator aSecIt = aListSec.begin();
+  Standard_Real                        aTolConf2 =
+    Precision::Confusion()*Precision::Confusion();
+  Standard_Real                        aX;
+  Standard_Real                        aY;
+
+  for (; aSecIt != aListSec.end(); ++aSecIt) {
+    Standard_Integer          i;
+    CurveCreator::Coordinates aCoords;
+
+    for (i = aSecIt->myPoints->Lower(); i <= aSecIt->myPoints->Upper(); ++i) {
+      const gp_Pnt &aPnt = aSecIt->myPoints->Value(i);
+
+      if (aPlane.SquareDistance(aPnt) > aTolConf2) {
+        // The point doesn't lie on the plane.
+        return false;
+      }
+
+      ElSLib::Parameters(aPlane, aPnt, aX, aY);
+      aCoords.push_back(aX);
+      aCoords.push_back(aY);
+    }
+
+    // Add a new section to the curve.
+    const std::string               aSecName =
+      CurveCreator_UtilsICurve::getUniqSectionName(theCurve);
+    const CurveCreator::SectionType aSecType = aSecIt->myIsBSpline ?
+      CurveCreator::Spline : CurveCreator::Polyline;
+
+    theCurve->addSectionInternal(aSecName, aSecType,
+                                 aSecIt->myIsClosed, aCoords);
+  }
+
+  // Set the local coordinate system.
+  theLocalCS = aPlane.Position();
+
+  return true;
+}
+
+class CompareSectionToPoint
+{
+public:
+  CompareSectionToPoint( const int theISection = -1, const int theIPoint = -1 )
+    : mySectionId( theISection ), myPointId( theIPoint ) {};
+  ~CompareSectionToPoint() {}
+
+  bool operator < ( const CompareSectionToPoint& theOther ) const
+  {
+    bool isLess = mySectionId < theOther.mySectionId;
+    if ( !isLess && mySectionId == theOther.mySectionId )
+      isLess = myPointId < theOther.myPointId;
+    return isLess;
+  }
+
+private:
+  int mySectionId;
+  int myPointId;
+};
+
+
+void CurveCreator_Utils::getSelectedPoints( Handle(AIS_InteractiveContext) theContext,
+                                            const CurveCreator_ICurve* theCurve,
+                                            CurveCreator_ICurve::SectionToPointList& thePoints )
+{
+  thePoints.clear();
+
+  std::list<float> aSelectedPoints;
+  gp_Pnt aPnt;
+  std::map<CompareSectionToPoint, int> aPointsMap;
+
+  CurveCreator_ICurve::SectionToPointList aPoints;
+  for ( theContext->InitSelected(); theContext->MoreSelected(); theContext->NextSelected() ) {
+    TopoDS_Vertex aVertex;
+    TopoDS_Shape aShape = theContext->SelectedShape();
+    if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
+      aVertex = TopoDS::Vertex( theContext->SelectedShape() );
+
+    if ( aVertex.IsNull() )
+      continue;
+    aPnt = BRep_Tool::Pnt( aVertex );
+
+    CurveCreator_UtilsICurve::findSectionsToPoints( theCurve, aPnt.X(), aPnt.Y(), aPoints );
+    CurveCreator_ICurve::SectionToPointList::const_iterator anIt = aPoints.begin(),
+                                                            aLast = aPoints.end();
+    CompareSectionToPoint aPoint;
+    for ( ; anIt != aLast; anIt++ ) {
+      aPoint = CompareSectionToPoint( (*anIt).first, (*anIt).second );
+      if ( aPointsMap.find( aPoint ) != aPointsMap.end() )
+        continue;
+      aPointsMap[aPoint] = 0;
+
+      thePoints.push_back( *anIt );
+    }
+  }
+}
+
+void CurveCreator_Utils::setSelectedPoints( Handle(AIS_InteractiveContext) theContext,
+                                            const CurveCreator_ICurve* theCurve,
+                                            const CurveCreator_ICurve::SectionToPointList& thePoints )
+{
+  if ( !theCurve )
+    return;
+
+  Handle(AIS_InteractiveObject) anAIS = theCurve->getAISObject();
+  if ( anAIS.IsNull() )
+    return;
+  Handle(AIS_Shape) anAISShape = Handle(AIS_Shape)::DownCast( anAIS );
+  if ( anAISShape.IsNull() )
+    return;
+
+  //ASL: we convert list of point indices to list of points coordinates
+  int aSize = thePoints.size();
+  std::vector<gp_Pnt> aPntsToSelect( aSize );
+
+  CurveCreator_ICurve::SectionToPointList::const_iterator
+                     aPIt = thePoints.begin(), aPLast = thePoints.end();
+  CurveCreator_ICurve::SectionToPoint aSToPoint;
+  for( int i=0; aPIt != aPLast; aPIt++, i++ )
+  {
+    gp_Pnt aPntToSelect;
+    CurveCreator_UtilsICurve::getPoint( theCurve, aPIt->first, aPIt->second, aPntToSelect );
+    aPntsToSelect[i] = aPntToSelect;
+  }
+
+  theContext->ClearSelected( Standard_False );
+  //ASL: we switch off automatic highlight to improve performance of selection
+  theContext->SetAutomaticHilight( Standard_False );
+
+  Handle_SelectMgr_Selection aSelection = anAISShape->Selection( AIS_Shape::SelectionMode( TopAbs_VERTEX ) );
+  for( aSelection->Init(); aSelection->More(); aSelection->Next() )
+  {
+    Handle_SelectBasics_SensitiveEntity aSenEntity = aSelection->Sensitive();
+    Handle_Select3D_SensitivePoint aSenPnt = Handle_Select3D_SensitivePoint::DownCast( aSenEntity );
+
+    gp_Pnt anOwnerPnt = aSenPnt->Point();
+    Handle_SelectMgr_EntityOwner anOwner = Handle_SelectMgr_EntityOwner::DownCast( aSenPnt->OwnerId() );
+
+
+    CurveCreator_ICurve::SectionToPointList::const_iterator anIt = thePoints.begin(),
+                                                                   aLast = thePoints.end();
+    bool isFound = false;
+    for( int i=0; i<aSize; i++ )
+    {
+      bool isIntersect = fabs( aPntsToSelect[i].X() - anOwnerPnt.X() ) < LOCAL_SELECTION_TOLERANCE &&
+                         fabs( aPntsToSelect[i].Y() - anOwnerPnt.Y() ) < LOCAL_SELECTION_TOLERANCE;
+      if( isIntersect )
+      {
+        theContext->AddOrRemoveSelected( anOwner, Standard_False );
+        break;
+      }
+    }
+  }
+
+  //ASL: we switch on again automatic highlight (otherwise selection will not be shown)
+  //     and call HilightPicked to draw selected owners
+  theContext->SetAutomaticHilight( Standard_True );
+  theContext->LocalContext()->HilightPicked( Standard_True );
+}
+
+//=======================================================================
+// function : setLocalPointContext
+// purpose  : Open/close the viewer local context
+//=======================================================================
+void CurveCreator_Utils::setLocalPointContext( const CurveCreator_ICurve* theCurve,
+                                               Handle(AIS_InteractiveContext) theContext,
+                                               const bool theOpen )
+{
+  if ( !theContext )
+    return;
+
+  if ( theOpen ) {
+    // Open local context if there is no one
+    if ( !theContext->HasOpenedContext() ) {
+      theContext->ClearCurrents( false );
+      theContext->OpenLocalContext( false/*use displayed objects*/, true/*allow shape decomposition*/ );
+    }
+    // load the curve AIS object to the local context with the point selection
+    Handle(AIS_InteractiveObject) anAIS = theCurve->getAISObject();
+    if ( !anAIS.IsNull() )
+    {
+      if ( anAIS->IsKind( STANDARD_TYPE( AIS_Shape ) ) )
+      {
+        theContext->Load( anAIS, -1/*selection mode*/, true/*allow decomposition*/ );
+        theContext->Activate( anAIS, AIS_Shape::SelectionMode( (TopAbs_ShapeEnum)TopAbs_VERTEX ) );
+      }
+    }
+  }
+  else {
+    if ( theContext->HasOpenedContext() )
+      theContext->CloseAllContexts();
+  }
+}
+
+bool CurveCreator_Utils::pointOnObject( Handle(V3d_View) theView,
+                                        Handle(AIS_InteractiveObject) theObject,
+                                        const int theX, const int theY,
+                                        gp_Pnt& thePoint,
+                                        gp_Pnt& thePoint1, gp_Pnt& thePoint2 )
+{
+  bool isFullFound = false;
+
+  if ( theObject.IsNull() || theView.IsNull() )
+    return isFullFound;
+  Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast( theObject );
+  if ( aShape.IsNull() )
+    return isFullFound;
+  const TopoDS_Compound& aCompound = TopoDS::Compound( aShape->Shape() );
+  if ( aCompound.IsNull() )
+    return isFullFound;
+
+  gp_Pnt aCurPoint, aCurPoint1, aCurPoint2;
+  gp_Pnt aFoundPoint, aFoundPnt1, aFoundPnt2;
+  Standard_Real aParameter;
+  bool isFound = false;
+  int aDelta, aMinDelta = 2*SCENE_PIXEL_PROJECTION_TOLERANCE*SCENE_PIXEL_PROJECTION_TOLERANCE;
+  TopExp_Explorer anExp( aCompound, TopAbs_EDGE );
+  for ( ; anExp.More(); anExp.Next())
+  {
+    const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
+    if ( anEdge.IsNull() )
+      continue;
+    Standard_Real aFirst, aLast;
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve( anEdge, aFirst, aLast );
+    if ( aCurve->IsKind( STANDARD_TYPE(Geom_BSplineCurve) ) ) {
+      Handle(Geom_BSplineCurve) aBSplineCurve =
+                          Handle(Geom_BSplineCurve)::DownCast( aCurve );
+      if ( !aBSplineCurve.IsNull() ) {
+        isFound = hasProjectPointOnCurve( theView, theX, theY, aBSplineCurve,
+                                          aParameter, aDelta );
+        if ( isFound ) {
+          aCurPoint = aBSplineCurve->Value( aParameter );
+          Standard_Integer anI1, anI2;
+          aBSplineCurve->LocateU( aParameter, LOCAL_SELECTION_TOLERANCE, anI1, anI2 );
+          aCurPoint1 = aBSplineCurve->Value( aBSplineCurve->Knot( anI1 ) );
+          aCurPoint2 = aBSplineCurve->Value( aBSplineCurve->Knot( anI2 ) );
+        }
+      }
+    }
+    else { // a curve built on a polyline edge
+      Handle(Geom_Line) aGLine = Handle(Geom_Line)::DownCast( aCurve );
+      if ( aGLine.IsNull() )
+        continue;
+      isFound = hasProjectPointOnCurve( theView, theX, theY, aGLine, aParameter,
+                                        aDelta );
+      if ( isFound ) {
+        aCurPoint = aGLine->Value( aParameter );
+        TopoDS_Vertex V1, V2;
+        TopExp::Vertices( anEdge, V1, V2, Standard_True );
+        if ( V1.IsNull() || V2.IsNull() )
+          continue;
+        aCurPoint1 = BRep_Tool::Pnt(V1);
+        aCurPoint2 = BRep_Tool::Pnt(V2);
+
+        // check that the projected point is on the bounded curve
+        gp_Vec aVec1( aCurPoint1, aCurPoint );
+        gp_Vec aVec2( aCurPoint2, aCurPoint );
+        isFound = fabs( aVec1.Angle( aVec2 ) - M_PI ) < LOCAL_SELECTION_TOLERANCE;
+      }
+    }
+    if ( isFound && aMinDelta >= aDelta ) {
+      aMinDelta = aDelta;
+
+      isFullFound = true;
+      aFoundPnt1 = aCurPoint1;
+      aFoundPnt2 = aCurPoint2;
+      aFoundPoint = aCurPoint;
+    }
+  }
+  if ( isFullFound ) {
+    int aX, anY, aX1, anY1, aX2, anY2;
+    int aDelta;
+    CurveCreator_Utils::ConvertPointToClick( aFoundPoint, theView, aX, anY );
+    CurveCreator_Utils::ConvertPointToClick( aFoundPnt1, theView, aX1, anY1 );
+    CurveCreator_Utils::ConvertPointToClick( aFoundPnt2, theView, aX2, anY2 );
+
+    isFullFound = !isEqualPixels( aX, anY, aX1, anY1, SCENE_PIXEL_POINT_TOLERANCE, aDelta ) &&
+                  !isEqualPixels( aX, anY, aX2, anY2, SCENE_PIXEL_POINT_TOLERANCE, aDelta );
+    if ( isFullFound ) {
+      thePoint = aFoundPoint;
+      thePoint1 = aFoundPnt1;
+      thePoint2 = aFoundPnt2;
+    }
+  }
+  return isFullFound;
+}
+
+bool CurveCreator_Utils::hasProjectPointOnCurve( Handle(V3d_View) theView,
+                                                 const int theX, const int theY,
+                                                 const Handle(Geom_Curve)& theCurve,
+                                                 Standard_Real& theParameter,
+                                                 int& theDelta )
+{
+  bool isFound = false;
+  if ( theView.IsNull() )
+    return isFound;
+
+  gp_Pnt aPoint = CurveCreator_Utils::ConvertClickToPoint( theX, theY, theView );
+
+  GeomAPI_ProjectPointOnCurve aProj( aPoint, theCurve );
+  Standard_Integer aNbPoint = aProj.NbPoints();
+  if (aNbPoint > 0) {
+    for (Standard_Integer j = 1; j <= aNbPoint && !isFound; j++) {
+      gp_Pnt aNewPoint = aProj.Point( j );
+      theParameter = aProj.Parameter( j );
+
+      int aX, anY;
+      CurveCreator_Utils::ConvertPointToClick( aNewPoint, theView, aX, anY );
+
+      isFound = isEqualPixels( aX, anY, theX, theY, SCENE_PIXEL_PROJECTION_TOLERANCE, theDelta );
+    }
+  }
+  return isFound;
+}
+
+bool CurveCreator_Utils::isEqualPixels( const int theX, const int theY, const int theOtherX,
+                                        const int theOtherY, const double theTolerance, int& theDelta )
+{
+  int aXDelta = abs( theX - theOtherX );
+  int anYDelta = abs( theY - theOtherY );
+
+  theDelta = aXDelta*aXDelta + anYDelta*anYDelta;
+
+  return aXDelta < theTolerance && anYDelta < theTolerance;
+}
+
+bool CurveCreator_Utils::isEqualPoints( const gp_Pnt& thePoint, const gp_Pnt& theOtherPoint )
+{
+  return theOtherPoint.IsEqual( thePoint, LOCAL_SELECTION_TOLERANCE );
+}
+
+//=======================================================================
+// function : getPoints
+// purpose  : 
+//=======================================================================
+Handle(TColgp_HArray1OfPnt) CurveCreator_Utils::getPoints
+                  (const TopoDS_Shape &theShape,
+                         bool         &IsClosed,
+                         bool         &IsBSpline)
+{
+  Handle(TColgp_HArray1OfPnt) aResult;
+
+  IsClosed  = false;
+  IsBSpline = false;
+
+  if (theShape.IsNull()) {
+    return aResult;
+  }
+
+  const TopAbs_ShapeEnum aShType = theShape.ShapeType();
+
+  if (aShType == TopAbs_VERTEX) {
+    // There is a single point.
+    gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape));
+
+    aResult = new TColgp_HArray1OfPnt(1, 1, aPnt);
+
+    return aResult;
+  } else if (aShType != TopAbs_WIRE) {
+    // The shape is neither a vertex nor a wire.
+    return aResult;
+  }
+
+  // Treat wire.
+  BRepTools_WireExplorer anExp(TopoDS::Wire(theShape));
+
+  if (!anExp.More()) {
+    // Empty wires are not allowed.
+    return aResult;
+  }
+
+  // Treat the first edge.
+  TopoDS_Edge        anEdge = anExp.Current();
+  Handle(Geom_Curve) aCurve = GetCurve(anEdge);
+
+  if (aCurve.IsNull()) {
+    return aResult;
+  }
+
+  // Check the curve type.
+  Handle(Standard_Type) aType     = aCurve->DynamicType();
+
+  if (aType == STANDARD_TYPE(Geom_BSplineCurve)) {
+    IsBSpline = true;
+  } else if (aType != STANDARD_TYPE(Geom_Line)) {
+    // The curve is neither a line or a BSpline. It is not valid.
+    return aResult;
+  }
+
+  // Go to the next edge.
+  TopoDS_Vertex aFirstVtx = anExp.CurrentVertex();
+
+  anExp.Next();
+
+  if (IsBSpline) {
+    // There should be a single BSpline curve in the wire.
+    if (anExp.More()) {
+      return aResult;
+    }
+
+    // Construct a section from poles of BSpline.
+    Handle(Geom_BSplineCurve) aBSplCurve =
+      Handle(Geom_BSplineCurve)::DownCast(aCurve);
+
+    // Check if the edge is valid. It should not be based on trimmed curve.
+    gp_Pnt aCP[2] = { aBSplCurve->StartPoint(), aBSplCurve->EndPoint() };
+    TopoDS_Vertex aV[2];
+    Standard_Integer i;
+
+    TopExp::Vertices(anEdge, aV[0], aV[1]);
+
+    for (i = 0; i < 2; i++) {
+      gp_Pnt        aPnt = BRep_Tool::Pnt(aV[i]);
+      Standard_Real aTol = BRep_Tool::Tolerance(aV[i]);
+
+      if (!aPnt.IsEqual(aCP[i], aTol)) {
+        return aResult;
+      }
+    }
+
+    IsClosed = aV[0].IsSame(aV[1]) ? true : false;
+    
+    const Standard_Integer aNbPoints = aBSplCurve->NbKnots();
+    TColStd_Array1OfReal   aKnots(1, aNbPoints);
+
+    aBSplCurve->Knots(aKnots);
+    aResult = new TColgp_HArray1OfPnt(1, aBSplCurve->NbKnots());
+
+    for (i = aKnots.Lower(); i <= aKnots.Upper(); ++i) {
+      aResult->SetValue(i, aBSplCurve->Value(aKnots.Value(i)));
+    }
+  } else {
+    // This is a polyline.
+    TopTools_ListOfShape aVertices;
+    Standard_Integer     aNbVtx = 1;
+
+
+    aVertices.Append(aFirstVtx);
+
+    for (; anExp.More(); anExp.Next(), ++aNbVtx) {
+      anEdge = anExp.Current();
+      aCurve = GetCurve(anEdge);
+
+      if (aCurve.IsNull()) {
+        return aResult;
+      }
+
+      aType = aCurve->DynamicType();
+
+      if (aType != STANDARD_TYPE(Geom_Line)) {
+        // The curve is not a line. It is not valid.
+        return aResult;
+      }
+
+      // Add the current vertex to the list.
+      aVertices.Append(anExp.CurrentVertex());
+    }
+
+    // Check if the section is closed.
+    TopoDS_Vertex aLastVtx = TopExp::LastVertex(anEdge, Standard_True);
+
+    IsClosed = aFirstVtx.IsSame(aLastVtx) ? true : false;
+
+    // Fill the array of points.
+    aResult = new TColgp_HArray1OfPnt(1, aNbVtx);
+
+    Standard_Integer i;
+    TopTools_ListIteratorOfListOfShape aVtxIter(aVertices);
+
+    for (i = 1; aVtxIter.More(); aVtxIter.Next(), ++i) {
+      gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVtxIter.Value()));
+
+      aResult->SetValue(i, aPnt);
+    }
+  }
+
+  return aResult;
+}
+//=======================================================================
+// function : FindPlane
+// purpose  : 
+//=======================================================================
+void CurveCreator_Utils::FindPlane
+                       (const Handle_TColgp_HArray1OfPnt &thePoints,
+                              gp_Pln                     &thePlane,
+                              Standard_Integer           &thePlnStatus)
+{
+  if (thePoints.IsNull() || thePlnStatus == PLN_FIXED) {
+    // The plane can't be defined or is fixed. Nothing to change.
+    return;
+  }
+
+  Standard_Integer    i;
+  const Standard_Real aTolConf = Precision::Confusion();
+
+  for (i = thePoints->Lower(); i <= thePoints->Upper(); ++i) {
+    const gp_Pnt &aPnt = thePoints->Value(i);
+
+    switch (thePlnStatus) {
+      case PLN_FREE:
+        // Fix the origin.
+        thePlane.SetLocation(aPnt);
+        thePlnStatus = PLN_ORIGIN;
+        break;
+      case PLN_ORIGIN:
+        {
+          // Fix origin + OX axis
+          const gp_Pnt &aPlnLoc = thePlane.Location();
+
+          if (!aPnt.IsEqual(aPlnLoc, aTolConf)) {
+            // Set the X axis.
+            gp_Dir aXDir(aPnt.XYZ().Subtracted(aPlnLoc.XYZ()));
+            gp_Ax3 aXNorm(aPlnLoc, aXDir);
+            gp_Ax3 aNewPlnPos(aPlnLoc, aXNorm.XDirection(), aXNorm.Direction());
+
+            thePlane.SetPosition(aNewPlnPos);
+            thePlnStatus = PLN_OX;
+          }
+        }
+        break;
+      case PLN_OX:
+        {
+          // Fix OY axis
+          gp_Lin aXLin(thePlane.XAxis());
+          Standard_Real aSqrDist = aXLin.SquareDistance(aPnt);
+
+          if (aSqrDist > aTolConf*aTolConf) {
+            // Compute main axis.
+            const gp_Pnt &aPlnLoc = thePlane.Location();
+            gp_Dir        aDir(aPnt.XYZ().Subtracted(aPlnLoc.XYZ()));
+            gp_Ax3        aXNorm(aPlnLoc, aXLin.Direction(), aDir);
+            gp_Ax3        aNewPlnPos(aPlnLoc, aXNorm.YDirection(),
+                                     aXNorm.Direction());
+
+            thePlane.SetPosition(aNewPlnPos);
+            thePlnStatus = PLN_FIXED;
+            return;
+          }
+        }
+        break;
+      default:
+        return;
+    }
+  }
+}
diff --git a/src/CurveCreator/CurveCreator_Utils.hxx b/src/CurveCreator/CurveCreator_Utils.hxx
new file mode 100644 (file)
index 0000000..8dddaf2
--- /dev/null
@@ -0,0 +1,211 @@
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef CURVECREATOR_UTILS_H
+#define CURVECREATOR_UTILS_H
+
+#include "CurveCreator_Macro.hxx"
+#include "CurveCreator_ICurve.hxx"
+
+#include <AIS_InteractiveContext.hxx>
+#include <AIS_InteractiveObject.hxx> // TODO: remove
+#include <V3d_View.hxx>
+#include <gp_Pnt.hxx>
+#include <Geom_Curve.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+
+#include <list>
+#include <vector> // TODO: remove
+
+class CurveCreator_Curve;
+
+
+class CurveCreator_Utils
+{
+public:
+
+    /*!
+   * \brief Returns the point clicked in 3D view.
+   *
+   * \param x The X coordinate in the view.
+   * \param y The Y coordinate in the view.
+   * \param theView View where the given point takes place.
+   * \retval gp_Pnt Returns the point clicked in 3D view
+   */
+  CURVECREATOR_EXPORT static void ConvertPointToClick( const gp_Pnt& thePoint,
+                                                       Handle(V3d_View) theView,
+                                                       int& x, int& y );
+
+  /*!
+   * \brief Returns the point clicked in 3D view.
+   *
+   * \param x The X coordinate in the view.
+   * \param y The Y coordinate in the view.
+   * \param theView View where the given point takes place.
+   * \retval gp_Pnt Returns the point clicked in 3D view
+   */
+  CURVECREATOR_EXPORT static gp_Pnt ConvertClickToPoint( int x, int y,
+                                                         Handle(V3d_View) theView );
+
+  /**
+   * Generates shape on the curve
+   * \param theCurve a curve object, that contains data
+   * \param theShape a generated shape
+   */
+  CURVECREATOR_EXPORT static void constructShape( const CurveCreator_ICurve* theCurve,
+                                                  TopoDS_Shape& theShape );
+
+  /**
+   * Generates a curve from a shape.
+   * \param theShape a shape to be converted to curve.
+   * \param theCurve a curve object to be initialized.
+   * \param theLocalCS the local coordinate system of the curve.
+   * \return true in case of success; false otherwise. Warning: the curve can
+   *         be modified even if the shape is not valid for curve construction.
+   */
+  CURVECREATOR_EXPORT static bool constructCurve
+                      (const TopoDS_Shape        theShape,
+                             CurveCreator_Curve *theCurve,
+                             gp_Ax3             &theLocalCS);
+
+  /**
+   * Find selected points in the context
+   * \param theContext the viewer context
+   * \param theCurve a curve object, that contains data
+   */
+  CURVECREATOR_EXPORT static void getSelectedPoints( Handle(AIS_InteractiveContext) theContext,
+                                         const CurveCreator_ICurve* theCurve,
+                                         CurveCreator_ICurve::SectionToPointList& thePoints );
+
+  /**
+   * Set selected points to the context
+   * \param theContext the viewer context
+   * \param theCurve a curve object, that contains data
+   * \param thePoints the curve point indices to be selected in the context
+   */
+  CURVECREATOR_EXPORT static void setSelectedPoints(
+                                         Handle(AIS_InteractiveContext) theContext,
+                                         const CurveCreator_ICurve* theCurve,
+                                         const CurveCreator_ICurve::SectionToPointList& thePoints =
+                                               CurveCreator_ICurve::SectionToPointList() );
+
+  /*!
+   * \brief Sets the local point context for the 3D viewer.
+   * \param theCurve a curve object, that contains data
+   * \param theContext the viewer context
+   * \param theOpen The flag to open or close the local context.
+   */
+  CURVECREATOR_EXPORT static void setLocalPointContext(
+                                        const CurveCreator_ICurve* theCurve,
+                                        Handle(AIS_InteractiveContext) theContext,
+                                        const bool theOpen );
+
+  /**
+   * Checks whether the point belongs to the OCC object
+   * \param theObject a line or shape with a bspline inside
+   * \param theX the X coordinate in the view.
+   * \param theY the Y coordinate in the view.
+   * \param thePoint the output point to be append to the model curve
+   * \param thePoint1 the output point to bound the line where a new point should be inserted
+   * \param thePoint2 the output point to bound the line where a new point should be inserted
+   */
+  CURVECREATOR_EXPORT static bool pointOnObject( Handle(V3d_View) theView,
+                                                 Handle(AIS_InteractiveObject) theObject,
+                                                 const int theX, const int theY,
+                                                 gp_Pnt& thePoint, gp_Pnt& thePoint1,
+                                                 gp_Pnt& thePoint2 );
+
+protected:
+  /*
+   * Returns whether the clicked point belong to the curve or has a very near projection
+   * \param theX the X coordinate of a point clicked in the OCC viewer
+   * \param theY the Y coordinate of a point clicked in the OCC viewer
+   * \param theCurve a geometry curve
+   * \param theOutPoint a found projected point on the curve
+  */
+  static bool hasProjectPointOnCurve(
+                             Handle(V3d_View) theView,
+                             const int theX, const int theY,
+                             const Handle(Geom_Curve)& theCurve,
+                             Standard_Real& theParameter,
+                             int& theDelta );
+
+  /*
+   * Returns whether the X and Y coordinates is in the pixel tolerance
+   * \param theX the X coordinate of the first point
+   * \param theY the Y coordinate of the first point
+   * \param theOtherX the X coordinate of the second point
+   * \param theOtherY the Y coordinate of the second point
+   * \param theTolerance the tolerance to compare
+   * \param theDelta the sum of the a square of X and a square of Y
+   * \returns whether the points are provide to the pixel tolerance
+  */
+  static bool isEqualPixels( const int theX, const int theY,
+                             const int theOtherX, const int theOtherY,
+                             const double theTolerance, int& theDelta );
+
+
+  /*
+   * Returns whether the points are the same
+   * \param thePoint the first point
+   * \param theOtherPoint the second point
+   * \returns whether the points are provide to the pixel tolerance
+  */
+  static bool isEqualPoints( const gp_Pnt& thePoint,
+                             const gp_Pnt& theOtherPoint );
+
+  /**
+   * Returns the array of points of a shape to construct a curve section. The
+   * shape can be either a wire or a vertex. For vertex a single point in the
+   * array is returned.
+   *
+   * \param theShape the shape. Can be either a wire or a vertex.
+   * \param IsClosed closed flag. Output parameter.
+   * \param IsBSpline BSpline flag. Output parameter.
+   * \return the array of points. Null handle in case of failure.
+   */
+  static Handle_TColgp_HArray1OfPnt getPoints
+                           (const TopoDS_Shape &theShape,
+                                  bool         &IsClosed,
+                                  bool         &IsBSpline);
+
+  /**
+   * This method computes a plane using the input points. The plane is defined
+   * by gp_Pln object and the status. The status can have one of the following
+   * values:
+   *   - 0 plane is not set.<BR>
+   *   - 1 origin of the plane is fixed. The plane is defined by 1 or several
+   *       coincident points.<BR>
+   *   - 2 origin + OX axis of the plane is fixed. The plane is defined by 2
+   *       or more points that lie on a particular line.<BR>
+   *   - 3 plane is fixed. Plane is defined by 3 not coincident points.<BR>
+   *
+   * \param thePoints the points.
+   * \param thePlane the current plane on input. It can be modified on output.
+   * \param thePlnStatus the current status on input. It can be modified on
+   *        output.
+   */
+  static void FindPlane(const Handle_TColgp_HArray1OfPnt &thePoints,
+                              gp_Pln                     &thePlane,
+                              Standard_Integer           &thePlnStatus);
+
+};
+
+#endif // CURVECREATOR_UTILS_H
diff --git a/src/CurveCreator/CurveCreator_UtilsICurve.cxx b/src/CurveCreator/CurveCreator_UtilsICurve.cxx
new file mode 100644 (file)
index 0000000..d11598e
--- /dev/null
@@ -0,0 +1,126 @@
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "CurveCreator_UtilsICurve.hxx"
+
+#include "CurveCreator.hxx"
+#include <gp_Pnt.hxx>
+
+const double LOCAL_SELECTION_TOLERANCE = 0.0001;
+
+int CurveCreator_UtilsICurve::findLocalPointIndex( const CurveCreator_ICurve* theCurve,
+                                             int theSectionId, float theX, float theY )
+{
+  int aPntIndex = -1;
+  if ( !theCurve )
+    return aPntIndex;
+
+  CurveCreator::Coordinates aCoords;
+  for ( int i = 0, aNb = theCurve->getNbPoints( theSectionId ); i < aNb && aPntIndex < 0; i++ ) {
+    aCoords = theCurve->getPoint( theSectionId, i );
+    if ( aCoords.size() < 2 )
+      continue;
+    if ( fabs( aCoords[0] - theX ) < LOCAL_SELECTION_TOLERANCE &&
+         fabs( aCoords[1] - theY ) < LOCAL_SELECTION_TOLERANCE )
+      aPntIndex = i;
+  }
+
+  return aPntIndex;
+}
+
+void CurveCreator_UtilsICurve::findSectionsToPoints( const CurveCreator_ICurve* theCurve,
+                                 const double theX, const double theY,
+                                 CurveCreator_ICurve::SectionToPointList& thePoints )
+{
+  thePoints.clear();
+
+  int aPointId = -1;
+  for ( int i = 0, aNb = theCurve->getNbSections(); i < aNb; i++ ) {
+    aPointId = CurveCreator_UtilsICurve::findLocalPointIndex( theCurve, i, theX, theY );
+    if ( aPointId < 0 )
+      continue;
+    CurveCreator_ICurve::SectionToPoint aPoint = std::make_pair( i, aPointId );
+    if ( !CurveCreator_UtilsICurve::contains( thePoints, aPoint ) )
+      thePoints.push_back( aPoint );
+  }
+}
+
+void CurveCreator_UtilsICurve::convert( const CurveCreator_ICurve::SectionToPointList& thePoints,
+                                  QMap<int, QList<int> >& theConvPoints )
+{
+  theConvPoints.clear();
+
+  CurveCreator_ICurve::SectionToPointList::const_iterator anIt = thePoints.begin(),
+                                                          aLast = thePoints.end();
+  QList<int> aPoints;
+  int aSectionId, aPointId;
+  for ( ; anIt != aLast; anIt++ ) {
+    aSectionId = anIt->first;
+    aPointId = anIt->second;
+    aPoints.clear();
+    if ( theConvPoints.contains( aSectionId ) )
+      aPoints = theConvPoints[aSectionId];
+    if ( aPoints.contains( aPointId ) )
+      continue;
+    aPoints.append( aPointId );
+    theConvPoints[aSectionId] = aPoints;
+  }
+}
+
+#include "CurveCreator_Curve.hxx" // TODO
+void CurveCreator_UtilsICurve::getPoint( const CurveCreator_ICurve* theCurve, const int theISection,
+                                         const int theIPoint, gp_Pnt& thePoint )
+{
+  double anX, anY, aZ;
+  // TODO
+  const CurveCreator_Curve* aCurve = dynamic_cast<const CurveCreator_Curve*>( theCurve );
+  if ( aCurve )
+    aCurve->getCoordinates( theISection, theIPoint, anX, anY, aZ );
+  thePoint = gp_Pnt( anX, anY, aZ);
+}
+
+std::string CurveCreator_UtilsICurve::getUniqSectionName( CurveCreator_ICurve* theCurve )
+{
+  for( int i = 0 ; i < 1000000 ; i++ ){
+    char aBuffer[255];
+    sprintf( aBuffer, "Section_%d", i+1 );
+    std::string aName(aBuffer);
+    int j;
+    for( j = 0 ; j < theCurve->getNbSections() ; j++ ){
+      if( theCurve->getSectionName(j) == aName )
+        break;
+    }
+    if( j == theCurve->getNbSections() )
+      return aName;
+  }
+  return "";
+}
+
+bool CurveCreator_UtilsICurve::contains( const CurveCreator_ICurve::SectionToPointList& theList,
+                                         const CurveCreator_ICurve::SectionToPoint& theValue )
+{
+  bool isFound = false;
+
+  CurveCreator_ICurve::SectionToPointList::const_iterator anIt = theList.begin(),
+                                                          aLast = theList.end();
+  for ( ; anIt != aLast && !isFound; anIt++ )
+    isFound = anIt->first == theValue.first && anIt->second == theValue.second;
+
+  return isFound;
+}
diff --git a/src/CurveCreator/CurveCreator_UtilsICurve.hxx b/src/CurveCreator/CurveCreator_UtilsICurve.hxx
new file mode 100644 (file)
index 0000000..96b4e45
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef CURVECREATOR_UTILS_ICURVE_H
+#define CURVECREATOR_UTILS_ICURVE_H
+
+#include "CurveCreator_Macro.hxx"
+
+#include "CurveCreator_ICurve.hxx"
+
+#include <gp_Pnt.hxx>
+
+#include <QMap>
+#include <QList>
+
+class CurveCreator_UtilsICurve
+{
+public:
+
+  /*!
+   * Returns a point index in the model curve by the point coordinates in the viewer
+   * \param theX the X coordinate of the point
+   * \param theY the Y coordinate of the point
+   */
+  CURVECREATOR_EXPORT static int  findLocalPointIndex( const CurveCreator_ICurve* theCurve,
+                                          int theSectionId, float theX, float theY );
+
+  CURVECREATOR_EXPORT static void findSectionsToPoints( const CurveCreator_ICurve* theCurve,
+                                          const double theX, const double theY,
+                                          CurveCreator_ICurve::SectionToPointList& thePoints );
+  CURVECREATOR_EXPORT static void convert( const CurveCreator_ICurve::SectionToPointList& thePoints,
+                                           QMap<int, QList<int> >& theConvPoints );
+
+  CURVECREATOR_EXPORT static void getPoint( const CurveCreator_ICurve* theCurve, const int theISection,
+                                            const int theIPoint, gp_Pnt& thePoint );
+
+  /*!
+   * Returns a unique section name
+   * \param theCurve a curve interface
+   */
+  CURVECREATOR_EXPORT static std::string getUniqSectionName(
+                                            CurveCreator_ICurve* theCurve );
+
+  /**
+   * Returns whethe the container has the value
+   * \param theList a container of values
+   * \param theValue a value
+   */
+  CURVECREATOR_EXPORT static bool contains( const CurveCreator_ICurve::SectionToPointList& theList,
+                                            const CurveCreator_ICurve::SectionToPoint& theValue );
+};
+
+#endif // CURVECREATOR_UTILS_ICURVE_H
index 180284fc16f86e95dbf279bf7e91423f22dd6ce3..9cd21e3b7fe3339a915b1f870a1c204bd037716e 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 #include "CurveCreator_Widget.h"
 #include "CurveCreator_TreeView.h"
-#include "CurveCreator_Curve.hxx"
-#include "CurveCreator_CurveEditor.hxx"
+#include "CurveCreator_ICurve.hxx"
 #include "CurveCreator.hxx"
-#include "CurveCreator_NewPointDlg.h"
 #include "CurveCreator_NewSectionDlg.h"
-
-#include <GEOMUtils.hxx>
+#include "CurveCreator_Utils.hxx"
+#include "CurveCreator_UtilsICurve.hxx"
+#include "CurveCreator_TableView.h"
 
 #include <SUIT_Session.h>
 #include <SUIT_Desktop.h>
 #include <SUIT_ResourceMgr.h>
 #include <SUIT_ViewManager.h>
 
-#include <OCCViewer_ViewWindow.h>
 #include <OCCViewer_ViewManager.h>
 #include <OCCViewer_ViewPort3d.h>
-
-#include <BRep_Tool.hxx>
-#include <TopoDS.hxx>
+#include <OCCViewer_Utilities.h>
 
 #include <QHBoxLayout>
 #include <QVBoxLayout>
 #include <QMenu>
 #include <QMouseEvent>
 #include <QApplication>
+#include <QTableWidget>
+#include <QTime>
+
+//#define MEASURE_TIME
+
+#ifdef MEASURE_TIME
+
+  #define START_MEASURE_TIME \
+    QTime aTimer;            \
+    aTimer.start();          \
+
+  #define END_MEASURE_TIME( theMsg )                      \
+    double aTime = aTimer.elapsed() * 0.001;              \
+    FILE* aFile = fopen( "performance", "a" );            \
+    fprintf( aFile, "%s = %.3lf sec\n", theMsg, aTime );  \
+    fclose( aFile );                                      \
+
+#else
+
+  #define START_MEASURE_TIME
+  #define END_MEASURE_TIME( theMsg )
+
+#endif
+
+
+
+
+
 
 CurveCreator_Widget::CurveCreator_Widget(QWidget* parent,
-                                         CurveCreator_Curve *theCurve,
-                                         Qt::WindowFlags fl) :
-    QWidget(parent), myNewPointEditor(NULL), myNewSectionEditor(NULL), myEdit(NULL), myCurve(theCurve)
-{
-    if( myCurve )
-        myEdit = new CurveCreator_CurveEditor( myCurve );
-
-    CurveCreator::Dimension aDim = CurveCreator::Dim2d;
-    if( myCurve )
-        aDim = myCurve->getDimension();
-    myNewPointEditor = new CurveCreator_NewPointDlg( aDim, this );
-    myNewPointEditor->hide();
-//    connect( myNewPointEditor, SIGNAL(addPoint()), this, SLOT(onAddNewPoint()) );
-    connect( myNewPointEditor, SIGNAL(modifyPoint()), this, SLOT(onModifyPoint()) );
-    connect( myNewPointEditor, SIGNAL(cancelPoint()), this, SLOT(onCancelPoint()) );
-
-    myNewSectionEditor = new CurveCreator_NewSectionDlg( this );
-    myNewSectionEditor->hide();
-    connect( myNewSectionEditor, SIGNAL(addSection()), this, SLOT(onAddNewSection()) );
-    connect( myNewSectionEditor, SIGNAL(modifySection()), this, SLOT(onModifySection()) );
-    connect( myNewSectionEditor, SIGNAL(cancelSection()), this, SLOT(onCancelSection()) );
-
-    QGroupBox* aSectionGroup = new QGroupBox(tr("Sections"),this);
-
-    mySectionView = new CurveCreator_TreeView(myCurve, aSectionGroup);
-    connect( mySectionView, SIGNAL(selectionChanged()), this, SLOT( onSelectionChanged() ) );
-    connect( mySectionView, SIGNAL(pointEntered(int,int)), this, SLOT(onEditPoint(int,int)) );
-    connect( mySectionView, SIGNAL(sectionEntered(int)), this, SLOT(onEditSection(int)) );
-    connect( mySectionView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onContextMenu(QPoint)) );
-    QToolBar* aTB = new QToolBar(tr("TOOL_BAR_TLT"), aSectionGroup);
+                                         CurveCreator_ICurve *theCurve,
+                                         const int theActionFlags,
+                                         const QStringList& theCoordTitles,
+                                         Qt::WindowFlags fl,
+                                         int theLocalPointRowLimit )
+: QWidget(parent), myNewSectionEditor(NULL), myCurve(theCurve), mySection(0),
+  myDragStarted( false ), myDragInteractionStyle( SUIT_ViewModel::STANDARD ),
+  myOCCViewer( 0 ), myLocalPointRowLimit( theLocalPointRowLimit ),
+  myOld2DMode(OCCViewer_ViewWindow::No2dMode)
+{
+  bool isToEnableClosed = !( theActionFlags & DisableClosedSection );
+  myNewSectionEditor = new CurveCreator_NewSectionDlg( this, isToEnableClosed );
+  myNewSectionEditor->hide();
+  connect( myNewSectionEditor, SIGNAL(addSection()), this, SLOT(onAddNewSection()) );
+  connect( myNewSectionEditor, SIGNAL(modifySection()), this, SLOT(onModifySection()) );
+  connect( myNewSectionEditor, SIGNAL(cancelSection()), this, SLOT(onCancelSection()) );
+
+  QGroupBox* aSectionGroup = new QGroupBox(tr("SECTION_GROUP_TITLE"),this);
+
+  mySectionView = new CurveCreator_TreeView(myCurve, aSectionGroup);
+  mySectionView->setSelectionMode( QTreeView::ExtendedSelection );
+  connect( mySectionView, SIGNAL(selectionChanged()), this, SLOT( onSelectionChanged() ) );
+  connect( mySectionView, SIGNAL(sectionEntered(int)), this, SLOT(onEditSection(int)) );
+  connect( mySectionView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onContextMenu(QPoint)) );
+
+  myLocalPointView = new CurveCreator_TableView( myCurve, this, theCoordTitles );
+  connect( myLocalPointView, SIGNAL( cellChanged( int, int ) ),
+           this, SLOT( onCellChanged( int, int ) ) );
+
+  QToolBar* aTB = new QToolBar(tr("SECTION_GROUP_TITLE"), aSectionGroup);
 //    QToolButton* anUndoBtn = new QToolButton(aTB);
 
-    SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
-    QPixmap anUndoPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_UNDO")));
-    QPixmap aRedoPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_REDO")));
-    QPixmap aNewSectionPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_NEW_SECTION")));
-    QPixmap aNewPointPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_NEW_POINT")));
-    QPixmap anEditPointsPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_EDIT_POINTS")));
-    QPixmap aDetectPointsPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_EDIT_POINTS")));
-    QPixmap aPolylinePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
-    QPixmap aSplinePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_SPLINE")));
-    QPixmap aRemovePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_DELETE")));
-    QPixmap aJoinPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_JOIN")));
-    QPixmap aStepUpPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_ARROW_UP")));
-    QPixmap aStepDownPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_ARROW_DOWN")));
-
-/*    QPixmap anUndoPixmap = QPixmap(tr(":images/ICON_UNDO"));
-    QPixmap aRedoPixmap = QPixmap(tr(":images/ICON_REDO"));
-    QPixmap aNewSectionPixmap = QPixmap(tr(":images/ICON_NEW_SECTION"));
-    QPixmap aNewPointPixmap = QPixmap(tr(":images/ICON_NEW_POINT"));
-    QPixmap aPolylinePixmap = QPixmap(tr(":images/ICON_POLYLINE"));
-    QPixmap aSplinePixmap = QPixmap(tr(":images/ICON_SPLINE"));
-    QPixmap aRemovePixmap = QPixmap(tr(":images/ICON_REMOVE"));
-    QPixmap aJoinPixmap = QPixmap(tr(":images/ICON_JOIN"));
-    QPixmap aStepUpPixmap = QPixmap(tr(":images/ICON_STEP_UP"));
-    QPixmap aStepDownPixmap = QPixmap(tr(":images/ICON_STEP_DOWN"));*/
-
-    QAction* anAct = createAction( UNDO_ID, tr("UNDO"), anUndoPixmap, tr("UNDO_TLT"), 
-                                   QKeySequence(Qt::ControlModifier|Qt::Key_Z) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onUndo()) );
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  QPixmap anUndoPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_UNDO")));
+  QPixmap aRedoPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_REDO")));
+  QPixmap aNewSectionPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_NEW_SECTION")));
+  QPixmap aNewPointPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_NEW_POINT")));
+  QPixmap anEditPointsPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_EDIT_POINTS")));
+  QPixmap aDetectPointsPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_EDIT_POINTS")));
+  QPixmap aPolylinePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
+  QPixmap aSplinePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_SPLINE")));
+  QPixmap aRemovePixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_DELETE")));
+  QPixmap aJoinPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_JOIN")));
+  QPixmap aStepUpPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_ARROW_UP")));
+  QPixmap aStepDownPixmap(aResMgr->loadPixmap("GEOM", tr("ICON_CC_ARROW_DOWN")));
+
+  QAction* anAct = createAction( UNDO_ID, tr("UNDO"), anUndoPixmap, tr("UNDO_TLT"), 
+                                 QKeySequence(Qt::ControlModifier|Qt::Key_Z) );
+  connect(anAct, SIGNAL(triggered()), this, SLOT(onUndo()) );
+  aTB->addAction(anAct);
+
+  anAct = createAction( REDO_ID, tr("REDO"), aRedoPixmap, tr("REDO_TLT"), 
+                        QKeySequence(Qt::ControlModifier|Qt::Key_Y) );
+  connect(anAct, SIGNAL(triggered()), this, SLOT(onRedo()) );
+  aTB->addAction(anAct);
+
+  aTB->addSeparator();
+  
+  anAct = createAction( NEW_SECTION_ID, tr("NEW_SECTION"), aNewSectionPixmap, tr("NEW_SECTION_TLT"), 
+                        QKeySequence(Qt::ControlModifier|Qt::Key_N) );
+  connect(anAct, SIGNAL(triggered()), this, SLOT(onNewSection()) );
+  if ( !(theActionFlags & DisableNewSection) ) {
     aTB->addAction(anAct);
+    aTB->addSeparator();
+  }
 
-    anAct = createAction( REDO_ID, tr("REDO"), aRedoPixmap, tr("REDO_TLT"), 
-                          QKeySequence(Qt::ControlModifier|Qt::Key_Y) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onRedo()) );
+  anAct = createAction( ADDITION_MODE_ID, tr("ADDITION_MODE"), aNewPointPixmap, tr("ADDITION_MODE_TLT"), 
+                        QKeySequence() );
+  anAct->setCheckable(true);
+  connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onAdditionMode(bool)) );
+  connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
+  aTB->addAction(anAct);
+  
+  anAct = createAction( MODIFICATION_MODE_ID, tr("MODIFICATION_MODE"), anEditPointsPixmap, tr("MODIFICATION_MODE_TLT"), 
+                        QKeySequence() );
+  anAct->setCheckable(true);
+  connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onModificationMode(bool)) );
+  connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
+  aTB->addAction(anAct);
+
+  anAct = createAction( DETECTION_MODE_ID, tr("DETECTION_MODE"), aDetectPointsPixmap, tr("DETECTION_MODE_TLT"), 
+                        QKeySequence() );
+  anAct->setCheckable(true);
+  connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onDetectionMode(bool)) );
+  connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
+  if ( !(theActionFlags & DisableDetectionMode) ) {
     aTB->addAction(anAct);
+  }
+  
+  anAct = createAction( CLOSE_SECTIONS_ID, tr("CLOSE_SECTIONS"), QPixmap(), tr("CLOSE_SECTIONS_TLT"), 
+                        QKeySequence(Qt::ControlModifier|Qt::Key_W) );
+  connect(anAct, SIGNAL(triggered()), this, SLOT(onCloseSections()) );
+
+  anAct = createAction( UNCLOSE_SECTIONS_ID, tr("UNCLOSE_SECTIONS"), QPixmap(), 
+                        tr("UNCLOSE_SECTIONS_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_S) );
+  connect(anAct, SIGNAL(triggered()), this, SLOT(onUncloseSections()) );
+
+  anAct = createAction( SET_SECTIONS_POLYLINE_ID, tr("SET_SECTIONS_POLYLINE"), 
+                        aPolylinePixmap, tr("SET_SECTIONS_POLYLINE_TLT"), 
+                        QKeySequence(Qt::ControlModifier|Qt::Key_E) );
+  connect(anAct, SIGNAL(triggered()), this, SLOT(onSetPolyline()) );
+
+  anAct = createAction( SET_SECTIONS_SPLINE_ID, tr("SET_SECTIONS_SPLINE"), aSplinePixmap, 
+                        tr("SET_SECTIONS_SPLINE_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_R) );
+  connect(anAct, SIGNAL(triggered()), this, SLOT(onSetSpline()) );
+
+  anAct = createAction( REMOVE_ID, tr("REMOVE"), aRemovePixmap, tr("REMOVE_TLT"), 
+                        QKeySequence(Qt::ControlModifier|Qt::Key_Delete ) );
+  connect(anAct, SIGNAL(triggered()), this, SLOT(onRemove()) );
+  aTB->addAction(anAct);
+  
+  aTB->addSeparator();
+
+  anAct = createAction( JOIN_ID, tr("JOIN"), aJoinPixmap, tr("JOIN_TLT"), 
+                        QKeySequence(Qt::ControlModifier|Qt::Key_Plus ) );
+  connect( anAct, SIGNAL(triggered()), this, SLOT(onJoin()) );
+  aTB->addAction(anAct);
+
+  anAct = createAction( CLEAR_ALL_ID, tr("CLEAR_ALL"), QPixmap(), tr("CLEAR_ALL_TLT"), 
+                        QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Delete ) );
+  connect( anAct, SIGNAL(triggered()), this, SLOT( onClearAll()) );
+
+  anAct = createAction( JOIN_ALL_ID, tr("JOIN_ALL"), QPixmap(), tr("JOIN_ALL_TLT"), 
+                        QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Plus ) );
+  connect( anAct, SIGNAL(triggered()), this, SLOT(onJoinAll()) );
+
+  QVBoxLayout* aSectLayout = new QVBoxLayout();
+  aSectLayout->setMargin( 5 );
+  aSectLayout->setSpacing( 5 );
+  aSectLayout->addWidget(aTB);
+  aSectLayout->addWidget(mySectionView);
+  aSectLayout->addWidget( myLocalPointView );
+  aSectionGroup->setLayout(aSectLayout);
+  QVBoxLayout* aLay = new QVBoxLayout();
+  aLay->setMargin( 0 );
+  aLay->setSpacing( 5 );
+//    aLay->addLayout(aNameLayout);
+  aLay->addWidget(aSectionGroup);
+  setLayout(aLay);
 
-    aTB->addSeparator();
+  updateActionsStates();
+  updateUndoRedo();
+}
 
-    anAct = createAction( NEW_SECTION_ID, tr("NEW_SECTION"), aNewSectionPixmap, tr("NEW_SECTION_TLT"), 
-                          QKeySequence(Qt::ControlModifier|Qt::Key_N) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onNewSection()) );
-    aTB->addAction(anAct);
-    aTB->addSeparator();
+/**
+ * Set an OCC viewer
+ */
+void CurveCreator_Widget::setOCCViewer( OCCViewer_Viewer* theViewer )
+{
+  if ( myOCCViewer == theViewer )
+    return;
 
-    anAct = createAction( INSERT_SECTION_BEFORE_ID, tr("INSERT_SECTION_BEFORE"), QPixmap(), 
-                          tr("INSERT_SECTION_BEFORE_TLT"),
-                          QKeySequence(Qt::ControlModifier | Qt::Key_Insert ) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onInsertSectionBefore()) );
-
-    anAct = createAction( INSERT_SECTION_AFTER_ID, tr("INSERT_SECTION_AFTER"), QPixmap(), 
-                          tr("INSERT_SECTION_AFTER_TLT"),
-                          QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Insert ) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onInsertSectionAfter()) );
-
-    anAct = createAction( ADDITION_MODE_ID, tr("ADDITION_MODE"), aNewPointPixmap, tr("ADDITION_MODE_TLT"), 
-                          QKeySequence() );
-    anAct->setCheckable(true);
-    connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onAdditionMode(bool)) );
-    connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
-    aTB->addAction(anAct);
+  if ( myOCCViewer ) {
+    OCCViewer_ViewManager* aViewManager = dynamic_cast<OCCViewer_ViewManager*>
+                                                    ( myOCCViewer->getViewManager() );
+    disconnect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
+           this, SLOT( onMousePress( SUIT_ViewWindow*, QMouseEvent* ) ) );
+    disconnect( aViewManager, SIGNAL( mouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ),
+           this, SLOT( onMouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ) );
+    disconnect( aViewManager, SIGNAL( mouseMove( SUIT_ViewWindow*, QMouseEvent* ) ),
+           this, SLOT( onMouseMove( SUIT_ViewWindow*, QMouseEvent* ) ) );
+    disconnect( aViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
+           this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
+    // restore normal mode in the viewer
+    SetViewer2DMode(false);
+    // all local contexts should be closed if the viewer is not more used
+    setLocalPointContext( false, true );
+  }
+
+  myOCCViewer = theViewer;
+  if ( myOCCViewer ) {
+    OCCViewer_ViewManager* aViewManager = dynamic_cast<OCCViewer_ViewManager*>
+                                                    ( myOCCViewer->getViewManager() );
+    connect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
+           this, SLOT( onMousePress( SUIT_ViewWindow*, QMouseEvent* ) ) );
+    connect( aViewManager, SIGNAL( mouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ),
+           this, SLOT( onMouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ) );
+    connect( aViewManager, SIGNAL( mouseMove( SUIT_ViewWindow*, QMouseEvent* ) ),
+           this, SLOT( onMouseMove( SUIT_ViewWindow*, QMouseEvent* ) ) );
+    connect( aViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
+           this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
+    SetViewer2DMode(true);
+  }
+}
+
+/**
+ * Returns current OCC viewer
+ */
+OCCViewer_Viewer* CurveCreator_Widget::getOCCViewer()
+{
+  return myOCCViewer;
+}
+
+/**
+ * Returns OCC viewer context
+ */
+Handle(AIS_InteractiveContext) CurveCreator_Widget::getAISContext()
+{
+  Handle(AIS_InteractiveContext) aContext;
+  OCCViewer_Viewer* aViewer = getOCCViewer();
+  if ( aViewer )
+    aContext = aViewer->getAISContext();
+
+  return aContext;
+}
+
+/**
+ * Returns OCC viewer view port
+ */
+OCCViewer_ViewPort3d* CurveCreator_Widget::getViewPort()
+{
+  OCCViewer_ViewPort3d* aViewPort = 0;
+  OCCViewer_Viewer* aViewer = getOCCViewer();
+  if ( aViewer )
+    aViewPort = ((OCCViewer_ViewWindow*)aViewer->getViewManager()->getActiveView())->getViewPort();
     
-    anAct = createAction( MODIFICATION_MODE_ID, tr("MODIFICATION_MODE"), anEditPointsPixmap, tr("MODIFICATION_MODE_TLT"), 
-                          QKeySequence() );
-    anAct->setCheckable(true);
-    connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onModificationMode(bool)) );
-    connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
-    aTB->addAction(anAct);
+  return aViewPort;
+}
 
-    anAct = createAction( DETECTION_MODE_ID, tr("DETECTION_MODE"), aDetectPointsPixmap, tr("DETECTION_MODE_TLT"), 
-                          QKeySequence() );
-    anAct->setCheckable(true);
-    connect(anAct, SIGNAL(triggered(bool)), this, SLOT(onDetectPoints(bool)) );
-    connect(anAct, SIGNAL(toggled(bool)), this, SLOT(onModeChanged(bool)) );
-    aTB->addAction(anAct);
+/**
+ * Set interaction style in the OCC viewer
+ * \param theStyle a new style
+ * \return the previous style
+ */
+int CurveCreator_Widget::changeInteractionStyle( int theStyle )
+{
+  OCCViewer_Viewer* aViewer = getOCCViewer();
+  if ( !aViewer )
+    return -1;
 
-    anAct = createAction( INSERT_POINT_BEFORE_ID, tr("INSERT_POINT_BEFORE"), QPixmap(), 
-                          tr("INSERT_POINT_BEFORE_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_B) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onInsertPointBefore()) );
-
-    anAct = createAction( INSERT_POINT_AFTER_ID, tr("INSERT_POINT_AFTER"), QPixmap(), 
-                           tr("INSERT_POINT_AFTER_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_M) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onInsertPointAfter()) );
-                                 
-    anAct = createAction( CLOSE_SECTIONS_ID, tr("CLOSE_SECTIONS"), QPixmap(), tr("CLOSE_SECTIONS_TLT"), 
-                          QKeySequence(Qt::ControlModifier|Qt::Key_W) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onCloseSections()) );
-
-    anAct = createAction( UNCLOSE_SECTIONS_ID, tr("UNCLOSE_SECTIONS"), QPixmap(), 
-                          tr("UNCLOSE_SECTIONS_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_S) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onUncloseSections()) );
-
-    anAct = createAction( SET_SECTIONS_POLYLINE_ID, tr("SET_SECTIONS_POLYLINE"), 
-                          aPolylinePixmap, tr("SET_POLYLINE_TLT"), 
-                          QKeySequence(Qt::ControlModifier|Qt::Key_E) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onSetPolyline()) );
-
-    anAct = createAction( SET_SECTIONS_SPLINE_ID, tr("SET_SECTIONS_SPLINE"), aSplinePixmap, 
-                          tr("SET_SPLINE_TLT"), QKeySequence(Qt::ControlModifier|Qt::Key_R) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onSetSpline()) );
-
-    anAct = createAction( REMOVE_ID, tr("REMOVE"), aRemovePixmap, tr("REMOVE_TLT"), 
-                          QKeySequence(Qt::ControlModifier|Qt::Key_Delete ) );
-    connect(anAct, SIGNAL(triggered()), this, SLOT(onRemove()) );
-    aTB->addAction(anAct);
-    aTB->addSeparator();
+  int aPrevStyle = aViewer->interactionStyle();
+  aViewer->setInteractionStyle( theStyle );
 
-    anAct = createAction( JOIN_ID, tr("JOIN"), aJoinPixmap, tr("JOIN_TLT"), 
-                          QKeySequence(Qt::ControlModifier|Qt::Key_Plus ) );
-    connect( anAct, SIGNAL(triggered()), this, SLOT(onJoin()) );
-    aTB->addAction(anAct);
-    aTB->addSeparator();
+  return aPrevStyle;
+}
 
-    anAct = createAction( UP_ID, tr("STEP_UP"), aStepUpPixmap, tr("STEP_UP_TLT"), 
-                          QKeySequence(Qt::ControlModifier|Qt::Key_Up ) );
-    connect( anAct, SIGNAL(triggered()), this, SLOT(onMoveUp()) );
-
-    anAct = createAction( DOWN_ID, tr("STEP_DOWN"), aStepDownPixmap, tr("STEP_DOWN"), 
-                          QKeySequence(Qt::ControlModifier|Qt::Key_Down ) );
-    connect( anAct, SIGNAL(triggered()), this, SLOT(onMoveDown()) );
-
-    anAct = createAction( CLEAR_ALL_ID, tr("CLEAR_ALL"), QPixmap(), tr("CLEAR_ALL_TLT"), 
-                          QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Delete ) );
-    connect( anAct, SIGNAL(triggered()), this, SLOT( onClearAll()) );
-
-    anAct = createAction( JOIN_ALL_ID, tr("JOIN_ALL"), QPixmap(), tr("JOIN_ALL_TLT"), 
-                          QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Plus ) );
-    connect( anAct, SIGNAL(triggered()), this, SLOT(onJoinAll()) );
-
-    QVBoxLayout* aSectLayout = new QVBoxLayout();
-    aSectLayout->setMargin( 5 );
-    aSectLayout->setSpacing( 5 );
-    aSectLayout->addWidget(aTB);
-    aSectLayout->addWidget(mySectionView);
-    aSectionGroup->setLayout(aSectLayout);
-    QVBoxLayout* aLay = new QVBoxLayout();
-    aLay->setMargin( 0 );
-    aLay->setSpacing( 5 );
-//    aLay->addLayout(aNameLayout);
-    aLay->addWidget(aSectionGroup);
-    setLayout(aLay);
-    onSelectionChanged();
+//=======================================================================
+// function: reset
+// purpose: reset the widget viewer, close local context, clear selection
+//=======================================================================
+void CurveCreator_Widget::reset()
+{
 }
 
-void CurveCreator_Widget::setCurve( CurveCreator_Curve* theCurve )
+void CurveCreator_Widget::setCurve( CurveCreator_ICurve* theCurve )
 {
-  if( myEdit != NULL ){
-    delete myEdit;
-    myEdit = NULL;
-  }
   myCurve = theCurve;
-  mySectionView->setCurve(myCurve);
-  if( myCurve != NULL ){
-    myEdit = new CurveCreator_CurveEditor(myCurve);
-  }
-  onSelectionChanged();
+  mySectionView->setCurve( myCurve );
+  myLocalPointView->setCurve( myCurve );
+  updateActionsStates();
   updateUndoRedo();
 }
 
 void CurveCreator_Widget::onSelectionChanged()
+{
+  updateActionsStates();
+  updateUndoRedo();
+  emit selectionChanged();
+}
+
+void CurveCreator_Widget::updateActionsStates()
 {
   QList<ActionId> anEnabledAct;
   if( myCurve ){
-    anEnabledAct << NEW_SECTION_ID;
+    anEnabledAct << NEW_SECTION_ID << MODIFICATION_MODE_ID;
+    if ( removeEnabled() )
+      anEnabledAct << REMOVE_ID;
     QList<int> aSelSections = mySectionView->getSelectedSections();
-    QList< QPair< int, int > > aSelPoints = mySectionView->getSelectedPoints();
     CurveCreator_TreeView::SelectionType aSelType = mySectionView->getSelectionType();
     switch( aSelType ){
     case CurveCreator_TreeView::ST_NOSEL:{
@@ -258,29 +354,47 @@ void CurveCreator_Widget::onSelectionChanged()
         anEnabledAct << UP_ID;
       }*/
       if( aSelSections.size() == 1 ){
-        anEnabledAct << ADDITION_MODE_ID << MODIFICATION_MODE_ID << DETECTION_MODE_ID;
+        anEnabledAct << ADDITION_MODE_ID << DETECTION_MODE_ID;
       }
-      if (myActionMap[ADDITION_MODE_ID]->isChecked()) {
-        mySection = -1;
-        myPointNum = -1;
-        QList<int> aSelSection = mySectionView->getSelectedSections();
-        if( aSelSection.size() > 0 ){
-          mySection = aSelSection[0];
-          myPointNum = myCurve->getNbPoints(mySection);
+      switch ( getActionMode() ) {
+        case AdditionMode: {
+          mySection = -1;
+          myPointNum = -1;
+          QList<int> aSelSection = mySectionView->getSelectedSections();
+          if( aSelSection.size() > 0 ){
+            mySection = aSelSection[0];
+            myPointNum = myCurve->getNbPoints(mySection);
+          }
         }
-      } else if (myActionMap[MODIFICATION_MODE_ID]->isChecked()) {
-        anEnabledAct << REMOVE_ID;
-        anEnabledAct << CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID << SET_SECTIONS_POLYLINE_ID << SET_SECTIONS_SPLINE_ID;
-        int aSectCnt = myCurve->getNbSections();
-        if( aSectCnt > 0 )
-          anEnabledAct << CLEAR_ALL_ID;
-        if( aSectCnt > 1 )
-          anEnabledAct << JOIN_ALL_ID;
-        if( aSelSections.size() > 1 ){
-          anEnabledAct << JOIN_ID;
+        break;
+        case ModificationMode: {
+          if ( myNewSectionEditor->isEnableClosed() )
+            anEnabledAct << CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID;
+          anEnabledAct << SET_SECTIONS_POLYLINE_ID << SET_SECTIONS_SPLINE_ID;
+          int aSectCnt = myCurve->getNbSections();
+          if( aSectCnt > 0 )
+            anEnabledAct << CLEAR_ALL_ID;
+          if( aSectCnt > 1 )
+            anEnabledAct << JOIN_ALL_ID;
+          if( aSelSections.size() > 1 ){
+            anEnabledAct << JOIN_ID;
+          }
+        }
+        break;
+        case DetectionMode: {
         }
-      } else if (myActionMap[DETECTION_MODE_ID]->isChecked()) {
-      } else { //no active mode
+        break;
+        case NoneMode:
+          {
+            int aSectCnt = myCurve->getNbSections();
+            if( aSectCnt > 1 )
+              anEnabledAct << JOIN_ALL_ID;
+            if( aSelSections.size() > 1 )
+              anEnabledAct << JOIN_ID;
+          }
+          break;
+        default:
+        break;
       }
       /*if( aSelSections[ aSelSections.size() - 1 ] < ( myCurve->getNbSections() - 1 ) ){
         anEnabledAct << DOWN_ID;
@@ -326,32 +440,16 @@ void CurveCreator_Widget::onSelectionChanged()
       }
     }
   }
-  emit selectionChanged();
 }
 
 void CurveCreator_Widget::onAdditionMode(bool checked)
 {
-  if( !myEdit )
+  if (!checked)
     return;
 
-  SUIT_ViewWindow* aViewWindow = 0;
-  SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
-  if ( activeStudy )
-    aViewWindow = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
-  if ( aViewWindow == 0 )
+  Handle(AIS_InteractiveContext) aContext = getAISContext();
+  if( !myCurve || aContext.IsNull() )
     return;
-  SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
-
-  if ( aViewManager->getType() == OCCViewer_Viewer::Type() ) {
-    if (checked) {
-      connect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
-             this, SLOT( onGetPointByClick( SUIT_ViewWindow*, QMouseEvent* ) ) );
-    } else {
-      disconnect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
-             this, SLOT( onGetPointByClick( SUIT_ViewWindow*, QMouseEvent* ) ) );
-      return;
-    }
-  }
 
   mySection= -1;
   myPointNum = -1;
@@ -359,78 +457,40 @@ void CurveCreator_Widget::onAdditionMode(bool checked)
   if( aSelSection.size() > 0 ){
     mySection = aSelSection[0];
   }
-  else{
-    QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
-    if( aSelPoints.size() > 0 ){
-      mySection = aSelPoints[0].first;
-      myPointNum = aSelPoints[0].second + 1;
-    }
-  }
-/*
-  QString aSectName;
-  if( mySection < 0 ){
-    mySection = myCurve->getNbSections() - 1;
-  }
-  aSectName = QString::fromStdString( myCurve->getSectionName(mySection));
-  if( myPointNum < 0 ){
-    myPointNum = myCurve->getNbPoints(mySection);
-  }
-  myNewPointEditor->clear();
-  myNewPointEditor->setEditMode(false);
-  myNewPointEditor->setSectionName(aSectName);
-  myNewPointEditor->setDimension(myCurve->getDimension());
-*/
 //  emit subOperationStarted( myNewPointEditor );
 }
 
 void CurveCreator_Widget::onModificationMode(bool checked)
 {
-  SUIT_ViewWindow* aViewWindow = 0;
-  SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
-  if ( activeStudy )
-    aViewWindow = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
-  if ( aViewWindow == 0 )
-    return;
-  SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
-  if ( aViewManager->getType() == OCCViewer_Viewer::Type() ) {
-    if (checked) {
-//      connect( aViewManager, SIGNAL( mouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ),
-//             this, SLOT( onPointSelect( SUIT_ViewWindow*, QMouseEvent* ) ) );
-      connect( aViewManager, SIGNAL( mouseMove( SUIT_ViewWindow*, QMouseEvent* ) ),
-             this, SLOT( onPointDrag( SUIT_ViewWindow*, QMouseEvent* ) ) );
-    }
-    else {
-//      disconnect( aViewManager, SIGNAL( mouseRelease( SUIT_ViewWindow*, QMouseEvent* ) ),
-//             this, SLOT( onPointSelect( SUIT_ViewWindow*, QMouseEvent* ) ) );
-      disconnect( aViewManager, SIGNAL( mouseMove( SUIT_ViewWindow*, QMouseEvent* ) ),
-             this, SLOT( onPointDrag( SUIT_ViewWindow*, QMouseEvent* ) ) );
-      return;
-    }
-  }
+  myLocalPointView->setVisible( checked );
 }
 
-void CurveCreator_Widget::onDetectPoints(bool checked)
+void CurveCreator_Widget::onDetectionMode(bool checked)
 {
 }
 
 void CurveCreator_Widget::onModeChanged(bool checked)
 {
+  ActionMode aMode = NoneMode;
   if (checked) {
     QAction* anAction = (QAction*)sender();
     switch(myActionMap.key(anAction)) {
       case ADDITION_MODE_ID:
+        aMode = AdditionMode;
         if (myActionMap[MODIFICATION_MODE_ID]->isChecked())
           myActionMap[MODIFICATION_MODE_ID]->trigger();
         else if (myActionMap[DETECTION_MODE_ID]->isChecked())
           myActionMap[DETECTION_MODE_ID]->trigger();
         break;
       case MODIFICATION_MODE_ID:
+        aMode = ModificationMode;
         if (myActionMap[ADDITION_MODE_ID]->isChecked())
           myActionMap[ADDITION_MODE_ID]->trigger();
         else if (myActionMap[DETECTION_MODE_ID]->isChecked())
           myActionMap[DETECTION_MODE_ID]->trigger();
         break;
       case DETECTION_MODE_ID:
+        aMode = DetectionMode;
         if (myActionMap[ADDITION_MODE_ID]->isChecked())
           myActionMap[ADDITION_MODE_ID]->trigger();
         else if (myActionMap[MODIFICATION_MODE_ID]->isChecked())
@@ -438,54 +498,39 @@ void CurveCreator_Widget::onModeChanged(bool checked)
         break;
     }
   }
-  onSelectionChanged();
-}
-
-void CurveCreator_Widget::onAddNewPoint(const CurveCreator::Coordinates& theCoords)
-{
-  if( !myEdit )
-    return;
-//  CurveCreator::Coordinates aCoords = myNewPointEditor->getCoordinates();
-  myEdit->insertPoints(theCoords, mySection, myPointNum );
-  mySectionView->pointsAdded( mySection, myPointNum );
-//  myNewPointEditor->clear();
-  myPointNum++;
-  onSelectionChanged();
+  updateActionsStates();
   updateUndoRedo();
+  setLocalPointContext( aMode == ModificationMode, true );
 }
 
 void CurveCreator_Widget::onNewSection()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
+
+  stopActionMode();
   myNewSectionEditor->clear();
   myNewSectionEditor->setEditMode(false);
-  QString aSectName = QString( myCurve->getUnicSectionName().c_str() );
+  QString aSectName = QString( CurveCreator_UtilsICurve::getUniqSectionName( myCurve ).c_str() );
   myNewSectionEditor->setSectionParameters(aSectName, true, CurveCreator::Polyline );
-  emit subOperationStarted( myNewSectionEditor );
+  emit subOperationStarted( myNewSectionEditor, false );
 }
 
 void CurveCreator_Widget::onAddNewSection()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
-  CurveCreator::Coordinates aCoords;
-  myEdit->addSection( myNewSectionEditor->getName().toStdString(), myNewSectionEditor->getSectionType(),
-                      myNewSectionEditor->isClosed(), aCoords  );
-  mySectionView->sectionAdded( mySection );
-  QString aNewName = QString(myCurve->getUnicSectionName().c_str());
+  myCurve->addSection( myNewSectionEditor->getName().toStdString(),
+                       myNewSectionEditor->getSectionType(),
+                       myNewSectionEditor->isClosed() );
+  mySectionView->sectionAdded( -1 ); // add a new section to the end of list
+  QString aNewName = QString( CurveCreator_UtilsICurve::getUniqSectionName( myCurve ).c_str() );
   myNewSectionEditor->setSectionName(aNewName);
-  mySection++;
-  onSelectionChanged();
+  updateActionsStates();
   updateUndoRedo();
   onCancelSection();
 }
 
-void CurveCreator_Widget::onCancelPoint()
-{
-  emit subOperationFinished( myNewPointEditor );
-}
-
 void CurveCreator_Widget::onCancelSection()
 {
   emit subOperationFinished( myNewSectionEditor );
@@ -504,212 +549,161 @@ QAction* CurveCreator_Widget::createAction( ActionId theId, const QString& theNa
   return anAct;
 }
 
-QAction* CurveCreator_Widget::getAction(ActionId theId)
+QAction* CurveCreator_Widget::getAction( ActionId theId )
 {
   if( myActionMap.contains(theId) )
     return myActionMap[theId];
   return NULL;
 }
 
+QAction* CurveCreator_Widget::getAction( ActionMode theMode )
+{
+  ActionId anActionId = NONE_ID;
+  switch ( theMode ) {
+    case AdditionMode:
+      anActionId = ADDITION_MODE_ID;
+      break;
+    case ModificationMode:
+      anActionId = MODIFICATION_MODE_ID;
+      break;
+    case DetectionMode:
+      anActionId = DETECTION_MODE_ID;
+      break;
+    default:
+      break;
+  }
+  QAction* anAction = 0;
+  if ( anActionId != NONE_ID && myActionMap.contains( anActionId ) )
+    anAction = myActionMap[anActionId];
+  return anAction;
+}
+
 void CurveCreator_Widget::onEditSection( int theSection )
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
+  
+  stopActionMode();
   mySection = theSection;
   QString aSectName = QString::fromStdString( myCurve->getSectionName(theSection));
   bool isClosed = myCurve->isClosed(theSection);
-  CurveCreator::Type aType = myCurve->getType(theSection);
+  CurveCreator::SectionType aType = myCurve->getSectionType(theSection);
   myNewSectionEditor->setEditMode(true);
   myNewSectionEditor->setSectionParameters( aSectName, isClosed, aType );
 
-  emit subOperationStarted( myNewSectionEditor );
+  emit subOperationStarted( myNewSectionEditor, true );
 }
 
 void CurveCreator_Widget::onModifySection()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
   QString aName = myNewSectionEditor->getName();
   bool isClosed = myNewSectionEditor->isClosed();
-  CurveCreator::Type aSectType = myNewSectionEditor->getSectionType();
-  myEdit->startOperation();
-  myEdit->setClosed( isClosed, mySection );
-  myEdit->setName( aName.toStdString(), mySection );
-  myEdit->setType( aSectType, mySection );
-  myEdit->finishOperation();
+  CurveCreator::SectionType aSectType = myNewSectionEditor->getSectionType();
+  if( myCurve->getSectionName(mySection) != aName.toStdString() )
+    myCurve->setSectionName( mySection , aName.toStdString() );
+
+  bool isGeomModified = false;
+
+  if( myCurve->getSectionType(mySection) != aSectType ) {
+    myCurve->setSectionType( mySection, aSectType );
+    isGeomModified = true;
+  }
+
+  if( myCurve->isClosed(mySection) != isClosed ) {
+    myCurve->setClosed( mySection, isClosed );
+    isGeomModified = true;
+  }
   mySectionView->sectionChanged(mySection);
   updateUndoRedo();
   onCancelSection();
-}
 
-void CurveCreator_Widget::onEditPoint( int theSection, int thePoint )
-{
-  if( !myNewPointEditor || !myEdit )
-    return;
-  mySection = theSection;
-  myPointNum = thePoint;
-  QString aSectName = QString::fromStdString( myCurve->getSectionName(theSection));
-  myNewPointEditor->setEditMode(true);
-  myNewPointEditor->setSectionName(aSectName);
-  myNewPointEditor->setDimension( myCurve->getDimension() );
-  CurveCreator::Coordinates aCoords = myCurve->getCoordinates(theSection,thePoint);
-  myNewPointEditor->setCoordinates(aCoords);
-  emit subOperationStarted( myNewPointEditor );
-}
-
-void CurveCreator_Widget::onModifyPoint()
-{
-  if( !myEdit )
-    return;
-  CurveCreator::Coordinates aCoords = myNewPointEditor->getCoordinates();
-  myEdit->setCoordinates( aCoords, mySection, myPointNum );
-  mySectionView->pointDataChanged( mySection, myPointNum );
-  updateUndoRedo();
-  onCancelPoint();
+  emit curveModified();
 }
 
 void CurveCreator_Widget::onJoin()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
   QList<int> aSections = mySectionView->getSelectedSections();
   if( aSections.size() == 0 ){
     return;
   }
-  int aMainSect = aSections[0];
-  int aMainSectSize = myCurve->getNbPoints(aMainSect);
-  myEdit->startOperation();
-  for( int i = 1 ; i < aSections.size() ; i++ ){
-    int aSectNum = aSections[i] - (i-1);
-    myEdit->join( aMainSect, aSectNum );
-    mySectionView->sectionsRemoved( aSectNum );
+  stopActionMode();
+
+  std::list<int> aSectionsToJoin;
+  for( int i = 0; i < aSections.size() ; i++ ){
+    aSectionsToJoin.push_back( aSections[i] );
+  }
+  //int aMainSect = aSectionsToJoin.front();
+  //int aMainSectSize = myCurve->getNbPoints(aMainSect);
+  if ( myCurve->join( aSectionsToJoin ) )
+  {
+    std::list<int>::const_iterator anIt = aSectionsToJoin.begin(),
+                                   aLast = aSectionsToJoin.end();
+    // the first section should be skipped. It is not removed, but is modified
+    anIt++;
+    for ( ; anIt != aLast; anIt++ )
+      mySectionView->sectionsRemoved( *anIt );
   }
-  myEdit->finishOperation();
+
+  /* The update for the points of the main section
   int aNewSectSize = myCurve->getNbPoints(aMainSect);
   if( aNewSectSize != aMainSectSize )
-    mySectionView->pointsAdded( aMainSect, aMainSectSize, aNewSectSize-aMainSectSize );
+    mySectionView->pointsAdded( aMainSect, aMainSectSize, aNewSectSize-aMainSectSize );*/
   updateUndoRedo();
-}
 
-void CurveCreator_Widget::onRemove()
-{
-  if( !myEdit )
-    return;
-  QList< QPair<int,int> > aSelPoints = mySectionView->getSelectedPoints();
-  int aCurrSect=-1;
-  int aRemoveCnt = 0;
-  myEdit->startOperation();
-  for( int i = 0 ; i < aSelPoints.size() ; i++ ){
-    if( aCurrSect != aSelPoints[i].first ){
-      aRemoveCnt = 0;
-      aCurrSect = aSelPoints[i].first;
-    }
-    int aPntIndx = aSelPoints[i].second - aRemoveCnt;
-    myEdit->removePoints(aCurrSect,aPntIndx, 1);
-    mySectionView->pointsRemoved( aCurrSect, aPntIndx );
-    aRemoveCnt++;
-  }
-  QList<int> aSections = mySectionView->getSelectedSections();
-  for( int i = 0 ; i < aSections.size() ; i++ ){
-    int aSectNum = aSections[i] - (i);
-    myEdit->removeSection( aSectNum );
-    mySectionView->sectionsRemoved( aSectNum );
-  }
-  myEdit->finishOperation();
-  mySectionView->clearSelection();
-  updateUndoRedo();
+  emit curveModified();
 }
 
-void CurveCreator_Widget::onMoveUp()
+void CurveCreator_Widget::onRemove()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
-  if( mySectionView->getSelectionType() == CurveCreator_TreeView::ST_SECTIONS ){
-    //Move sections
-    QList<int> aSections = mySectionView->getSelectedSections();
-    for( int i = 0 ; i < aSections.size() ; i++ ){
-      int anIndx = aSections[i];
-      myEdit->moveSection( anIndx, anIndx-1);
-      mySectionView->sectionsSwapped( anIndx, -1 );
-    }
-  }
-  else{
-    //Move points
-    QList< QPair<int,int> > aPoints = mySectionView->getSelectedPoints();
-    for( int i = 0 ; i < aPoints.size() ; i++ ){
-      int aSection = aPoints[i].first;
-      int aPoint = aPoints[i].second;
-      myEdit->movePoint(aSection, aPoint, aPoint-2);
-      mySectionView->pointsSwapped( aSection, aPoint, -1 );
-    }
-  }
-  updateUndoRedo();
-}
 
-void CurveCreator_Widget::onMoveDown()
-{
-  if( !myEdit )
-    return;
-  if( mySectionView->getSelectionType() == CurveCreator_TreeView::ST_SECTIONS ){
-    //Move sections
-    QList<int> aSections = mySectionView->getSelectedSections();
-    for( int i = aSections.size()-1 ; i >=0 ; i-- ){
-      int anIndx = aSections[i];
-      myEdit->moveSection( anIndx, anIndx+1);
-      mySectionView->sectionsSwapped( anIndx, 1 );
-    }
-  }
-  else{
-    //Move points
-    QList< QPair<int,int> > aPoints = mySectionView->getSelectedPoints();
-    for( int i = aPoints.size() - 1; i >= 0 ; i--  ){
-      int aSection = aPoints[i].first;
-      int aPoint = aPoints[i].second;
-      myEdit->movePoint(aSection, aPoint, aPoint+1);
-      mySectionView->pointsSwapped( aSection, aPoint, 1 );
-    }
+  switch( getActionMode() ) {
+    case NoneMode:
+      removeSection();
+    break;
+    case ModificationMode:
+      removePoint();
+    break;
+    default:
+      break;
   }
-  updateUndoRedo();
 }
 
 void CurveCreator_Widget::onClearAll()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
-  myEdit->clear();
+  stopActionMode();
+  myCurve->clear();
   mySectionView->reset();
-  onSelectionChanged();
+  updateActionsStates();
   updateUndoRedo();
+  
+  emit curveModified();
 }
 
 void CurveCreator_Widget::onJoinAll()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
-  myEdit->join();
-  mySectionView->reset();
-  onSelectionChanged();
-  updateUndoRedo();
-}
+  stopActionMode();
 
-void CurveCreator_Widget::onInsertSectionBefore()
-{
-
-}
-
-void CurveCreator_Widget::onInsertSectionAfter()
-{
-
-}
-
-void CurveCreator_Widget::onInsertPointBefore()
-{
-
-}
+  std::list<int> aSectionsToJoin;
+  for( int i = 0, aNb = myCurve->getNbSections(); i < aNb ; i++ ){
+    aSectionsToJoin.push_back( i );
+  }
+  bool aRes = myCurve->join( aSectionsToJoin );
 
-void CurveCreator_Widget::onInsertPointAfter()
-{
+  mySectionView->reset();
+  updateActionsStates();
+  updateUndoRedo();
 
+  emit curveModified();
 }
 
 void CurveCreator_Widget::onUndoSettings()
@@ -719,104 +713,119 @@ void CurveCreator_Widget::onUndoSettings()
 
 void CurveCreator_Widget::onSetSpline()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
+  stopActionMode();
   QList<int> aSelSections = mySectionView->getSelectedSections();
-  myEdit->startOperation();
   for( int i = 0 ; i < aSelSections.size() ; i++ ){
-    myEdit->setType(CurveCreator::BSpline, aSelSections[i]);
+    myCurve->setSectionType(aSelSections[i], CurveCreator::Spline );
     mySectionView->sectionChanged(aSelSections[i]);
   }
-  myEdit->finishOperation();
   updateUndoRedo();
+
+  emit curveModified();
 }
 
 void CurveCreator_Widget::onSetPolyline()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
-  myEdit->startOperation();
+  stopActionMode();
   QList<int> aSelSections = mySectionView->getSelectedSections();
   for( int i = 0 ; i < aSelSections.size() ; i++ ){
-    myEdit->setType(CurveCreator::Polyline, aSelSections[i]);
-    mySectionView->sectionChanged(aSelSections[i]);
+    myCurve->setSectionType( aSelSections[i], CurveCreator::Polyline );
+    mySectionView->sectionChanged( aSelSections[i] );
   }
-  myEdit->finishOperation();
   updateUndoRedo();
+
+  emit curveModified();
 }
 
 void CurveCreator_Widget::onCloseSections()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
-  myEdit->startOperation();
+  stopActionMode();
   QList<int> aSelSections = mySectionView->getSelectedSections();
   for( int i = 0 ; i < aSelSections.size() ; i++ ){
-    myEdit->setClosed(true, aSelSections[i]);
+    myCurve->setClosed(aSelSections[i], true);
     mySectionView->sectionChanged(aSelSections[i]);
   }
-  myEdit->finishOperation();
   updateUndoRedo();
+
+  emit curveModified();
 }
 
 void CurveCreator_Widget::onUncloseSections()
 {
-  if( !myEdit )
+  if( !myCurve )
     return;
-  myEdit->startOperation();
+  stopActionMode();
   QList<int> aSelSections = mySectionView->getSelectedSections();
   for( int i = 0 ; i < aSelSections.size() ; i++ ){
-    myEdit->setClosed(false, aSelSections[i]);
+    myCurve->setClosed(aSelSections[i], false);
     mySectionView->sectionChanged(aSelSections[i]);
   }
-  myEdit->finishOperation();
   updateUndoRedo();
+
+  emit curveModified();
 }
 
 void CurveCreator_Widget::onUndo()
 {
-    if( !myEdit )
-      return;
-    myEdit->undo();
-    mySectionView->reset();
-    updateUndoRedo();
+  if( !myCurve )
+    return;
+
+  CurveCreator_ICurve::SectionToPointList aPoints;
+  startCurveModification( aPoints, false );
+  myCurve->undo();
+  finishCurveModification();
+  mySectionView->reset();
+
+  emit curveModified();
 }
 
 void CurveCreator_Widget::onRedo()
 {
-    if( !myEdit )
-      return;
-    myEdit->redo();
-    mySectionView->reset();
-    updateUndoRedo();
+  if( !myCurve )
+    return;
+  CurveCreator_ICurve::SectionToPointList aPoints;
+  startCurveModification( aPoints, false );
+  myCurve->redo();
+  finishCurveModification();
+  mySectionView->reset();
+
+  emit curveModified();
 }
 
 void CurveCreator_Widget::updateUndoRedo()
 {
-    QAction* anAct = myActionMap[UNDO_ID];
-    if( anAct != 0 ){
-        if( myEdit->getNbUndo() != 0 ){
-            anAct->setEnabled(true);
-        }
-        else{
-            anAct->setDisabled(true);
-        }
+  if( !myCurve )
+    return;
+  QAction* anAct = myActionMap[UNDO_ID];
+  if( anAct != 0 ){
+    if( myCurve->getNbUndo() != 0 ){
+      anAct->setEnabled(true);
     }
-    anAct = myActionMap[REDO_ID];
-    if( anAct != 0 ){
-        if( myEdit->getNbRedo() != 0 ){
-            anAct->setEnabled(true);
-        }
-        else{
-            anAct->setDisabled(true);
-        }
+    else{
+      anAct->setDisabled(true);
+    }
+  }
+  anAct = myActionMap[REDO_ID];
+  if( anAct != 0 ){
+    if( myCurve->getNbRedo() != 0 ){
+      anAct->setEnabled(true);
     }
+    else{
+      anAct->setDisabled(true);
+    }
+  }
 }
 
 void CurveCreator_Widget::onContextMenu( QPoint thePoint )
 {
   QList<ActionId> aContextActions;
-  aContextActions << CLEAR_ALL_ID << JOIN_ALL_ID << SEPARATOR_ID <<
+  aContextActions << CLEAR_ALL_ID << JOIN_ID << JOIN_ALL_ID << SEPARATOR_ID <<
                      CLOSE_SECTIONS_ID << UNCLOSE_SECTIONS_ID << SET_SECTIONS_POLYLINE_ID <<
                      SET_SECTIONS_SPLINE_ID;
   QPoint aGlPoint = mySectionView->mapToGlobal(thePoint);
@@ -857,35 +866,111 @@ QList<int> CurveCreator_Widget::getSelectedSections()
   return mySectionView->getSelectedSections();
 }
 
-QList< QPair< int, int > > CurveCreator_Widget::getSelectedPoints()
+void CurveCreator_Widget::setSelectedSections( const QList<int>& theSections )
 {
-  return mySectionView->getSelectedPoints();
+  mySectionView->setSelectedSections( theSections );
+  updateActionsStates();
+  updateUndoRedo();
 }
 
-bool CurveCreator_Widget::isInstantSketchingEnabled() const
+/**
+ * According to the widget state, performs the remove action
+ */
+void CurveCreator_Widget::removeSelected()
 {
-  if( myNewPointEditor )
-    return myNewPointEditor->isInstantSketchingEnabled();
-  return false;
+  onRemove();
 }
 
-void CurveCreator_Widget::setInstantSketchingEnabled( const bool theState )
+/**
+ * Checks whether there are some selection to be removed
+ */
+bool CurveCreator_Widget::removeEnabled()
 {
-  if( myNewPointEditor )
-    myNewPointEditor->setInstantSketchingEnabled( theState );
+  bool isEnabled = getActionMode() == ModificationMode;
+  if ( !isEnabled ) {
+    QList<int> aSelSections = mySectionView->getSelectedSections();
+    CurveCreator_TreeView::SelectionType aSelType = mySectionView->getSelectionType();
+    isEnabled = aSelType == CurveCreator_TreeView::ST_SECTIONS &&
+                aSelSections.size() == 1;
+  }
+  return isEnabled;
+}
+
+void CurveCreator_Widget::setActionMode( const ActionMode& theMode )
+{
+  ActionMode aPrevMode = getActionMode();
+  QAction* aPrevAction = getAction( aPrevMode );
+  QAction* anAction = getAction( theMode );
+  switch ( theMode ) {
+    case NoneMode:
+    case AdditionMode: {
+      if ( aPrevAction ) {
+        if ( aPrevAction->isChecked() ) {
+          aPrevAction->setChecked( false );
+        }
+      }
+      if ( aPrevMode == ModificationMode )
+        onModificationMode( false );
+      if ( aPrevMode == AdditionMode )
+        onAdditionMode( false );
+
+      if ( theMode == AdditionMode )
+      {
+        anAction->setChecked( true );
+        onModeChanged( true );
+      }
+    }
+    break;
+    break;
+    case ModificationMode:
+    {
+      //TODO
+    }
+    break;
+    case DetectionMode:
+      break;
+  }
+}
+
+CurveCreator_Widget::ActionMode CurveCreator_Widget::getActionMode() const
+{
+  ActionMode aMode = NoneMode;
+
+  if ( myActionMap[ADDITION_MODE_ID]->isChecked() )
+    aMode = AdditionMode;
+  else if ( myActionMap[MODIFICATION_MODE_ID]->isChecked() )
+    aMode = ModificationMode;
+  else if ( myActionMap[DETECTION_MODE_ID]->isChecked() )
+    aMode = DetectionMode;
+
+  return aMode;
+}
+
+void CurveCreator_Widget::SetViewer2DMode(const bool To2D)
+{
+  if (myOCCViewer) {
+    if (To2D) {
+      myOld2DMode = OCCViewer_Utilities::setViewer2DMode
+                    (myOCCViewer, OCCViewer_ViewWindow::XYPlane);
+    } else {
+      OCCViewer_Utilities::setViewer2DMode(myOCCViewer, myOld2DMode);
+    }
+  }
 }
 
 //=================================================================================
-// function : GeometryGUI::onGetPointByClick()
+// function : GeometryGUI::addCoordsByClick()
 // purpose  : Manage mouse press events in Additon mode
 //=================================================================================
-void CurveCreator_Widget::onGetPointByClick( SUIT_ViewWindow* theViewWindow, QMouseEvent* pe )
+void CurveCreator_Widget::addCoordsByClick( QMouseEvent* pe )
 {
-  if ( myNewPointEditor && theViewWindow->getViewManager()->getType() == OCCViewer_Viewer::Type() &&
-       pe->modifiers() != Qt::ControlModifier ) {
-    OCCViewer_Viewer* anOCCViewer =
-      ( (OCCViewer_ViewManager*)( theViewWindow->getViewManager() ) )->getOCCViewer();
-    Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
+  if (pe->button() != Qt::LeftButton)
+    return;
+
+  if ( pe->modifiers() != Qt::ControlModifier ) {
+    Handle(AIS_InteractiveContext) ic = getAISContext();
+    if ( ic.IsNull() )
+      return;
 
     gp_Pnt aPnt;    
 
@@ -895,18 +980,9 @@ void CurveCreator_Widget::onGetPointByClick( SUIT_ViewWindow* theViewWindow, QMo
     else
       ic->Select();       // New selection
 
-    /*TopoDS_Shape aShape;
-
-    ic->InitSelected();
-    if ( ic->MoreSelected() )
-      aShape = ic->SelectedShape();
-
-    if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
-      aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) );
-    else*/
     {
-      OCCViewer_ViewPort3d* vp =  ((OCCViewer_ViewWindow*)theViewWindow)->getViewPort();
-      aPnt = GEOMUtils::ConvertClickToPoint( pe->x(), pe->y(), vp->getView() );
+      OCCViewer_ViewPort3d* vp = getViewPort();
+      aPnt = CurveCreator_Utils::ConvertClickToPoint( pe->x(), pe->y(), vp->getView() );
     }
     // set the coordinates into dialog
     CurveCreator::Coordinates aCoords;
@@ -915,28 +991,522 @@ void CurveCreator_Widget::onGetPointByClick( SUIT_ViewWindow* theViewWindow, QMo
     if ( myCurve->getDimension() == 3 ) {
       aCoords.push_back( aPnt.Z() );
     }
-    onAddNewPoint(aCoords);
-//    myNewPointEditor->setCoordinates( aCoords );
+    addNewPoint(aCoords);
   }
 }
 
-//=================================================================================
-// function : GeometryGUI::onPointDrag()
-// purpose  : Manage mouse move events in Modification mode
-//=================================================================================
-void CurveCreator_Widget::onPointDrag( SUIT_ViewWindow* theViewWindow, QMouseEvent* pe )
+/**
+ * Manage mouse press events
+ * \param theWindow an owner of the signal
+ * \param theEvent a mouse event
+ */
+void CurveCreator_Widget::onMousePress( SUIT_ViewWindow*, QMouseEvent* theEvent )
 {
-  if ( !(pe->buttons() & Qt::LeftButton) )
+  if ( theEvent->button() != Qt::LeftButton )
     return;
-  if ( (pe->pos() - myDragStartPosition).manhattanLength() < QApplication::startDragDistance() )
+
+  myPressedX = theEvent->x();
+  myPressedY = theEvent->y();
+
+  switch( getActionMode() ) {
+    case ModificationMode: {
+      //store initial cursor position for Drag&Drop
+      setDragStarted( true, theEvent->pos() );
+      break;
+    }
+    case AdditionMode: {
+      addCoordsByClick( theEvent );
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+/**
+ * Manage mouse release events in Modification mode
+ * \param theWindow an owner of the signal
+ * \param theEvent a mouse event
+ */
+void CurveCreator_Widget::onMouseRelease( SUIT_ViewWindow*, QMouseEvent* theEvent )
+{
+  if ( getActionMode() != ModificationMode )
     return;
-/*  
-  QDrag *drag = new QDrag(this);
-  QMimeData *mimeData = new QMimeData;
-  
-  mimeData->setData(mimeType, data);
-  drag->setMimeData(mimeData);
-  
-  Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);
-  */
+
+  if ( myDragStarted ) {
+    bool isDragged = myDragged;
+    CurveCreator_ICurve::SectionToPointList aDraggedPoints;
+    QMap<CurveCreator_ICurve::SectionToPoint, std::deque< float > > anInitialDragPointsCoords;
+    if ( myDragged ) {
+      aDraggedPoints = myDragPoints;
+      anInitialDragPointsCoords = myInitialDragPointsCoords;
+    }
+
+    setDragStarted( false );
+
+    if ( aDraggedPoints.size() > 0 ) {
+      // Collect old coordinates of the dragged points
+      CurveCreator_ICurve::SectionToPointCoordsList anOldPoints;
+      foreach ( const CurveCreator_ICurve::SectionToPoint aSectionToPoint, anInitialDragPointsCoords.keys() ) {
+        CurveCreator::Coordinates aCoords = anInitialDragPointsCoords.value( aSectionToPoint );
+        anOldPoints.push_back( std::make_pair( aSectionToPoint, aCoords ) );
+      }
+
+      if ( myCurve->canPointsBeSorted() ) {
+        // Add old coordinates of the curve points (except the dragged points) to the list
+        for( int aSectionId = 0 ; aSectionId < myCurve->getNbSections() ; aSectionId++ ) {
+          CurveCreator::Coordinates aCoords;
+          for ( int aPointId = 0, aNb = myCurve->getNbPoints( aSectionId ); aPointId < aNb; aPointId++ ) {
+            aCoords = myCurve->getPoint( aSectionId, aPointId );
+            if ( aCoords.size() < 2 ) {
+              continue;
+            }
+            
+            CurveCreator_ICurve::SectionToPoint aSectionToPoint = std::make_pair( aSectionId, aPointId );
+
+            if ( !anInitialDragPointsCoords.contains( aSectionToPoint ) ) {
+              anOldPoints.push_back( std::make_pair( aSectionToPoint, aCoords ) );
+            }
+          }
+        }
+        
+        // Apply points sorting
+        CurveCreator_ICurve::SectionToPointList aPoints;
+        startCurveModification( aPoints, false );
+
+        myCurve->setSkipSorting( false );
+
+        CurveCreator_ICurve::SectionToPointCoordsList aCoordList;
+        CurveCreator_ICurve::SectionToPointList::const_iterator anIt = aDraggedPoints.begin(),
+                                                                aLast = aDraggedPoints.end();
+        for ( ; anIt != aLast; anIt++ ) {
+          int aSectionId = anIt->first;
+          int aPointId = anIt->second;
+          std::deque<float> aPos = myCurve->getPoint( aSectionId, aPointId );
+
+          aCoordList.push_back(
+            std::make_pair( std::make_pair( aSectionId, aPointId ), aPos ) );
+        }
+
+        myCurve->setSeveralPoints( aCoordList, false );
+    
+        finishCurveModification( aDraggedPoints );
+      } else {
+        // if the drag of some points has happened, restore the drag selection
+        START_MEASURE_TIME;
+        setSelectedPoints( aDraggedPoints );
+        END_MEASURE_TIME( "drop" );
+      }
+
+      // Save drag difference
+      myCurve->saveCoordDiff( anOldPoints );
+    }
+  }
+  else // check whether the segment is clicked an a new point should be added to the segment
+  {
+    int aReleasedX = theEvent->x();
+    int aReleasedY = theEvent->y();
+    if ( myPressedX == aReleasedX && myPressedY == aReleasedY )
+      insertPointToSelectedSegment( aReleasedX, aReleasedY );
+  }
+
+  // updates the input panel table to show the selected point coordinates
+  updateLocalPointView();
+  updateUndoRedo();
+
+  emit curveModified();
+}
+
+/**
+ * Manage mouse move events in Modification mode
+ * \param theWindow an owner of the signal
+ * \param theEvent a mouse event
+ */
+void CurveCreator_Widget::onMouseMove( SUIT_ViewWindow*, QMouseEvent* theEvent )
+{
+  if ( getActionMode() != ModificationMode || !myDragStarted )
+    return;
+
+  QPoint aPos = theEvent->pos();
+  if ( (aPos - myDragStartPosition).manhattanLength() < QApplication::startDragDistance() )
+    return;
+
+  START_MEASURE_TIME;
+
+  moveSelectedPoints( aPos.x(), aPos.y() );
+  myDragStartPosition = aPos;
+
+  END_MEASURE_TIME( "drag" );
+}
+
+/**
+ * Set zero viewer by the last view closed in
+ * \param theManager a viewer manager
+ */
+void CurveCreator_Widget::onLastViewClosed( SUIT_ViewManager* theManager )
+{
+  myOCCViewer = 0;
+}
+
+void CurveCreator_Widget::onMousePress( QMouseEvent* theEvent )
+{
+  onMousePress( 0, theEvent );
+}
+
+void CurveCreator_Widget::onMouseRelease( QMouseEvent* theEvent )
+{
+  onMouseRelease( 0, theEvent );
+}
+
+void CurveCreator_Widget::onMouseMove( QMouseEvent* theEvent )
+{
+  onMouseMove( 0, theEvent );
+}
+
+void CurveCreator_Widget::onCellChanged( int theRow, int theColumn )
+{
+  int aCurrSect = myLocalPointView->getSectionId( theRow );
+  int aPntIndex = myLocalPointView->getPointId( theRow );
+
+  if ( aPntIndex < 0 )
+    return;
+
+  CurveCreator_ICurve::SectionToPointList aSelPoints;
+  startCurveModification( aSelPoints );
+
+  double aX  = myLocalPointView->item( theRow, 2 )->data( Qt::UserRole ).toDouble();
+  double anY = myLocalPointView->item( theRow, 3 )->data( Qt::UserRole ).toDouble();
+  std::deque<float> aChangedPos;
+  aChangedPos.push_back( aX );
+  aChangedPos.push_back( anY );
+  myCurve->setPoint( aCurrSect, aPntIndex, aChangedPos );
+
+  finishCurveModification( aSelPoints );
+
+  emit curveModified();
+}
+
+/**
+ * Removes a selected section from the curve. Updates undo/redo status
+ */
+void CurveCreator_Widget::removeSection()
+{
+  stopActionMode();
+
+  QList<int> aSections = mySectionView->getSelectedSections();
+  for( int i = 0 ; i < aSections.size() ; i++ ){
+    int aSectNum = aSections[i] - (i);
+    myCurve->removeSection( aSectNum );
+    mySectionView->sectionsRemoved( aSectNum );
+  }
+  mySectionView->clearSelection();
+  updateUndoRedo();
+
+  emit curveModified();
+}
+
+/**
+ * Removes a selected points from the curve. Updates undo/redo status
+ */
+void CurveCreator_Widget::removePoint()
+{
+  CurveCreator_ICurve::SectionToPointList aPoints;
+  getSelectedPoints( aPoints );
+  if ( aPoints.size() == 0 )
+    return;
+
+  CurveCreator_ICurve::SectionToPointList aSelPoints;
+  startCurveModification( aSelPoints, false );
+
+  myCurve->removeSeveralPoints( aPoints );
+  finishCurveModification( CurveCreator_ICurve::SectionToPointList() );
+  mySectionView->reset();
+
+  emit curveModified();
+}
+
+void CurveCreator_Widget::addNewPoint(const CurveCreator::Coordinates& theCoords)
+{
+  if( !myCurve )
+    return;
+  QList<int> aSections = mySectionView->getSelectedSections();
+  if( aSections.size() == 0 ){
+    return;
+  }
+  int aSection = aSections[0];
+  myCurve->addPoints(theCoords, aSection); // add to the end of section
+  mySectionView->pointsAdded( aSection, myCurve->getNbPoints( aSection ) );
+  updateActionsStates();
+  updateUndoRedo();
+
+  emit curveModified();
+}
+
+void CurveCreator_Widget::insertPointToSelectedSegment( const int theX,
+                                                        const int theY )
+{
+  Handle(AIS_InteractiveContext) aContext = getAISContext();
+
+  OCCViewer_ViewPort3d* aViewPort = getViewPort();
+  Handle(V3d_View) aView;
+  if ( aViewPort )
+    aView = aViewPort->getView();
+
+  if ( aContext.IsNull() || aView.IsNull() )
+    return;
+  gp_Pnt aPoint;
+  gp_Pnt aPoint1, aPoint2;
+  Handle(AIS_InteractiveObject) anAISObject = myCurve->getAISObject();
+  bool isFoundPoint = CurveCreator_Utils::pointOnObject( aView, anAISObject, theX, theY,
+                                                         aPoint, aPoint1, aPoint2 );
+  if ( !isFoundPoint )
+    return;
+
+  // insert the point to the model curve
+  CurveCreator_ICurve::SectionToPointList aSelPoints;
+  startCurveModification( aSelPoints );
+
+  CurveCreator::Coordinates aCoords;
+  aCoords.push_back( aPoint.X() );
+  aCoords.push_back( aPoint.Y() );
+
+  CurveCreator_ICurve::SectionToPointList aPoints1, aPoints2;
+  findSectionsToPoints( aPoint1.X(), aPoint1.Y(), aPoints1 );
+  findSectionsToPoints( aPoint2.X(), aPoint2.Y(), aPoints2 );
+  CurveCreator_ICurve::SectionToPointList::const_iterator anIt = aPoints1.begin(),
+                                                          aLast = aPoints1.end();
+  int aSectionId = -1;
+  // find the indices of the neighbour point
+  // there can be a case when a new point is added into two sections
+  int aPoint1Id = -1, aPoint2Id = -1;
+  for ( ; anIt != aLast && aSectionId < 0; anIt++ ) {
+    int aSectionCur = anIt->first;
+    CurveCreator_ICurve::SectionToPointList::const_iterator anIt2 = aPoints2.begin(),
+                                                            aLast2 = aPoints2.end();
+    for ( ; anIt2 != aLast2 && aSectionId < 0; anIt2++ ) {
+      if ( anIt2->first == aSectionCur ) {
+        aSectionId = aSectionCur;
+        aPoint1Id = anIt->second;
+        aPoint2Id = anIt2->second;
+      }
+    }
+  }
+
+  int anInsertPos = -1;
+  int aLastPoint = myCurve->getNbPoints( aSectionId )-1; 
+  if ( ( aPoint1Id == aLastPoint && aPoint2Id == 0 ) ||
+       ( aPoint2Id == aLastPoint && aPoint1Id == 0 ) )
+    anInsertPos = -1; // if the section happens between first and last points
+  else
+    anInsertPos = aPoint1Id < aPoint2Id ? aPoint1Id + 1 : aPoint2Id + 1;
+
+  myCurve->addPoints( aCoords, aSectionId, anInsertPos );
+  mySectionView->pointsAdded( aSectionId, myCurve->getNbPoints( aSectionId ) );
+
+  finishCurveModification( aSelPoints );
+
+  setSelectedPoints();
+
+  emit curveModified();
+}
+
+void CurveCreator_Widget::moveSelectedPoints( const int theXPosition,
+                                              const int theYPosition )
+{
+  OCCViewer_ViewPort3d* aViewPort = getViewPort();
+  if ( !aViewPort )
+    return;
+
+  CurveCreator_ICurve::SectionToPointList aPoints;
+  startCurveModification( aPoints, false );
+
+  gp_Pnt aStartPnt = CurveCreator_Utils::ConvertClickToPoint( myDragStartPosition.x(),
+                                                              myDragStartPosition.y(),
+                                                              aViewPort->getView() );
+  gp_Pnt anEndPnt = CurveCreator_Utils::ConvertClickToPoint( theXPosition, theYPosition,
+                                                             aViewPort->getView() );
+  double aXDelta = aStartPnt.X() - anEndPnt.X();
+  double anYDelta = aStartPnt.Y() - anEndPnt.Y();
+
+  CurveCreator_ICurve::SectionToPointCoordsList aCoordList;
+  std::deque<float> aChangedPos;
+  CurveCreator_ICurve::SectionToPointList::const_iterator anIt = myDragPoints.begin(),
+                                                          aLast = myDragPoints.end();
+  for ( ; anIt != aLast; anIt++ ) {
+    int aSectionId = anIt->first;
+    int aPointId = anIt->second;
+    aChangedPos = myCurve->getPoint( aSectionId, aPointId );
+    if ( aChangedPos.size() < 2 )
+      continue;
+
+    // Remember drag points coordinates
+    if ( !myDragged ) {
+      myInitialDragPointsCoords.insert( std::make_pair( aSectionId, aPointId ), aChangedPos );
+    }
+
+    aChangedPos[0] = aChangedPos[0] - aXDelta;
+    aChangedPos[1] = aChangedPos[1] - anYDelta;
+    
+    aCoordList.push_back(
+      std::make_pair(std::make_pair( aSectionId, aPointId ), 
+                     aChangedPos ));
+  }
+  myCurve->setSeveralPoints( aCoordList, false );
+
+  myDragged = true;
+  finishCurveModification( myDragPoints );
+
+  emit curveModified();
+}
+
+void CurveCreator_Widget::updateLocalPointView()
+{
+  if ( myDragStarted )
+    return;
+  Handle(AIS_InteractiveContext) aContext = getAISContext();
+  if ( aContext.IsNull() )
+    return;
+
+  CurveCreator_Utils::getSelectedPoints( aContext, myCurve, myLocalPoints );
+  int aNbPoints = myLocalPoints.size();
+
+  bool isRowLimit = aNbPoints > myLocalPointRowLimit;
+  myLocalPointView->setVisible( getActionMode() == ModificationMode && !isRowLimit );
+
+  if ( !isRowLimit ) {
+    bool isBlocked = myLocalPointView->blockSignals(true);
+
+    myLocalPointView->setLocalPointsToTable( myLocalPoints );
+
+    myLocalPointView->blockSignals( isBlocked );
+  }
+}
+
+/**
+ * 
+ */
+void CurveCreator_Widget::setLocalPointContext( const bool theOpen, const bool isUpdateTable )
+{
+  CurveCreator_Utils::setLocalPointContext( myCurve, getAISContext(), theOpen );
+  if ( !theOpen && isUpdateTable )
+    updateLocalPointView();
+}
+
+/**
+ * Set drag operation started. Save the position and a list of dragged points
+ * \param theState the drag operation state: started/finished
+ * \param thePoint the start drag position
+ */
+void CurveCreator_Widget::setDragStarted( const bool theState, const QPoint& thePoint )
+{
+  if ( theState ) {
+    getSelectedPoints( myDragPoints );
+
+    myDragStarted = myDragPoints.size();
+    myDragStartPosition = thePoint;
+    if ( myDragStarted ) {
+      // change a viewer interaction style in order to avoid a select rectangle build
+      myDragInteractionStyle = changeInteractionStyle( SUIT_ViewModel::KEY_FREE );
+      myCurve->setSkipSorting( true );
+    }
+  }
+  else {
+    if ( myDragStarted )
+      changeInteractionStyle( myDragInteractionStyle );
+    myDragStarted = false;
+    myDragPoints.clear();
+    myInitialDragPointsCoords.clear();
+  }
+  myDragged = false;
+}
+
+void CurveCreator_Widget::getSelectedPoints( CurveCreator_ICurve::SectionToPointList& thePoints )
+{
+  thePoints.clear();
+  thePoints = myLocalPoints;
+}
+
+void CurveCreator_Widget::setSelectedPoints( const CurveCreator_ICurve::SectionToPointList& thePoints )
+{
+  if ( myDragStarted )
+    return;
+  Handle(AIS_InteractiveContext) aContext = getAISContext();
+  if ( aContext.IsNull() || !aContext->HasOpenedContext() )
+    return;
+
+  CurveCreator_Utils::setSelectedPoints( aContext, myCurve, thePoints );
+
+  updateLocalPointView();
+}
+
+void CurveCreator_Widget::stopActionMode()
+{
+  setActionMode( NoneMode );
+}
+
+/**
+ * Get viewer information before perform the curve modification.
+ * Take a list of selected cuve points an close local context.
+ * The context should be closed because the curve presentation is
+ * redisplayed and if it is not closed, when we close the local context
+ * later, the presentation shown in the local context is disappeared.
+ * \param thePoints an output list of curve selected points
+ * \param theFillPoints a flag whether the selection list should be filled
+ */
+void CurveCreator_Widget::startCurveModification(
+                           CurveCreator_ICurve::SectionToPointList& thePoints,
+                           const bool theFillPoints )
+{
+  if ( theFillPoints ) {
+    thePoints.clear();
+    getSelectedPoints( thePoints );
+  }
+  setLocalPointContext( false );
+}
+
+/**
+ * Restore the viewer state after the curve modification is done.
+ * Open local context and select given points inside it.
+ * \param thePoints a list of curve selected points
+ */
+void CurveCreator_Widget::finishCurveModification(
+                           const CurveCreator_ICurve::SectionToPointList& thePoints )
+{
+  if ( getActionMode() == ModificationMode )
+    setLocalPointContext( true );
+  setSelectedPoints( thePoints );
+  updateUndoRedo();
+}
+
+/**
+ * Returns a point index in the model curve by the point coordinates in the viewer
+ * \param theX the X coordinate of the point
+ * \param theY the Y coordinate of the point
+ */
+int CurveCreator_Widget::findLocalPointIndex( int theSectionId, float theX, float theY )
+{
+  return CurveCreator_UtilsICurve::findLocalPointIndex( myCurve, theSectionId, theX, theY );
+}
+
+void CurveCreator_Widget::findSectionsToPoints( const double theX, const double theY,
+                                 CurveCreator_ICurve::SectionToPointList& thePoints )
+{
+  return CurveCreator_UtilsICurve::findSectionsToPoints( myCurve, theX, theY, thePoints );
+}
+
+void CurveCreator_Widget::convert( const CurveCreator_ICurve::SectionToPointList& thePoints,
+                                   QMap<int, QList<int> >& theConvPoints )
+{
+  return CurveCreator_UtilsICurve::convert( thePoints, theConvPoints );
+}
+
+/**
+ * Returns whethe the container has the value
+ * \param theList a container of values
+ * \param theValue a value
+ */
+bool CurveCreator_Widget::contains( const CurveCreator_ICurve::SectionToPointList& theList,
+                                    const CurveCreator_ICurve::SectionToPoint& theValue ) const
+{
+  return CurveCreator_UtilsICurve::contains( theList, theValue );
 }
index 7f335e8dbbead8007badae375b3473458b09729c..e15e923095278f82b0756cbf83d4aef6ed9078f9 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2013-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
+// version 2.1 of the License.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 #ifndef CURVECREATOR_WIDGET_H
 #define CURVECREATOR_WIDGET_H
 
-#include "CurveCreator_Curve.hxx"
+#include "CurveCreator_Macro.hxx"
 #include "CurveCreator.hxx"
+#include "CurveCreator_ICurve.hxx"
 
 #include <QWidget>
 #include <QMap>
 
+#include <OCCViewer_ViewWindow.h>
 #include <SUIT_ViewWindow.h>
+#include <AIS_InteractiveObject.hxx>
+#include <AIS_InteractiveContext.hxx>
+
+#include <Geom_Curve.hxx>
+#include <V3d_View.hxx>
+#include <gp_Pnt.hxx>
+#include <TopoDS_Vertex.hxx> // TODO - remove
+
+class OCCViewer_Viewer;
+class OCCViewer_ViewPort3d;
+
+class AIS_ListOfInteractive;
 
 class QAction;
 class QPixmap;
-class CurveCreator_CurveEditor;
+class CurveCreator_TableView;
 class CurveCreator_TreeView;
-class CurveCreator_NewPointDlg;
 class CurveCreator_NewSectionDlg;
 
 class CURVECREATOR_EXPORT CurveCreator_Widget : public QWidget
 {
-    Q_OBJECT
+  Q_OBJECT
+
+public:
+  enum ActionFlags {
+    NoFlags              = 0x00000000,
+    DisableDetectionMode = 0x00000001,
+    DisableNewSection    = 0x00000002,
+    DisableClosedSection = 0x00000004
+  };
+
+  enum ActionMode {
+    NoneMode,
+    AdditionMode,
+    ModificationMode,
+    DetectionMode
+  };
+
 public:
-    explicit CurveCreator_Widget( QWidget* parent,
-                      CurveCreator_Curve *theCurve,
-                      Qt::WindowFlags fl=0 );
+  explicit CurveCreator_Widget( QWidget* parent,
+                                CurveCreator_ICurve *theCurve,
+                                const int theActionFlags = NoFlags,
+                                const QStringList& theCoordTitles = QStringList(),
+                                Qt::WindowFlags fl=0,
+                                int theLocalPointRowLimit = 20);
 
-    void setCurve( CurveCreator_Curve* theCurve );
+  // OCC viewer manipulation
+  void setOCCViewer( OCCViewer_Viewer* theViewer );
 
-    QList<int> getSelectedSections();
-    QList< QPair< int, int > > getSelectedPoints();
+  Handle(AIS_InteractiveContext) getAISContext();
+  OCCViewer_ViewPort3d* getViewPort();
+  int changeInteractionStyle( int theStyle );
 
-    bool isInstantSketchingEnabled() const;
-    void setInstantSketchingEnabled( const bool theState );
+  void reset();
+  void setCurve( CurveCreator_ICurve* theCurve );
+
+  QList<int> getSelectedSections();
+  void setSelectedSections( const QList<int>& theSections );
+
+  void  removeSelected();
+  bool  removeEnabled();
+
+  void setActionMode( const ActionMode& theMode );
+  ActionMode getActionMode() const;
+
+  void SetViewer2DMode(const bool To2D);
 
 signals:
-    void selectionChanged();
-    void subOperationStarted( QWidget* );
-    void subOperationFinished( QWidget* );
+  void selectionChanged();
+  void subOperationStarted( QWidget*, bool );
+  void subOperationFinished( QWidget* );
+  void curveModified();
 
 public slots:
 
 protected slots:
-    void     onAdditionMode(bool checked);
-    void     onModificationMode(bool checked);
-    void     onDetectPoints(bool checked);
-    void     onModeChanged(bool checked);
-    void     onNewSection();
-    void     onSelectionChanged();
-    void     onAddNewPoint(const CurveCreator::Coordinates& theCoords);
-    void     onAddNewSection();
-    void     onEditSection( int theSection );
-    void     onEditPoint( int theSection, int thePoint );
-    void     onModifyPoint();
-    void     onModifySection();
-    void     onCancelPoint();
-    void     onCancelSection();
-    void     onJoin();
-    void     onRemove();
-    void     onMoveUp();
-    void     onMoveDown();
-    void     onClearAll();
-    void     onJoinAll();
-    void     onInsertSectionBefore();
-    void     onInsertSectionAfter();
-    void     onSetSpline();
-    void     onSetPolyline();
-    void     onCloseSections();
-    void     onUncloseSections();
-    void     onInsertPointBefore();
-    void     onInsertPointAfter();
-    void     onUndo();
-    void     onRedo();
-    void     onUndoSettings();
-    void     onContextMenu(QPoint thePoint);
-    void     onGetPointByClick( SUIT_ViewWindow*, QMouseEvent* );
-//    void     onPointSelect( SUIT_ViewWindow*, QMouseEvent* );
-    void     onPointDrag( SUIT_ViewWindow*, QMouseEvent* );
+  void     onAdditionMode(bool checked);
+  void     onModificationMode(bool checked);
+  void     onDetectionMode(bool checked);
+  void     onModeChanged(bool checked);
+  void     onNewSection();
+  void     onSelectionChanged();
+  void     onAddNewSection();
+  void     onEditSection( int theSection );
+  void     onModifySection();
+  void     onCancelSection();
+  void     onJoin();
+  void     onRemove();
+  void     onClearAll();
+  void     onJoinAll();
+  void     onSetSpline();
+  void     onSetPolyline();
+  void     onCloseSections();
+  void     onUncloseSections();
+  void     onUndo();
+  void     onRedo();
+  void     onUndoSettings();
+  void     onContextMenu(QPoint thePoint);
+
+  void     onMousePress( SUIT_ViewWindow*, QMouseEvent* theEvent );
+  void     onMouseRelease( SUIT_ViewWindow*, QMouseEvent* theEvent );
+  void     onMouseMove( SUIT_ViewWindow*, QMouseEvent* theEvent );
+  void     onLastViewClosed( SUIT_ViewManager* theManager );
+
+  void     onMousePress( QMouseEvent* theEvent );
+  void     onMouseRelease( QMouseEvent* theEvent );
+  void     onMouseMove( QMouseEvent* theEvent );
+
+  void     onCellChanged( int theRow, int theColumn );
+
+protected:
+  void     addCoordsByClick( QMouseEvent* );
+
 protected:
-    enum ActionId{ UNDO_ID, REDO_ID, NEW_SECTION_ID, ADDITION_MODE_ID, REMOVE_ID, REMOVE_ALL_ID, JOIN_ID,
-                   JOIN_ALL_ID, UP_ID, DOWN_ID, INSERT_SECTION_BEFORE_ID, INSERT_SECTION_AFTER_ID,
-                   INSERT_POINT_BEFORE_ID, INSERT_POINT_AFTER_ID, CLOSE_SECTIONS_ID, UNCLOSE_SECTIONS_ID,
-                   SET_SECTIONS_POLYLINE_ID, SET_SECTIONS_SPLINE_ID, CLEAR_ALL_ID, SEPARATOR_ID, 
-                   MODIFICATION_MODE_ID, DETECTION_MODE_ID };
+  enum ActionId{ NONE_ID,
+                 UNDO_ID, 
+                 REDO_ID, 
+                 NEW_SECTION_ID, 
+                 ADDITION_MODE_ID, 
+                 REMOVE_ID, 
+                 REMOVE_ALL_ID, 
+                 JOIN_ID,
+                 JOIN_ALL_ID, 
+                 CLOSE_SECTIONS_ID, 
+                 UNCLOSE_SECTIONS_ID,
+                 SET_SECTIONS_POLYLINE_ID, 
+                 SET_SECTIONS_SPLINE_ID, 
+                 CLEAR_ALL_ID, 
+                 SEPARATOR_ID, 
+                 MODIFICATION_MODE_ID, 
+                 DETECTION_MODE_ID 
+  };
+
 private:
-    QAction* createAction( ActionId theId, const QString& theName, const QPixmap& theImage,
-                           const QString& theToolTip, const QKeySequence& theShortcut );
-    QAction* getAction(ActionId theId);
-    void     updateUndoRedo();
+  OCCViewer_Viewer* getOCCViewer();
+
+  QAction* createAction( ActionId theId, const QString& theName, const QPixmap& theImage,
+                         const QString& theToolTip, const QKeySequence& theShortcut );
+  QAction* getAction(ActionId theId);
+  QAction* getAction(ActionMode theMode);
+
+  void updateActionsStates();
+  void updateUndoRedo();
+
+  void removeSection();
+  void removePoint();
+  void addNewPoint(const CurveCreator::Coordinates& theCoords);
+  void insertPointToSelectedSegment( const int theXPosition,
+                                     const int theYPosition );
+  void moveSelectedPoints( const int theXPosition, const int theYPosition );
+  void updateLocalPointView();
+  void setLocalPointContext( const bool theOpen, const bool isUpdateTable = false );
+
+  void setDragStarted( const bool theState, const QPoint& thePoint = QPoint() );
+
+  void getSelectedPoints( CurveCreator_ICurve::SectionToPointList& thePoints );
+  void setSelectedPoints( const CurveCreator_ICurve::SectionToPointList& =
+                               CurveCreator_ICurve::SectionToPointList() );
+
+  void stopActionMode();
+
+  void startCurveModification( CurveCreator_ICurve::SectionToPointList& thePoints,
+                               const bool theFillPoints = true );
+  void finishCurveModification( const CurveCreator_ICurve::SectionToPointList& thePoints = 
+                                      CurveCreator_ICurve::SectionToPointList() );
+
+  // curve algorithm
+  int  findLocalPointIndex( int theSectionId, float theX, float theY );
+  void findSectionsToPoints( const double theX, const double theY,
+                             CurveCreator_ICurve::SectionToPointList& thePoints );
+  void convert( const CurveCreator_ICurve::SectionToPointList& thePoints,
+                QMap<int, QList<int> >& theConvPoints );
+
+  bool contains( const CurveCreator_ICurve::SectionToPointList& theList,
+                 const CurveCreator_ICurve::SectionToPoint& theValue ) const;
+
 private:
-    QMap<ActionId, QAction*>    myActionMap;
-    CurveCreator_Curve*         myCurve;
-    CurveCreator_CurveEditor*   myEdit;
-    CurveCreator_TreeView*      mySectionView;
-    CurveCreator_NewPointDlg*   myNewPointEditor;
-    CurveCreator_NewSectionDlg* myNewSectionEditor;
-    int                         mySection;
-    int                         myPointNum;
-    QPoint                      myDragStartPosition;
+  QMap<ActionId, QAction*>    myActionMap;
+  CurveCreator_ICurve*        myCurve;
+  CurveCreator_TreeView*      mySectionView;
+  CurveCreator_TableView*     myLocalPointView;
+  CurveCreator_ICurve::SectionToPointList myLocalPoints;
+  CurveCreator_NewSectionDlg* myNewSectionEditor;
+  OCCViewer_Viewer*           myOCCViewer;
+  int                         myLocalPointRowLimit;
+  int                         mySection;
+  int                         myPointNum;
+  bool                        myDragStarted;
+  QPoint                      myDragStartPosition;
+  int                         myDragInteractionStyle;
+  CurveCreator_ICurve::SectionToPointList myDragPoints;
+  QMap<CurveCreator_ICurve::SectionToPoint, CurveCreator::Coordinates> myInitialDragPointsCoords;
+  bool                        myDragged;
+  QByteArray                  myGuiState;
+  int                         myPressedX;
+  int                         myPressedY;
+  OCCViewer_ViewWindow::Mode2dType myOld2DMode;
 };
 
 #endif // CURVECREATOR_WIDGET_H
index 865678ad32bd4e1b8caee35efbe145dbd8030f2a..79668add1cf4b08310c41def8e5807d3c7522f88 100755 (executable)
@@ -40,6 +40,7 @@ INCLUDE_DIRECTORIES(
   ${PROJECT_SOURCE_DIR}/src/GEOMGUI
   ${PROJECT_SOURCE_DIR}/src/GEOMBase
   ${PROJECT_SOURCE_DIR}/src/SKETCHER
+  ${PROJECT_SOURCE_DIR}/src/CurveCreator
   ${PROJECT_SOURCE_DIR}/src/ShapeRecognition
   ${PROJECT_SOURCE_DIR}/src/DlgRef
   ${PROJECT_BINARY_DIR}/src/DlgRef
@@ -65,6 +66,7 @@ SET(_link_LIBRARIES
   GEOM
   DlgRef
   GEOMSketcher
+  CurveCreator
   )
 
 # optional sources
@@ -103,6 +105,7 @@ SET(EntityGUI_HEADERS
   EntityGUI.h
   EntityGUI_Widgets.h
   EntityGUI_SketcherDlg.h
+  EntityGUI_PolylineDlg.h
   EntityGUI_3DSketcherDlg.h
   EntityGUI_IsolineDlg.h
   EntityGUI_SubShapeDlg.h
@@ -115,6 +118,7 @@ SET(_moc_HEADERS
   EntityGUI_Widgets.h
   EntityGUI_FieldDlg.h
   EntityGUI_SketcherDlg.h
+  EntityGUI_PolylineDlg.h
   EntityGUI_3DSketcherDlg.h
   EntityGUI_IsolineDlg.h
   EntityGUI_SubShapeDlg.h
@@ -135,6 +139,7 @@ SET(EntityGUI_SOURCES
   EntityGUI_Widgets.cxx
   EntityGUI_FieldDlg.cxx
   EntityGUI_SketcherDlg.cxx
+  EntityGUI_PolylineDlg.cxx
   EntityGUI_3DSketcherDlg.cxx
   EntityGUI_IsolineDlg.cxx
   EntityGUI_SubShapeDlg.cxx
index b6f36c8ad524ded52e3d0bd396bdb798db117fdc..3a3bd62971e4f761b477cd3c2fbe7bbe9be84fa5 100644 (file)
@@ -59,6 +59,7 @@
 #include "EntityGUI_FeatureDetectorDlg.h" // Feature Detection
 #include "EntityGUI_PictureImportDlg.h"   // Import Picture in viewer
 #include "EntityGUI_FieldDlg.h"           // Create/Edit Field
+#include "EntityGUI_PolylineDlg.h"        // Create/Edit 2d polyline
 
 #include "GEOMImpl_Types.hxx"
 
@@ -188,6 +189,10 @@ bool EntityGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent )
     SUIT_MessageBox::warning(parent, tr("WRN_WARNING"), tr("NO_FIELD"));
     break;
   }
+  case GEOMOp::Op2dPolylineEditor: // POLYLINE EDITOR
+    getGeometryGUI()->ActiveWorkingPlane();
+    aDlg = new EntityGUI_PolylineDlg( getGeometryGUI(), parent );
+    break;
   default:
     app->putInfo( tr( "GEOM_PRP_COMMAND" ).arg( theCommandID ) );
     break;
diff --git a/src/EntityGUI/EntityGUI_PolylineDlg.cxx b/src/EntityGUI/EntityGUI_PolylineDlg.cxx
new file mode 100644 (file)
index 0000000..50c1246
--- /dev/null
@@ -0,0 +1,670 @@
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "EntityGUI_PolylineDlg.h"
+#include <CurveCreator_Curve.hxx>
+#include <CurveCreator_Utils.hxx>
+#include <CurveCreator_Widget.h>
+#include <DlgRef.h>
+#include <GeometryGUI.h>
+#include <GEOMBase.h>
+
+#include <OCCViewer_ViewManager.h>
+#include <LightApp_SelectionMgr.h>
+#include <SalomeApp_Application.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+
+#include <BRep_Tool.hxx>
+#include <Geom_Surface.hxx>
+#include <GeomLib_IsPlanarSurface.hxx>
+#include <TopoDS.hxx>
+
+#include <QGroupBox>
+#include <QVBoxLayout>
+
+//#define SET_PLANE
+
+//=================================================================================
+// function : Constructor
+// purpose  :
+//=================================================================================
+EntityGUI_PolylineDlg::EntityGUI_PolylineDlg
+        (GeometryGUI* theGeometryGUI, QWidget* parent, bool modal, Qt::WindowFlags fl)
+  : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl ),
+    myCurve               (0),
+    myEditorWidget        (0),
+    myAddElementBox       (0),
+    myPlnComboBox         (0),
+    myPlnButton           (0),
+    myPlnSelButton        (0),
+    myWPlaneLineEdit      (0),
+    myPolylineSelButton   (0),
+    myPolylineEdit        (0),
+    myEditCurrentArgument (0)
+{
+  QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
+  QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
+
+  setWindowTitle(tr("POLYLINE_DLG_TITLE"));
+
+  /***************************************************************/
+  mainFrame()->GroupConstructors->setTitle(tr("POLYLINE_TITLE"));
+  mainFrame()->RadioButton1->setIcon(image0);
+  mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
+  mainFrame()->RadioButton2->close();
+  mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
+  mainFrame()->RadioButton3->close();
+
+  QGroupBox   *aGroupBox1 = new QGroupBox(tr("GEOM_CS"), this);
+  QGridLayout *aPlaneLayout = new QGridLayout(aGroupBox1);
+
+  aPlaneLayout->setSpacing(6);
+  aPlaneLayout->setMargin(11);
+
+  myPlnComboBox = new QComboBox(aGroupBox1);
+  aPlaneLayout->addWidget(myPlnComboBox, 0, 0, 1, 3);
+
+  myPlnButton = new QPushButton (aGroupBox1);
+  myPlnButton->setText( tr( "GEOM_SKETCHER_RESTORE" ) );
+  aPlaneLayout->addWidget(myPlnButton, 0, 3);
+
+#ifdef SET_PLANE
+  QLabel *aPlaneLbl = new QLabel(tr("GEOM_PLANE"), aGroupBox1);
+
+  myPlnSelButton = new QPushButton (aGroupBox1);
+  myPlnSelButton->setIcon(image1);
+  myWPlaneLineEdit = new QLineEdit (aGroupBox1);
+  myWPlaneLineEdit->setReadOnly(true);
+#endif
+
+  QLabel *aPolylineLbl = new QLabel(tr("POLYLINE_IMPORT"), aGroupBox1);
+
+  myPolylineSelButton = new QPushButton (aGroupBox1);
+  myPolylineSelButton->setIcon(image1);
+  myPolylineEdit = new QLineEdit (aGroupBox1);
+  myPolylineEdit->setReadOnly(true);
+
+#ifdef SET_PLANE
+  aPlaneLayout->addWidget(aPlaneLbl, 1, 0);
+  aPlaneLayout->addWidget(myPlnSelButton, 1, 1);
+  aPlaneLayout->addWidget(myWPlaneLineEdit, 1, 2, 1, 2);
+#endif
+  aPlaneLayout->addWidget(aPolylineLbl, 2, 0);
+  aPlaneLayout->addWidget(myPolylineSelButton, 2, 1);
+  aPlaneLayout->addWidget(myPolylineEdit, 2, 2, 1, 2);
+  
+  aPlaneLayout->setColumnStretch(2, 1);
+
+  myCurve = new CurveCreator_Curve( CurveCreator::Dim2d );
+  myEditorWidget = new CurveCreator_Widget (centralWidget(), myCurve);
+  myAddElementBox = new QGroupBox (tr("POLYLINE_ADD_SECTION"), centralWidget());
+
+  QBoxLayout* anAddElementLayout = new QVBoxLayout( myAddElementBox );
+
+  anAddElementLayout->setMargin( 0 );
+  anAddElementLayout->setSpacing( 6 );
+
+  QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
+
+  layout->setMargin( 0 );
+  layout->setSpacing( 6 );
+  layout->addWidget( aGroupBox1 );
+  layout->addWidget( myEditorWidget );
+  layout->addWidget( myAddElementBox );
+
+  /***************************************************************/
+
+  setHelpFileName( "create_polyline_page.html" );
+
+  /* Initialisations */
+  Init();
+}
+
+//=================================================================================
+// function : Destructor
+// purpose  :
+//=================================================================================
+EntityGUI_PolylineDlg::~EntityGUI_PolylineDlg()
+{
+  delete myCurve;
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void EntityGUI_PolylineDlg::Init()
+{
+  initName(tr("POLYLINE_NAME"));
+
+  SalomeApp_Application *anApp        = myGeomGUI->getApp();
+  OCCViewer_ViewManager *aViewManager = dynamic_cast<OCCViewer_ViewManager*>
+    (anApp->getViewManager(OCCViewer_Viewer::Type(), true));
+  LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr();
+
+  myEditorWidget->setOCCViewer(aViewManager ? aViewManager->getOCCViewer() : 0);
+
+  // Init the list of local coordinate system
+  gp_Pnt aPnt(0., 0., 0.);
+  gp_Dir aDirN(0., 0., 1.);
+  gp_Dir aDirX(1., 0., 0.);
+  gp_Ax3 aLCS(aPnt, aDirN, aDirX);
+
+  //add Global CS
+  myPlnComboBox->addItem(tr("GEOM_GCS"), false);
+  myWPlaneList.push_back(GEOM::GeomObjPtr());
+  myLCSList.push_back(aLCS);
+
+  connect(myGeomGUI,      SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
+  connect(myGeomGUI,      SIGNAL(SignalCloseAllDialogs()),        this, SLOT(ClickOnCancel()));
+
+#ifdef SET_PLANE
+  connect(myPlnSelButton, SIGNAL(clicked()),
+          this,           SLOT(SetEditCurrentArgument()));
+#endif
+  connect(myPolylineSelButton, SIGNAL(clicked()),
+          this,                SLOT(SetEditCurrentArgument()));
+  connect(aSelMgr,        SIGNAL(currentSelectionChanged()),
+          this,           SLOT(SelectionIntoArgument()));
+  connect(myEditorWidget, SIGNAL(subOperationStarted(QWidget*, bool)),
+          this,           SLOT(processStartedSubOperation(QWidget*, bool)));
+  connect(myEditorWidget, SIGNAL(subOperationFinished(QWidget*)),
+          this,           SLOT(processFinishedSubOperation(QWidget*)));
+  connect(myEditorWidget, SIGNAL(curveModified()),
+          this,           SLOT(onUpdatePreview()));
+#ifdef SET_PLANE
+  connect(myPlnComboBox,  SIGNAL(activated(int)),
+          this,           SLOT(ActivateLocalCS()));
+  connect(myPlnButton,    SIGNAL(clicked()),
+          this,           SLOT(ActivateLocalCS()));
+#endif
+  connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+  connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+
+  myAddElementBox->hide();
+  myPolylineSelButton->click();
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : Clear
+// purpose  :
+//=================================================================================
+void EntityGUI_PolylineDlg::Clear()
+{
+  delete myCurve;
+
+  myCurve = new CurveCreator_Curve( CurveCreator::Dim2d );
+  myEditorWidget->setCurve(myCurve);
+}
+
+//=================================================================================
+// function : GetCurveParams
+// purpose  :
+//=================================================================================
+void EntityGUI_PolylineDlg::GetCurveParams(GEOM::ListOfListOfDouble &theCoords,
+                                           GEOM::string_array       &theNames,
+                                           GEOM::short_array        &theTypes,
+                                           GEOM::ListOfBool         &theCloseds)
+{
+  const int aNbSec = myCurve->getNbSections();
+  int       i;
+  int       j;
+
+  theCoords.length(aNbSec);
+  theNames.length(aNbSec);
+  theTypes.length(aNbSec);
+  theCloseds.length(aNbSec);
+
+  for (i = 0; i < aNbSec; ++i) {
+    // Set coordinates
+    CurveCreator::Coordinates aCoords   = myCurve->getPoints(i);
+    const int                 aNbPoints = aCoords.size();
+
+    theCoords[i].length(aNbPoints);
+
+    for (j = 0; j < aNbPoints; ++j) {
+      theCoords[i][j] = aCoords[j];
+    }
+
+    // Set section type
+    const CurveCreator::SectionType aType = myCurve->getSectionType(i);
+
+    switch (aType) {
+      case CurveCreator::Spline:
+        theTypes[i] = GEOM::Interpolation;
+        break;
+      case CurveCreator::Polyline:
+      default:
+        theTypes[i] = GEOM::Polyline;
+        break;
+    }
+
+    // Set section names and closed flags.
+    theNames[i]   = CORBA::string_dup(myCurve->getSectionName(i).c_str());
+    theCloseds[i] = myCurve->isClosed(i);
+  }
+}
+
+//=================================================================================
+// function : createOperation
+// purpose  :
+//=================================================================================
+GEOM::GEOM_IOperations_ptr EntityGUI_PolylineDlg::createOperation()
+{
+  return getGeomEngine()->GetICurvesOperations( getStudyId() );
+}
+
+//=================================================================================
+// function : isValid
+// purpose  :
+//=================================================================================
+bool EntityGUI_PolylineDlg::isValid( QString& msg )
+{
+  return true;
+}
+
+//=================================================================================
+// function : execute
+// purpose  :
+//=================================================================================
+bool EntityGUI_PolylineDlg::execute( ObjectList& objects )
+{
+  GEOM::GEOM_ICurvesOperations_var anOper =
+    GEOM::GEOM_ICurvesOperations::_narrow(getOperation());
+
+  // Get the polyline creation parameters.
+  GEOM::ListOfListOfDouble aCoords;
+  GEOM::string_array       aNames;
+  GEOM::short_array        aTypes;
+  GEOM::ListOfBool         aCloseds;
+
+  GetCurveParams(aCoords, aNames, aTypes, aCloseds);
+
+  // Get Working Plane.
+  int ind = myPlnComboBox->currentIndex();
+
+  if (ind != -1) {
+    bool                  isPlane = myPlnComboBox->itemData(ind).toBool();
+    GEOM::GEOM_Object_var anObj;
+
+    // Perform operation
+    if (isPlane) {
+      anObj = anOper->MakePolyline2DOnPlane
+        (aCoords, aNames, aTypes, aCloseds, myWPlaneList.at(ind).get());
+    } else {
+      gp_Ax3             anAxis = myLCSList.at(ind);
+      GEOM::ListOfDouble aPlane;
+
+      aPlane.length(9);
+      aPlane[0] = anAxis.Location().X();
+      aPlane[1] = anAxis.Location().Y();
+      aPlane[2] = anAxis.Location().Z();
+      aPlane[3] = anAxis.Direction().X();
+      aPlane[4] = anAxis.Direction().Y();
+      aPlane[5] = anAxis.Direction().Z();
+      aPlane[6] = anAxis.XDirection().X();
+      aPlane[7] = anAxis.XDirection().Y();
+      aPlane[8] = anAxis.XDirection().Z();
+
+      anObj = anOper->MakePolyline2D
+        (aCoords, aNames, aTypes, aCloseds, aPlane);
+    }
+
+    if (!anObj->_is_nil()) {
+      objects.push_back(anObj._retn());
+    }
+  }
+
+  return true;
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose  :
+//=================================================================================
+void EntityGUI_PolylineDlg::ClickOnOk()
+{
+  setIsApplyAndClose( true );
+
+  if (ClickOnApply())
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose  :
+//=================================================================================
+bool EntityGUI_PolylineDlg::ClickOnApply()
+{
+  if (!onAccept())
+    return false;
+
+  initName();
+
+  return true;
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose  :
+//=================================================================================
+void EntityGUI_PolylineDlg::ClickOnCancel()
+{
+  myEditorWidget->SetViewer2DMode(false);
+  GEOMBase_Skeleton::ClickOnCancel();
+}
+
+//=================================================================================
+// function : processStartedSubOperation
+// purpose  :
+//=================================================================================
+void EntityGUI_PolylineDlg::processStartedSubOperation( QWidget* theWidget, bool theIsEdit )
+{
+  myEditorWidget->setEnabled( false );
+
+  myAddElementBox->setTitle( theIsEdit ? tr( "POLYLINE_EDIT_SECTION" ) : tr( "POLYLINE_ADD_SECTION" ) );
+  QBoxLayout* anAddElementLayout = dynamic_cast<QBoxLayout*>( myAddElementBox->layout() );
+  anAddElementLayout->addWidget( theWidget );
+
+  theWidget->show();
+  myAddElementBox->show();
+}
+
+
+//=================================================================================
+// function : processFinishedSubOperation
+// purpose  :
+//=================================================================================
+void EntityGUI_PolylineDlg::processFinishedSubOperation( QWidget* theWidget )
+{
+  myEditorWidget->setEnabled( true );
+
+  QBoxLayout* anAddElementLayout = dynamic_cast<QBoxLayout*>( myAddElementBox->layout() );
+  anAddElementLayout->removeWidget( theWidget );
+
+  theWidget->hide();
+  myAddElementBox->hide();
+}
+
+//=================================================================================
+// function : deleteSelected
+// purpose  : Redirect the delete action to editor widget
+//=================================================================================
+void EntityGUI_PolylineDlg::deleteSelected()
+{
+  myEditorWidget->removeSelected();
+}
+
+//=================================================================================
+// function : deleteEnabled
+// purpose  : Checks whether there are some to delete
+//=================================================================================
+bool EntityGUI_PolylineDlg::deleteEnabled()
+{
+  return myEditorWidget->removeEnabled();
+}
+
+//=================================================================================
+// function : SelectionIntoArgument
+// purpose  : Called when selection is changed
+//=================================================================================
+void EntityGUI_PolylineDlg::SelectionIntoArgument()
+{
+  bool             isModified      = false;
+  GEOM::GeomObjPtr aSelectedObject = getSelected(TopAbs_SHAPE);
+  TopoDS_Shape     aShape;
+
+  if (aSelectedObject && GEOMBase::GetShape(aSelectedObject.get(), aShape) &&
+      !aShape.IsNull()) {
+    QString aName = GEOMBase::GetName(aSelectedObject.get()); 
+
+    if (myEditCurrentArgument == myPolylineEdit) {
+      // Import a curve
+      CurveCreator_Curve *aNewCurve = 
+        new CurveCreator_Curve(CurveCreator::Dim2d);
+      gp_Ax3              aLocalCS;
+
+      if (CurveCreator_Utils::constructCurve(aShape, aNewCurve, aLocalCS)) {
+        // Change the current curve be the new one.
+        myEditorWidget->setCurve(aNewCurve);
+        delete myCurve;
+        myCurve = aNewCurve;
+        isModified = true;
+        myPolylineEdit->setText(aName);
+#ifdef SET_PLANE
+        AddLocalCS(aSelectedObject.get(), false, aLocalCS);
+        myWPlaneLineEdit->clear();
+        myPlnSelButton->setDown(false);
+#endif
+        myPolylineSelButton->setDown(true);
+      } else {
+        // Does nothing, just clears selection.
+        delete aNewCurve;
+      }
+#ifdef SET_PLANE
+    } else if (myEditCurrentArgument == myWPlaneLineEdit) {
+      // Import planar face.
+      if (aShape.ShapeType() == TopAbs_FACE) {
+        // Check if the face is planar
+        Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape));
+        GeomLib_IsPlanarSurface aPlanarCheck(aSurf, Precision::Confusion());
+
+        if (aPlanarCheck.IsPlanar()) {
+          myWPlaneLineEdit->setText(aName);
+          myPolylineEdit->clear();
+          AddLocalCS(aSelectedObject.get(), true, 
+                     WPlaneToLCS(aSelectedObject.get()));
+          isModified = true;
+          myPlnSelButton->setDown(true);
+          myPolylineSelButton->setDown(false);
+        }
+      }
+      
+      if (!isModified) {
+        myEditCurrentArgument->setText(tr("GEOM_SKETCHER_WPLANE"));
+      }
+#endif
+    }
+  }
+
+  if (!isModified) {
+    // Does nothing, just clears selection.
+    disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
+    myGeomGUI->getApp()->selectionMgr()->clearSelected();
+    connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
+            this, SLOT(SelectionIntoArgument()));
+  }
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose  :
+//=================================================================================
+void EntityGUI_PolylineDlg::SetEditCurrentArgument()
+{
+  if (sender() == myPlnSelButton) {
+#ifdef SET_PLANE
+    myEditCurrentArgument = myWPlaneLineEdit;
+    myEditCurrentArgument->setFocus();
+    myPlnSelButton->setDown(true);
+    myPolylineSelButton->setDown(false);
+#endif
+  } else if (sender() == myPolylineSelButton) {
+    myEditCurrentArgument = myPolylineEdit;
+    myEditCurrentArgument->setFocus();
+#ifdef SET_PLANE
+    myPlnSelButton->setDown(false);
+#endif
+    myPolylineSelButton->setDown(true);
+  }
+}
+
+//=================================================================================
+// function : ActivateThisDialog
+// purpose  :
+//=================================================================================
+void EntityGUI_PolylineDlg::ActivateThisDialog()
+{
+  GEOMBase_Skeleton::ActivateThisDialog();
+
+  connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
+           this, SLOT(SelectionIntoArgument()));
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose  :
+//=================================================================================
+void EntityGUI_PolylineDlg::enterEvent (QEvent*)
+{
+  if (!mainFrame()->GroupConstructors->isEnabled())
+    ActivateThisDialog();
+}
+
+//=================================================================================
+// function : onUpdatePreview
+// purpose  : 
+//=================================================================================
+void EntityGUI_PolylineDlg::onUpdatePreview()
+{
+  displayPreview(true);
+}
+
+//=================================================================================
+// function : ActivateLocalCS
+// purpose  : Activate & Fit Working plane
+//=================================================================================
+void EntityGUI_PolylineDlg::ActivateLocalCS()
+{
+  const int ind = myPlnComboBox->currentIndex();
+
+  if (ind == 0) {
+    // Default plane
+#ifdef SET_PLANE
+    myWPlaneLineEdit->clear();
+#endif
+    myPolylineEdit->clear();
+  } else if (ind > 0) { // Skip 0 as it is default
+    // Update text on line edits.
+    QString aName   = GEOMBase::GetName(GetActiveWPlane().get());
+    bool    isPlane = myPlnComboBox->itemData(ind).toBool();
+
+    if (isPlane) {
+#ifdef SET_PLANE
+      myWPlaneLineEdit->setText(aName);
+#endif
+      myPolylineEdit->clear();
+    } else {
+      myPolylineEdit->setText(aName);
+#ifdef SET_PLANE
+      myWPlaneLineEdit->clear();
+#endif
+    }
+  }
+
+  gp_Ax3 anAxis = GetActiveLocalCS();
+
+  myGeomGUI->SetWorkingPlane(anAxis);
+  myGeomGUI->ActiveWorkingPlane();
+}
+
+//=================================================================================
+// function : GetActiveLocalCS
+// purpose  : Get Working plane
+//=================================================================================
+gp_Ax3 EntityGUI_PolylineDlg::GetActiveLocalCS()
+{
+  const int ind = myPlnComboBox->currentIndex();
+
+  return ind >= 0 ? myLCSList.at(ind) : myGeomGUI->GetWorkingPlane();
+}
+
+//=================================================================================
+// function : GetActiveWPlane
+// purpose  : Get Working plane
+//=================================================================================
+GEOM::GeomObjPtr EntityGUI_PolylineDlg::GetActiveWPlane()
+{
+  const int ind = myPlnComboBox->currentIndex();
+
+  return ind >= 0 ? myWPlaneList.at(ind) : GEOM::GeomObjPtr();
+}
+
+//=================================================================================
+// function : AddLocalCS()
+// purpose  : Add All Coordinates systems in study
+//=================================================================================
+void EntityGUI_PolylineDlg::AddLocalCS(GEOM::GeomObjPtr  theSelectedObject,
+                                       const bool        IsPlane,
+                                       const gp_Ax3      &theLCS)
+{
+  QString aName = GEOMBase::GetName(theSelectedObject.get());
+
+  int index = myPlnComboBox->findText(aName, Qt::MatchExactly);
+
+  if (index == -1) { // If the working plane hasn't been added yet
+    myWPlaneList.push_back(theSelectedObject);
+    myLCSList.push_back(theLCS);
+    myPlnComboBox->addItem(aName, QVariant(IsPlane));
+    index = myPlnComboBox->count();
+    myPlnComboBox->setCurrentIndex(index - 1);
+  } else {
+    myPlnComboBox->setCurrentIndex(index);
+  }
+  ActivateLocalCS();
+}
+
+//=================================================================================
+// function : WPlaneToLCS ( aWPlane )
+// purpose  : 
+//=================================================================================
+gp_Ax3 EntityGUI_PolylineDlg::WPlaneToLCS(GEOM::GeomObjPtr theGeomObj)
+{
+  TopoDS_Shape aShape =
+    GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), theGeomObj.get());
+  gp_Ax3 aLCS;
+
+  if (theGeomObj || aShape.IsNull()) {
+    MESSAGE("CORBA::is_nil(theGeomObj) || aShape.IsNull()")
+  }
+
+  aLCS.Transform(aShape.Location().Transformation());
+
+  if (aShape.ShapeType() == TopAbs_FACE) {
+    GEOM::GEOM_IMeasureOperations_ptr aMeasureOp =
+      myGeomGUI->GetGeomGen()->GetIMeasureOperations(getStudyId());
+    double Ox, Oy, Oz, Zx, Zy, Zz, Xx, Xy, Xz;
+
+    aMeasureOp->GetPosition(theGeomObj.get(), Ox, Oy, Oz, Zx, Zy, Zz, Xx, Xy, Xz);
+
+    if (aMeasureOp->IsDone()) {
+      gp_Pnt aPnt (Ox, Oy, Oz);
+      gp_Dir aDirN (Zx, Zy, Zz);
+      gp_Dir aDirX (Xx, Xy, Xz);
+      aLCS = gp_Ax3(aPnt, aDirN, aDirX);
+    }
+  }
+
+  return aLCS;
+}
diff --git a/src/EntityGUI/EntityGUI_PolylineDlg.h b/src/EntityGUI/EntityGUI_PolylineDlg.h
new file mode 100644 (file)
index 0000000..6f7b009
--- /dev/null
@@ -0,0 +1,152 @@
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef ENTITYGUI_POLYLINEDLG_H
+#define ENTITYGUI_POLYLINEDLG_H
+
+
+#include <GEOMBase_Skeleton.h>
+
+class CurveCreator_Curve;
+class CurveCreator_Widget;
+class QGroupBox;
+class QComboBox;
+
+
+//=================================================================================
+// class    : EntityGUI_PolylineDlg
+// purpose  :
+//=================================================================================
+class EntityGUI_PolylineDlg : public GEOMBase_Skeleton
+{
+  Q_OBJECT
+
+public:
+
+  EntityGUI_PolylineDlg (GeometryGUI*, QWidget* = 0,
+                         bool = false, Qt::WindowFlags = 0);
+
+  virtual ~EntityGUI_PolylineDlg();
+
+  void  deleteSelected();
+  bool  deleteEnabled();
+
+protected:
+
+  // redefined from GEOMBase_Helper
+  virtual GEOM::GEOM_IOperations_ptr createOperation();
+  virtual bool                       isValid( QString& );
+  virtual bool                       execute( ObjectList& );
+       
+private:
+
+  void Init();
+  void Clear();
+  void enterEvent(QEvent *);
+
+  /**
+   * This method converts the curve into curve parameters required to
+   * construct an object using the interface
+   * GEOM_ICurvesOperations::MakePolyline2DOnPlane.
+   *
+   * \param theCurve a curve object, that contains data.
+   *  \param theCoordsList the list of coordinates list. theCoordsList[0]
+   *         is the coordinates list of the first section. theCoordsList[1]
+   *         is for the second section etc. Output parameter.
+   *  \param theNamesList the list of names. The order corresponds to
+   *         theCoordsList. Output parameter.
+   *  \param theTypesList the list of curve types. The order corresponds to
+   *         theCoordsList. Output parameter.
+   *  \param theClosedList the list of Closed flags. The order corresponds to
+   *         theCoordsList. Output parameter.
+   */
+  void GetCurveParams(GEOM::ListOfListOfDouble &theCoords,
+                      GEOM::string_array       &theNames,
+                      GEOM::short_array        &theTypes,
+                      GEOM::ListOfBool         &theCloseds);
+
+  /**
+   * This method returns the current local coordinate system.
+   *
+   * \return local coordinate system.
+   */
+  gp_Ax3 GetActiveLocalCS();
+
+  /**
+   * This method returns the current working plane. Can be null.
+   *
+   * \return the current working plane.
+   */
+  GEOM::GeomObjPtr GetActiveWPlane();
+
+  /**
+   * This method add a local coordinate system of the selected object.
+   *
+   * \param theSelectedObject the selected object. It can be a planar face
+   *        or an inported polyline.
+   * \param IsPlane true for planar face; false for imported polyline.
+   * \param theLCS the local coordinate system.
+   */
+  void AddLocalCS(GEOM::GeomObjPtr  theSelectedObject,
+                  const bool        IsPlane,
+                  const gp_Ax3      &theLCS);
+
+  /**
+   * This method converts the working plane object into
+   * the local coordinate system of the polyline.
+   *
+   * \param theGeomObj the working plane
+   * \return the local coordinate system
+   */
+  gp_Ax3 WPlaneToLCS(GEOM::GeomObjPtr theGeomObj);
+
+protected slots:
+
+  void ClickOnOk();
+  bool ClickOnApply();
+  void ClickOnCancel();
+  void processStartedSubOperation( QWidget*, bool );
+  void processFinishedSubOperation( QWidget* );
+  void SetEditCurrentArgument();
+  void SelectionIntoArgument();
+  void ActivateThisDialog();
+  void onUpdatePreview();
+  void ActivateLocalCS();
+
+private:
+
+  CurveCreator_Curve           *myCurve;
+  CurveCreator_Widget          *myEditorWidget;
+  QGroupBox                    *myAddElementBox;
+  QComboBox                    *myPlnComboBox;
+  QPushButton                  *myPlnButton;
+  QPushButton                  *myPlnSelButton;
+  QPushButton                  *myPolylineSelButton;
+  QLineEdit                    *myWPlaneLineEdit;
+  QLineEdit                    *myPolylineEdit;
+  QLineEdit                    *myEditCurrentArgument;   /* Current LineEdit */
+  QList<gp_Ax3>                 myLCSList;
+  QList<GEOM::GeomObjPtr>       myWPlaneList;
+
+};
+
+#endif // ENTITYGUI_POLYLINEDLG_H
index c141e2e4ca881575de56f34f7982517708187c4e..458e0a0bc75079623e12f8a53a5d664ff1401bf6 100644 (file)
@@ -36,6 +36,8 @@
 #include <TDF_Data.hxx>
 #include <TDF_ChildIterator.hxx>
 #include <TDF_Reference.hxx>
+#include <TDataStd_BooleanArray.hxx>
+#include <TDataStd_ByteArray.hxx>
 #include <TDataStd_Integer.hxx>
 #include <TDataStd_IntegerArray.hxx>
 #include <TDataStd_Real.hxx>
@@ -474,6 +476,74 @@ Handle(TColStd_HArray1OfInteger) GEOM_Function::GetIntegerArray(int thePosition)
   return anIntegerArray->Array();
 }
 
+//=============================================================================
+/*!
+ *  SetByteArray
+ */
+//=============================================================================
+void GEOM_Function::SetByteArray (int thePosition,
+                                  const Handle(TColStd_HArray1OfByte)& theArray)
+{
+  _isDone = false;
+  if(thePosition <= 0) return;
+  TDF_Label anArgLabel = ARGUMENT(thePosition);
+  Handle(TDataStd_ByteArray) anAttr =
+    TDataStd_ByteArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
+  anAttr->ChangeArray(theArray);
+  _isDone = true;
+}
+
+//=============================================================================
+/*!
+ *  GetByteArray
+ */
+//=============================================================================
+Handle(TColStd_HArray1OfByte) GEOM_Function::GetByteArray(int thePosition)
+{
+  _isDone = false;
+  if(thePosition <= 0) return 0;
+  Handle(TDataStd_ByteArray) aByteArray;
+  TDF_Label anArgLabel = ARGUMENT(thePosition);
+  if(!anArgLabel.FindAttribute(TDataStd_ByteArray::GetID(), aByteArray)) return 0;
+
+  _isDone = true;
+  return aByteArray->InternalArray();
+}
+
+//=============================================================================
+/*!
+ *  SetBooleanArray
+ */
+//=============================================================================
+void GEOM_Function::SetBooleanArray (int thePosition,
+                                     const Handle(TColStd_HArray1OfByte)& theArray)
+{
+  _isDone = false;
+  if(thePosition <= 0) return;
+  TDF_Label anArgLabel = ARGUMENT(thePosition);
+  Handle(TDataStd_BooleanArray) anAttr =
+    TDataStd_BooleanArray::Set(anArgLabel, theArray->Lower(), theArray->Upper());
+  anAttr->SetInternalArray(theArray);
+  _isDone = true;
+}
+
+//=============================================================================
+/*!
+ *  GetBooleanArray
+ */
+//=============================================================================
+Handle(TColStd_HArray1OfByte) GEOM_Function::GetBooleanArray(int thePosition)
+{
+  _isDone = false;
+  if(thePosition <= 0) return 0;
+  Handle(TDataStd_BooleanArray) aBooleanArray;
+  TDF_Label anArgLabel = ARGUMENT(thePosition);
+  if(!anArgLabel.FindAttribute(TDataStd_BooleanArray::GetID(), aBooleanArray)) return 0;
+
+  _isDone = true;
+  return aBooleanArray->InternalArray();
+}
+
 //=============================================================================
 /*!
  *  SetString
index 702acb95981ea341008cea1524cb6d0620664084..688324dae0c173c3edd72a87364e78513e8bde17 100644 (file)
@@ -32,6 +32,7 @@
 #include <TDataStd_ListOfExtendedString.hxx>
 #include <TopoDS_Shape.hxx>
 
+class Handle_TColStd_HArray1OfByte;
 class Handle_TColStd_HArray1OfReal;
 class Handle_TColStd_HArray1OfInteger;
 class Handle_TColStd_HSequenceOfTransient;
@@ -108,6 +109,18 @@ public:
   //Returns an integer array argument at position thePosition
   Standard_EXPORT Handle(TColStd_HArray1OfInteger) GetIntegerArray(int thePosition);
 
+  //Sets a byte array argument at position thePosition
+  Standard_EXPORT void SetByteArray(int thePosition, const Handle(TColStd_HArray1OfByte)& theArray);
+
+  //Returns a byte array argument at position thePosition
+  Standard_EXPORT Handle(TColStd_HArray1OfByte) GetByteArray(int thePosition);
+
+  //Sets a boolean array argument at position thePosition
+  Standard_EXPORT void SetBooleanArray(int thePosition, const Handle(TColStd_HArray1OfByte)& theArray);
+
+  //Returns a boolean array argument at position thePosition
+  Standard_EXPORT Handle(TColStd_HArray1OfByte) GetBooleanArray(int thePosition);
+
   //Sets a reference to other function argument at position thePosition
   Standard_EXPORT void SetReference(int thePosition, Handle(GEOM_Function) theReference);
 
index 115e51e67bf40a4ac764b069bc639d7aa86b34a2..40c06a6320f4c4b1352bc1d3cfc84289f515be60 100644 (file)
             <source>ICO_SHELL_SEL_ONLY</source>
             <translation>build_shell.png</translation>
         </message>
+        <message>
+          <source>ICO_CURVE_CREATOR</source>
+          <translation>polyline.png</translation>
+        </message>
         <message>
             <source>ICO_SKETCH</source>
             <translation>sketch.png</translation>
index 89480676be4adacfa972228531fcec5c51cccff2..754afda3d6174beed6288015700b39d082182d3d 100644 (file)
@@ -2366,7 +2366,15 @@ Please, select face, shell or solid and try again</translation>
     </message>
     <message>
         <source>MEN_CURVE_CREATOR</source>
-        <translation>Curve creator</translation>
+        <translation>2D Polyline</translation>
+    </message>
+    <message>
+      <source>TOP_CURVE_CREATOR</source>
+      <translation>Create 2D polyline</translation>
+    </message>
+    <message>
+      <source>STB_CURVE_CREATOR</source>
+      <translation>Create 2D polyline</translation>
     </message>
     <message>
         <source>MEN_ALL_SEL_ONLY</source>
@@ -5163,6 +5171,22 @@ shells and solids on the other hand.</translation>
         <source>TOOL_IMPORTEXPORT</source>
         <translation>Import / Export XAO</translation>
     </message>
+    <message>
+        <source>TABLE_SECTION</source>
+        <translation>Section</translation>
+    </message>
+    <message>
+        <source>TABLE_INDEX</source>
+        <translation>Index</translation>
+    </message>
+    <message>
+        <source>TABLE_X</source>
+        <translation>X</translation>
+    </message>
+    <message>
+        <source>TABLE_Y</source>
+        <translation>Y</translation>
+    </message>
 </context>
 <context>
     <name>BasicGUI_CurveDlg</name>
@@ -5404,74 +5428,39 @@ shells and solids on the other hand.</translation>
         <translation>Face 2 V</translation>
     </message>
 </context>
-<context>
-    <name>CurveCreator_NewPointDlg</name>
-    <message>
-        <source>ADD_NEW_POINT</source>
-        <translation>Add new points</translation>
-    </message>
-    <message>
-        <source>X_COORD</source>
-        <translation>X</translation>
-    </message>
-    <message>
-        <source>Y_COORD</source>
-        <translation>Y</translation>
-    </message>
-    <message>
-        <source>Z_COORD</source>
-        <translation>Z</translation>
-    </message>
-    <message>
-        <source>ADD_BTN</source>
-        <translation>Add</translation>
-    </message>
-    <message>
-        <source>ADD_CONTINUE_BTN</source>
-        <translation>Add and continue</translation>
-    </message>
-    <message>
-        <source>ADD_NEW_POINT_TO_%1</source>
-        <translation>Add new point to %1</translation>
-    </message>
-    <message>
-        <source>SET_POINT_COORDINATES</source>
-        <translation>Set point coordinates</translation>
-    </message>
-</context>
 <context>
     <name>CurveCreator_NewSectionDlg</name>
     <message>
-        <source>NAME</source>
+        <source>SECTION_NAME</source>
         <translation>Name</translation>
     </message>
     <message>
-        <source>LINE_TYPE</source>
+        <source>SECTION_LINE_TYPE</source>
         <translation>Type</translation>
     </message>
     <message>
-        <source>POLYLINE_TYPE</source>
+        <source>SECTION_POLYLINE_TYPE</source>
         <translation>Polyline</translation>
     </message>
     <message>
-        <source>SPLINE_TYPE</source>
+        <source>SECTION_SPLINE_TYPE</source>
         <translation>Spline</translation>
     </message>
     <message>
-        <source>LINE_CLOSED</source>
+        <source>SECTION_LINE_CLOSED</source>
         <translation>Closed</translation>
     </message>
     <message>
-        <source>OK</source>
-        <translation>Ok</translation>
+        <source>SECTION_ADD_BTN</source>
+        <translation>Add</translation>
     </message>
     <message>
-        <source>ADD_BTN</source>
-        <translation>Add</translation>
+        <source>SECTION_OK_BTN</source>
+        <translation>Ok</translation>
     </message>
     <message>
-        <source>ADD_CONTINUE_BTN</source>
-        <translation>Add and continue</translation>
+        <source>SECTION_CANCEL_BTN</source>
+        <translation>Cancel</translation>
     </message>
     <message>
         <source>ADD_NEW_SECTION</source>
@@ -5496,11 +5485,7 @@ shells and solids on the other hand.</translation>
 <context>
     <name>CurveCreator_Widget</name>
     <message>
-        <source>CURVE_NAME_TLT</source>
-        <translation>Name</translation>
-    </message>
-    <message>
-        <source>SECTION_GROUP_TLT</source>
+        <source>SECTION_GROUP_TITLE</source>
         <translation>Sections</translation>
     </message>
     <message>
@@ -5527,22 +5512,6 @@ shells and solids on the other hand.</translation>
         <source>NEW_SECTION_TLT</source>
         <translation>Insert new section</translation>
     </message>
-    <message>
-        <source>INSERT_SECTION_BEFORE</source>
-        <translation>Insert section before</translation>
-    </message>
-    <message>
-        <source>INSERT_SECTION_BEFORE_TLT</source>
-        <translation>Insert section before</translation>
-    </message>
-    <message>
-        <source>INSERT_SECTION_AFTER</source>
-        <translation>Insert section after</translation>
-    </message>
-    <message>
-        <source>INSERT_SECTION_AFTER_TLT</source>
-        <translation>Insert section after</translation>
-    </message>
     <message>
         <source>ADDITION_MODE</source>
         <translation>Addition mode</translation>
@@ -5567,18 +5536,6 @@ shells and solids on the other hand.</translation>
         <source>DETECTION_MODE_TLT</source>
         <translation>Detection mode</translation>
     </message>
-    <message>
-        <source>INSERT_POINT_BEFORE</source>
-        <translation>Insert point before</translation>
-    </message>
-    <message>
-        <source>INSERT_POINT_BEFORE_TLT</source>
-        <translation>Insert point before</translation>
-    </message>
-    <message>
-        <source>INSERT_POINT_AFTER</source>
-        <translation>Insert point after</translation>
-    </message>
     <message>
         <source>CLOSE_SECTIONS</source>
         <translation>Set closed</translation>
@@ -5627,22 +5584,6 @@ shells and solids on the other hand.</translation>
         <source>JOIN_TLT</source>
         <translation>Join selected sections</translation>
     </message>
-    <message>
-        <source>STEP_UP</source>
-        <translation>Move up</translation>
-    </message>
-    <message>
-        <source>STEP_UP_TLT</source>
-        <translation>Move selected objects up</translation>
-    </message>
-    <message>
-        <source>STEP_DOWN</source>
-        <translation>Move down</translation>
-    </message>
-    <message>
-        <source>STEP_DOWN_TLT</source>
-        <translation>Move selected objects down</translation>
-    </message>
     <message>
         <source>CLEAR_ALL</source>
         <translation>Clear all</translation>
@@ -5660,6 +5601,33 @@ shells and solids on the other hand.</translation>
         <translation>Join all sections</translation>
     </message>
 </context>
+<context>
+    <name>EntityGUI_PolylineDlg</name>
+    <message>
+        <source>POLYLINE_DLG_TITLE</source>
+        <translation>Polyline Construction</translation>
+    </message>
+    <message>
+        <source>POLYLINE_TITLE</source>
+        <translation>Polyline</translation>
+    </message>
+    <message>
+        <source>POLYLINE_NAME</source>
+        <translation>Polyline</translation>
+    </message>
+    <message>
+        <source>POLYLINE_IMPORT</source>
+        <translation>Import polyline</translation>
+    </message>
+    <message>
+        <source>POLYLINE_ADD_SECTION</source>
+        <translation>Add section</translation>
+    </message>
+    <message>
+        <source>POLYLINE_EDIT_SECTION</source>
+        <translation>Edit section</translation>
+    </message>
+</context>
 <context>
     <name>EntityGUI_SketcherDlg</name>
     <message>
index 2b3b7ca836fa5a19382539d9d43d024d5f98d55a..d3d37411ced98181e82137b83d7ea2435010f214 100644 (file)
@@ -561,6 +561,7 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam )
   case GEOMOp::OpCreateField:        // MENU FIELD - CREATE FIELD
   case GEOMOp::OpEditField:          // MENU FIELD - EDIT FIELD
   case GEOMOp::OpEditFieldPopup:     // POPUP MENU - EDIT FIELD
+  case GEOMOp::Op2dPolylineEditor:   // MENU BASIC - POLYLINE EDITOR
     libName = "EntityGUI";
     break;
   case GEOMOp::OpEdge:               // MENU BUILD - EDGE
@@ -600,10 +601,6 @@ void GeometryGUI::OnGUIEvent( int id, const QVariant& theParam )
   case GEOMOp::OpSharedShapes:       // MENU OPERATION - GET SHARED SHAPES
   case GEOMOp::OpExtrudedBoss:       // MENU OPERATION - EXTRUDED BOSS
   case GEOMOp::OpExtrudedCut:        // MENU OPERATION - EXTRUDED CUT
-#ifdef DEBUG_CURVE_CREATOR  
-  // for debug purposes, to be removed
-  case GEOMOp::OpCurveCreator:       // MENU OPERATION - CURVE CREATOR
-#endif
     libName = "OperationGUI";
     break;
   case GEOMOp::OpSewing:             // MENU REPAIR - SEWING
@@ -941,6 +938,7 @@ void GeometryGUI::initialize( CAM_Application* app )
   createGeomAction( GEOMOp::OpFeatureDetect,"FEATURE_DETECTION" );
 #endif
   createGeomAction( GEOMOp::OpPictureImport,"PICTURE_IMPORT" );
+  createGeomAction( GEOMOp::Op2dPolylineEditor, "CURVE_CREATOR" );
 
   createGeomAction( GEOMOp::OpEdge,        "EDGE" );
   createGeomAction( GEOMOp::OpWire,        "WIRE" );
@@ -973,10 +971,6 @@ void GeometryGUI::initialize( CAM_Application* app )
   createGeomAction( GEOMOp::OpSharedShapes,   "GET_SHARED_SHAPES" );
   createGeomAction( GEOMOp::OpExtrudedCut,    "EXTRUDED_CUT" );
   createGeomAction( GEOMOp::OpExtrudedBoss,   "EXTRUDED_BOSS" );
-#ifdef DEBUG_CURVE_CREATOR
-  // for debug purposes, to be removed
-  createGeomAction( GEOMOp::OpCurveCreator,   "CURVE_CREATOR" );
-#endif
   createGeomAction( GEOMOp::OpFillet1d,       "FILLET_1D" );
   createGeomAction( GEOMOp::OpFillet2d,       "FILLET_2D" );
 
@@ -1106,19 +1100,20 @@ void GeometryGUI::initialize( CAM_Application* app )
   int newEntId = createMenu( tr( "MEN_NEW_ENTITY" ), -1, -1, 10 );
 
   int basicId = createMenu( tr( "MEN_BASIC" ), newEntId, -1 );
-  createMenu( GEOMOp::OpPoint,   basicId, -1 );
-  createMenu( GEOMOp::OpLine,    basicId, -1 );
-  createMenu( GEOMOp::OpCircle,  basicId, -1 );
-  createMenu( GEOMOp::OpEllipse, basicId, -1 );
-  createMenu( GEOMOp::OpArc,     basicId, -1 );
-  createMenu( GEOMOp::OpCurve,   basicId, -1 );
-  createMenu( GEOMOp::Op2dSketcher, basicId, -1 );
-  createMenu( GEOMOp::Op3dSketcher, basicId, -1 );
-  createMenu( GEOMOp::OpIsoline, basicId, -1 );
-  createMenu( separator(),       basicId, -1 );
-  createMenu( GEOMOp::OpVector,  basicId, -1 );
-  createMenu( GEOMOp::OpPlane,   basicId, -1 );
-  createMenu( GEOMOp::OpLCS,     basicId, -1 );
+  createMenu( GEOMOp::OpPoint,            basicId, -1 );
+  createMenu( GEOMOp::OpLine,             basicId, -1 );
+  createMenu( GEOMOp::OpCircle,           basicId, -1 );
+  createMenu( GEOMOp::OpEllipse,          basicId, -1 );
+  createMenu( GEOMOp::OpArc,              basicId, -1 );
+  createMenu( GEOMOp::OpCurve,            basicId, -1 );
+  createMenu( GEOMOp::Op2dSketcher,       basicId, -1 );
+  createMenu( GEOMOp::Op2dPolylineEditor, basicId, -1 );
+  createMenu( GEOMOp::Op3dSketcher,       basicId, -1 );
+  createMenu( GEOMOp::OpIsoline,          basicId, -1 );
+  createMenu( separator(),                basicId, -1 );
+  createMenu( GEOMOp::OpVector,           basicId, -1 );
+  createMenu( GEOMOp::OpPlane,            basicId, -1 );
+  createMenu( GEOMOp::OpLCS,              basicId, -1 );
   createMenu( GEOMOp::OpOriginAndVectors, basicId, -1 );
 
   int primId = createMenu( tr( "MEN_PRIMITIVES" ), newEntId, -1 );
@@ -1224,11 +1219,6 @@ void GeometryGUI::initialize( CAM_Application* app )
   createMenu( GEOMOp::OpChamfer,       operId, -1 );
   createMenu( GEOMOp::OpExtrudedBoss,  operId, -1 );
   createMenu( GEOMOp::OpExtrudedCut,   operId, -1 );
-#ifdef DEBUG_CURVE_CREATOR
-  // for debug purposes, to be removed
-  createMenu( separator(), operId, -1 );
-  createMenu( GEOMOp::OpCurveCreator,   operId, -1 );
-#endif
   //createMenu( GEOMOp::OpClipping,      operId, -1 );
 
   int repairId = createMenu( tr( "MEN_REPAIR" ), -1, -1, 10 );
@@ -1319,18 +1309,19 @@ void GeometryGUI::initialize( CAM_Application* app )
   // ---- create toolbars --------------------------
 
   int basicTbId = createTool( tr( "TOOL_BASIC" ), QString( "GEOMBasic" ) );
-  createTool( GEOMOp::OpPoint,      basicTbId );
-  createTool( GEOMOp::OpLine,       basicTbId );
-  createTool( GEOMOp::OpCircle,     basicTbId );
-  createTool( GEOMOp::OpEllipse,    basicTbId );
-  createTool( GEOMOp::OpArc,        basicTbId );
-  createTool( GEOMOp::OpCurve,      basicTbId );
-  createTool( GEOMOp::OpVector,     basicTbId );
-  createTool( GEOMOp::Op2dSketcher, basicTbId ); //rnc
-  createTool( GEOMOp::Op3dSketcher, basicTbId ); //rnc
-  createTool( GEOMOp::OpIsoline,    basicTbId );
-  createTool( GEOMOp::OpPlane,      basicTbId );
-  createTool( GEOMOp::OpLCS,        basicTbId );
+  createTool( GEOMOp::OpPoint,            basicTbId );
+  createTool( GEOMOp::OpLine,             basicTbId );
+  createTool( GEOMOp::OpCircle,           basicTbId );
+  createTool( GEOMOp::OpEllipse,          basicTbId );
+  createTool( GEOMOp::OpArc,              basicTbId );
+  createTool( GEOMOp::OpCurve,            basicTbId );
+  createTool( GEOMOp::OpVector,           basicTbId );
+  createTool( GEOMOp::Op2dSketcher,       basicTbId ); //rnc
+  createTool( GEOMOp::Op2dPolylineEditor, basicTbId ); 
+  createTool( GEOMOp::Op3dSketcher,       basicTbId ); //rnc
+  createTool( GEOMOp::OpIsoline,          basicTbId );
+  createTool( GEOMOp::OpPlane,            basicTbId );
+  createTool( GEOMOp::OpLCS,              basicTbId );
   createTool( GEOMOp::OpOriginAndVectors, basicTbId );
 
 //   int sketchTbId = createTool( tr( "TOOL_SKETCH" ), QString( "GEOMSketch" ) );
@@ -1390,10 +1381,6 @@ void GeometryGUI::initialize( CAM_Application* app )
   createTool( GEOMOp::OpChamfer,         featTbId );
   createTool( GEOMOp::OpExtrudedBoss,    featTbId );
   createTool( GEOMOp::OpExtrudedCut,     featTbId );
-#ifdef DEBUG_CURVE_CREATOR
-  // for debug purposes, to be removed
-  createTool( GEOMOp::OpCurveCreator,    featTbId ); 
-#endif
 
   int buildTbId = createTool( tr( "TOOL_BUILD" ), QString( "GEOMBuild" ) );
   createTool( GEOMOp::OpEdge,     buildTbId );
index f392e4df669595e11429f838113352c57e549a50..f66c19df10cc4c453b316ca8d9a514bb3a4c326e 100644 (file)
@@ -119,6 +119,7 @@ namespace GEOMOp {
     OpCreateField         = 3305,   // MENU FIELD - CREATE FIELD
     OpEditField           = 3306,   // MENU FIELD - EDIT FIELD
     OpEditFieldPopup      = 3307,   // POPUP MENU - EDIT FIELD
+    Op2dPolylineEditor    = 3308,   // MENU NEW ENTITY - BASIC - POLYLINE EDITOR
     // BuildGUI --------------------//--------------------------------
     OpEdge                = 3400,   // MENU NEW ENTITY - BUILD - EDGE
     OpWire                = 3401,   // MENU NEW ENTITY - BUILD - WIRE
@@ -154,10 +155,6 @@ namespace GEOMOp {
     OpSharedShapes        = 3708,   // MENU OPERATION - GET SHARED SHAPES
     OpExtrudedBoss        = 3709,   // MENU OPERATION - ETRUDED BOSS
     OpExtrudedCut         = 3710,   // MENU OPERATION - ETRUDED CUT
-#ifdef DEBUG_CURVE_CREATOR
-    OpCurveCreator        = 3799,   // MENU OPERATION - CURVE CREATOR
-#endif
-    // for debug purposes, to be removed
     // RepairGUI -------------------//--------------------------------
     OpSewing              = 4000,   // MENU REPAIR - SEWING
     OpSuppressFaces       = 4001,   // MENU REPAIR - SUPPRESS FACES
index 0fb1459313a5cae281c4f04e8daa3340fe39603a..a09066811d366dd93546347d84c08eedcce281d0 100755 (executable)
@@ -74,6 +74,7 @@ SET(GEOMImpl_HEADERS
   GEOMImpl_PointDriver.hxx
   GEOMImpl_IPoint.hxx
   GEOMImpl_IPolyline.hxx
+  GEOMImpl_IPolyline2D.hxx
   GEOMImpl_ICircle.hxx
   GEOMImpl_ISpline.hxx
   GEOMImpl_IEllipse.hxx
@@ -150,6 +151,7 @@ SET(GEOMImpl_HEADERS
   GEOMImpl_Block6Explorer.hxx
   GEOMImpl_MeasureDriver.hxx
   GEOMImpl_PolylineDriver.hxx
+  GEOMImpl_PolylineDumper.hxx
   GEOMImpl_CircleDriver.hxx
   GEOMImpl_EllipseDriver.hxx
   GEOMImpl_ArcDriver.hxx
@@ -192,6 +194,7 @@ SET(GEOMImpl_SOURCES
   GEOMImpl_IGroupOperations.cxx
   GEOMImpl_IFieldOperations.cxx
   GEOMImpl_IBaseIEOperations.cxx
+  GEOMImpl_IPolyline2D.cxx
   GEOMImpl_Gen.cxx
   GEOMImpl_PointDriver.cxx
   GEOMImpl_VectorDriver.cxx
@@ -221,6 +224,7 @@ SET(GEOMImpl_SOURCES
   GEOMImpl_Block6Explorer.cxx
   GEOMImpl_MeasureDriver.cxx
   GEOMImpl_PolylineDriver.cxx
+  GEOMImpl_PolylineDumper.cxx
   GEOMImpl_CircleDriver.cxx
   GEOMImpl_EllipseDriver.cxx
   GEOMImpl_ArcDriver.cxx
index df1c543e71af2f96c77fba94eaeb6770fb8badcd..f6c452b951ebbb6dc730764b009df7bba96e10fc 100644 (file)
@@ -51,6 +51,7 @@
 #include "GEOMImpl_3DSketcherDriver.hxx"
 
 #include "GEOMImpl_IPolyline.hxx"
+#include "GEOMImpl_IPolyline2D.hxx"
 #include "GEOMImpl_ICircle.hxx"
 #include "GEOMImpl_ISpline.hxx"
 #include "GEOMImpl_IEllipse.hxx"
 #include "GEOMImpl_I3DSketcher.hxx"
 #include "GEOMImpl_ICurveParametric.hxx"
 #include "GEOMImpl_IIsoline.hxx"
+#include "GEOMImpl_PolylineDumper.hxx"
 
 #include <Basics_OCCTVersion.hxx>
 
 #include "utilities.h"
 
 #include <TDF_Tool.hxx>
+#include <TColStd_HArray1OfByte.hxx>
 #include <TColStd_HArray1OfReal.hxx>
 
 #include <Standard_Failure.hxx>
@@ -1465,3 +1468,155 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeIsoline
   SetErrorCode(OK);
   return anIsoline;
 }
+
+//=============================================================================
+/*!
+ *  MakePolyline2D
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakePolyline2D
+            (const std::list <std::list <double> >         &theCoords,
+             const Handle(TColStd_HArray1OfExtendedString) &theNames,
+             const Handle(TColStd_HArray1OfByte)           &theTypes,
+             const Handle(TColStd_HArray1OfByte)           &theCloseds,
+             const Handle(TColStd_HArray1OfReal)           &theWorkingPlane)
+{
+  SetErrorCode(KO);
+
+  if (theCoords.empty()   || theNames.IsNull() || theTypes.IsNull() ||
+      theCloseds.IsNull() || theWorkingPlane.IsNull()) {
+    return NULL;
+  }
+
+  // Add a new Polyline object
+  Handle(GEOM_Object)   aResult   =
+    GetEngine()->AddObject(GetDocID(), GEOM_POLYLINE2D);
+  Handle(GEOM_Function) aFunction = aResult->AddFunction
+    (GEOMImpl_PolylineDriver::GetID(), POLYLINE2D_PLN_COORDS);
+
+  if (aFunction.IsNull()) {
+    return NULL;
+  }
+
+  // Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_PolylineDriver::GetID()) {
+    return NULL;
+  }
+
+  GEOMImpl_IPolyline2D aCI(aFunction);
+
+  aCI.SetCoords(theCoords);
+  aCI.SetNames(theNames);
+  aCI.SetTypes(theTypes);
+  aCI.SetClosedFlags(theCloseds);
+  aCI.SetWorkingPlaneDbls(theWorkingPlane);
+
+  // Compute the isoline curve
+  try {
+#if OCC_VERSION_LARGE > 0x06010000
+    OCC_CATCH_SIGNALS;
+#endif
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Polyline driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure) {
+    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+    SetErrorCode(aFail->GetMessageString());
+    return NULL;
+  }
+
+  //Make a Python command
+  GEOMImpl_PolylineDumper aDumper(theCoords, theNames, theTypes,
+                                  theCloseds, theWorkingPlane);
+
+  aDumper.Dump(aResult);
+
+  if (aDumper.IsDone() == Standard_False) {
+    SetErrorCode("Python dump failed");
+    return NULL;
+  }
+
+  SetErrorCode(OK);
+  return aResult;
+}
+
+//=============================================================================
+/*!
+ *  MakePolyline2DOnPlane
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakePolyline2DOnPlane
+            (const std::list <std::list <double> >         &theCoords,
+             const Handle(TColStd_HArray1OfExtendedString) &theNames,
+             const Handle(TColStd_HArray1OfByte)           &theTypes,
+             const Handle(TColStd_HArray1OfByte)           &theCloseds,
+             const Handle(GEOM_Object)                     &theWorkingPlane)
+{
+  SetErrorCode(KO);
+
+  if (theCoords.empty()   || theNames.IsNull() || theTypes.IsNull() ||
+      theCloseds.IsNull() || theWorkingPlane.IsNull()) {
+    return NULL;
+  }
+
+  //Add a new Polyline object
+  Handle(GEOM_Object) aResult =
+    GetEngine()->AddObject(GetDocID(), GEOM_POLYLINE2D);
+  Handle(GEOM_Function) aFunction = aResult->AddFunction
+    (GEOMImpl_PolylineDriver::GetID(), POLYLINE2D_PLN_OBJECT);
+
+  if (aFunction.IsNull()) {
+    return NULL;
+  }
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_PolylineDriver::GetID()) {
+    return NULL;
+  }
+
+  Handle(GEOM_Function) aRefPlane = theWorkingPlane->GetLastFunction();
+
+  if (aRefPlane.IsNull()) {
+    return NULL;
+  }
+
+  GEOMImpl_IPolyline2D aCI(aFunction);
+
+  aCI.SetCoords(theCoords);
+  aCI.SetNames(theNames);
+  aCI.SetTypes(theTypes);
+  aCI.SetClosedFlags(theCloseds);
+  aCI.SetWorkingPlane(aRefPlane);
+
+  //Compute the isoline curve
+  try {
+#if OCC_VERSION_LARGE > 0x06010000
+    OCC_CATCH_SIGNALS;
+#endif
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Polyline driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure) {
+    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+    SetErrorCode(aFail->GetMessageString());
+    return NULL;
+  }
+
+  //Make a Python command
+  GEOMImpl_PolylineDumper aDumper(theCoords, theNames, theTypes,
+                                  theCloseds, theWorkingPlane);
+
+  aDumper.Dump(aResult);
+
+  if (aDumper.IsDone() == Standard_False) {
+    SetErrorCode("Python dump failed");
+    return NULL;
+  }
+
+  SetErrorCode(OK);
+  return aResult;
+}
index 15591a64f17b1bbc3bea20e56fcb92693d210432..fe4278cc630b94ac846db8505d9c45408740f401 100644 (file)
@@ -100,6 +100,19 @@ class GEOMImpl_ICurvesOperations : public GEOM_IOperations {
                    const bool                 IsUIso,
                    const double               theParameter);
 
+  Standard_EXPORT Handle(GEOM_Object) MakePolyline2D
+            (const std::list <std::list <double> >         &theCoords,
+             const Handle(TColStd_HArray1OfExtendedString) &theNames,
+             const Handle(TColStd_HArray1OfByte)           &theTypes,
+             const Handle(TColStd_HArray1OfByte)           &theCloseds,
+             const Handle(TColStd_HArray1OfReal)           &theWorkingPlane);
+
+  Standard_EXPORT Handle(GEOM_Object) MakePolyline2DOnPlane
+            (const std::list <std::list <double> >         &theCoords,
+             const Handle(TColStd_HArray1OfExtendedString) &theNames,
+             const Handle(TColStd_HArray1OfByte)           &theTypes,
+             const Handle(TColStd_HArray1OfByte)           &theCloseds,
+             const Handle(GEOM_Object)                     &theWorkingPlane);
 };
 
 #endif
diff --git a/src/GEOMImpl/GEOMImpl_IPolyline2D.cxx b/src/GEOMImpl/GEOMImpl_IPolyline2D.cxx
new file mode 100644 (file)
index 0000000..eb1bcfd
--- /dev/null
@@ -0,0 +1,112 @@
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+
+#include "GEOMImpl_IPolyline2D.hxx"
+
+#include <TColStd_HArray1OfInteger.hxx>
+
+
+//=============================================================================
+/*!
+ *  SetCoords
+ */
+//=============================================================================
+void GEOMImpl_IPolyline2D::SetCoords
+                  (const std::list <std::list <double> > &theValue)
+{
+  const Standard_Integer aNbSec = theValue.size();
+
+  if (aNbSec > 0) {
+    // Compute the total number of points and fill the array of start indices.
+    Standard_Integer                                i;
+    Standard_Integer                                aNbCoords = 0;
+    Handle(TColStd_HArray1OfInteger)                anIndices =
+      new TColStd_HArray1OfInteger(1, aNbSec);
+    Handle(TColStd_HArray1OfReal)                   aCoords;
+    std::list <std::list <double> >::const_iterator aSecIter = theValue.begin();
+
+    for (i = 1; aSecIter != theValue.end(); ++aSecIter, ++i) {
+      anIndices->SetValue(i, aNbCoords + 1);
+      aNbCoords += aSecIter->size();
+    }
+
+    if (aNbCoords > 0) {
+      // Fill the array of coordinates.
+      std::list<double>::const_iterator aCIter;
+
+      aCoords  = new TColStd_HArray1OfReal(1, aNbCoords);
+      aSecIter = theValue.begin();
+
+      for (i = 1; aSecIter != theValue.end(); ++aSecIter) {
+        for (aCIter = aSecIter->begin(); aCIter != aSecIter->end(); ++aCIter) {
+          aCoords->SetValue(i++, *aCIter);
+        }
+      }
+    }
+
+    // Store the coordinates.
+    if (aCoords.IsNull() == Standard_False) {
+      _func->SetRealArray(POLY_ARG_COORDS, aCoords);
+    }
+
+    _func->SetIntegerArray(POLY_ARG_START_INDICES, anIndices);
+  }
+}
+
+//=============================================================================
+/*!
+ *  GetCoords
+ */
+//=============================================================================
+void GEOMImpl_IPolyline2D::GetCoords(std::list <std::list <double> > &theValue)
+{
+  theValue.clear();
+
+  Handle(TColStd_HArray1OfReal)    aCoords   =
+    _func->GetRealArray(POLY_ARG_COORDS);
+  Handle(TColStd_HArray1OfInteger) anIndices =
+    _func->GetIntegerArray(POLY_ARG_START_INDICES);
+
+  if (anIndices.IsNull() == Standard_False) {
+    const Standard_Integer aNbSec = anIndices->Length();
+
+    // Create an empty sections.
+    theValue.resize(aNbSec);
+
+    if (aCoords.IsNull() == Standard_False) {
+      Standard_Integer i;
+      Standard_Integer j;
+      std::list <std::list <double> >::iterator anIt = theValue.begin();
+
+      for (i = anIndices->Lower(); i <= anIndices->Upper(); ++i, ++anIt) {
+        const Standard_Integer iCoord1 = anIndices->Value(i);
+        const Standard_Integer iCoord2 = i + 1 > anIndices->Upper() ?
+          aCoords->Upper() + 1 : anIndices->Value(i + 1);
+
+        for (j = iCoord1; j < iCoord2; ++j) {
+          anIt->push_back(aCoords->Value(j));
+        }
+      }
+    }
+  }
+}
diff --git a/src/GEOMImpl/GEOMImpl_IPolyline2D.hxx b/src/GEOMImpl/GEOMImpl_IPolyline2D.hxx
new file mode 100644 (file)
index 0000000..302e9f8
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//NOTE: This is an interface to a function for the Polyline2D creation.
+
+
+#ifndef _GEOMImpl_IPolyline2D_HXX_
+#define _GEOMImpl_IPolyline2D_HXX_
+
+
+#include <GEOM_GEOMImpl.hxx>
+#include <GEOM_Function.hxx>
+
+#include <list>
+
+#include <TColStd_HArray1OfExtendedString.hxx>
+#include <TColStd_HArray1OfByte.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+
+
+#define POLY_ARG_NAMES         1
+#define POLY_ARG_TYPES         2
+#define POLY_ARG_CLOSEDS       3
+#define POLY_ARG_COORDS        4
+#define POLY_ARG_START_INDICES 5
+#define POLY_ARG_WPLANE_DBLS   6
+#define POLY_ARG_WPLANE_OBJ    7
+
+
+class GEOMIMPL_EXPORT GEOMImpl_IPolyline2D
+{
+ public:
+
+  GEOMImpl_IPolyline2D(Handle(GEOM_Function) theFunction): _func(theFunction) {}
+
+  void SetNames(const Handle_TColStd_HArray1OfExtendedString &theValue)
+              { _func->SetStringArray(POLY_ARG_NAMES, theValue); }
+
+  Handle_TColStd_HArray1OfExtendedString GetNames()
+              { return _func->GetStringArray(POLY_ARG_NAMES); }
+
+  void SetTypes(const Handle_TColStd_HArray1OfByte &theValue)
+              { _func->SetByteArray(POLY_ARG_TYPES, theValue); }
+
+  Handle_TColStd_HArray1OfByte GetTypes()
+              { return _func->GetByteArray(POLY_ARG_TYPES); }
+
+  void SetClosedFlags(const Handle_TColStd_HArray1OfByte &theValue)
+              { _func->SetBooleanArray(POLY_ARG_CLOSEDS, theValue); }
+
+  Handle_TColStd_HArray1OfByte GetClosedFlags()
+              { return _func->GetBooleanArray(POLY_ARG_CLOSEDS); }
+
+  void SetWorkingPlaneDbls(const Handle_TColStd_HArray1OfReal &thePlane)
+              { _func->SetRealArray(POLY_ARG_WPLANE_DBLS, thePlane); }
+
+  Handle_TColStd_HArray1OfReal GetWorkingPlaneDbls()
+              { return _func->GetRealArray(POLY_ARG_WPLANE_DBLS); }
+
+  void SetWorkingPlane(const Handle_GEOM_Function &thePlane)
+              { _func->SetReference(POLY_ARG_WPLANE_OBJ, thePlane); }
+
+  Handle_GEOM_Function GetWorkingPlane()
+              { return _func->GetReference(POLY_ARG_WPLANE_OBJ); }
+
+  void SetCoords(const std::list <std::list <double> > &theValue);
+
+  void GetCoords(std::list <std::list <double> > &theValue);
+
+ private:
+
+  Handle(GEOM_Function) _func;
+};
+
+#endif
index 1eeeaf27763596f0b065a3d9b3bef95f5be62406..1a996c1e514e19efea9155654dabffed4258a108 100644 (file)
 #include "GEOMImpl_PolylineDriver.hxx"
 
 #include "GEOMImpl_ICurveParametric.hxx"
+#include "GEOMImpl_ICurvesOperations.hxx"
 #include "GEOMImpl_IPolyline.hxx"
+#include "GEOMImpl_IPolyline2D.hxx"
 #include "GEOMImpl_Types.hxx"
 #include "GEOM_Function.hxx"
+#include <GEOMUtils.hxx>
+#include <Sketcher_Utils.hxx>
 
 #include <BRepBuilderAPI_MakePolygon.hxx>
 #include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
 #include <Precision.hxx>
 #include <TColgp_Array1OfPnt.hxx>
@@ -38,6 +43,7 @@
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
+#include <gp_Ax3.hxx>
 #include <gp_Pnt.hxx>
 
 //=======================================================================
@@ -59,6 +65,125 @@ GEOMImpl_PolylineDriver::GEOMImpl_PolylineDriver()
 {
 }
 
+//=======================================================================
+//function : MakePolyline2D
+//purpose  :
+//======================================================================= 
+Standard_Integer GEOMImpl_PolylineDriver::MakePolyline2D
+                      (TFunction_Logbook& log) const
+{
+  if (Label().IsNull()) {
+    return 0;
+  }
+
+  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
+  GEOMImpl_IPolyline2D  aCI(aFunction);
+  Standard_Integer      aType = aFunction->GetType();
+  TopoDS_Shape          aShape;
+
+  // Get data.
+  Handle(TColStd_HArray1OfExtendedString) aNames       = aCI.GetNames();
+  Handle(TColStd_HArray1OfByte)           aTypes       = aCI.GetTypes();
+  Handle(TColStd_HArray1OfByte)           aClosedFlags = aCI.GetClosedFlags();
+  std::list <std::list <double> >         aCoords;
+  gp_Ax3                                  aWPlane;
+
+  aCI.GetCoords(aCoords);
+
+  // Check the data validity
+  if (aNames.IsNull()) {
+    return 0;
+  }
+
+  Standard_Integer aNbSections = aNames->Length();
+
+  if (aTypes.IsNull() || aNbSections != aTypes->Length()) {
+    return 0;
+  }
+
+  if (aClosedFlags.IsNull() || aNbSections != aClosedFlags->Length()) {
+    return 0;
+  }
+
+  if (aNbSections != aCoords.size()) {
+    return 0;
+  }
+
+  if (aType == POLYLINE2D_PLN_COORDS) {
+    Handle(TColStd_HArray1OfReal) aPlaneCoords = aCI.GetWorkingPlaneDbls();
+
+    if (aPlaneCoords.IsNull()) {
+      return 0;
+    }
+
+    if (aPlaneCoords->Length() != 9) {
+      return 0;
+    }
+
+    Standard_Integer i = aPlaneCoords->Lower();
+    gp_Pnt aOrigin(aPlaneCoords->Value(i), aPlaneCoords->Value(i + 1),
+                 aPlaneCoords->Value(i + 2));
+    gp_Dir aDirZ(aPlaneCoords->Value(i + 3), aPlaneCoords->Value(i + 4),
+                 aPlaneCoords->Value(i + 5));
+    gp_Dir aDirX(aPlaneCoords->Value(i + 6), aPlaneCoords->Value(i + 7),
+                 aPlaneCoords->Value(i + 8));
+    aWPlane = gp_Ax3(aOrigin, aDirZ, aDirX);
+  } else if (aType == POLYLINE2D_PLN_OBJECT) {
+    Handle(GEOM_Function) aRefFace = aCI.GetWorkingPlane();
+    TopoDS_Shape aShape = aRefFace->GetValue();
+
+    aWPlane = GEOMUtils::GetPosition(aShape);
+  } else {
+    return 0;
+  }
+
+  // Construct a shape.
+  Standard_Integer iN = aNames->Lower();
+  Standard_Integer iT = aTypes->Lower();
+  Standard_Integer iC = aClosedFlags->Lower();
+  std::list <std::list <double> >::const_iterator anIter = aCoords.begin();
+  BRep_Builder aBuilder;
+  Standard_Boolean isEmpty = Standard_True;
+
+  if (aNbSections > 1) {
+    aBuilder.MakeCompound(TopoDS::Compound(aShape));
+  }
+
+  for (; anIter != aCoords.end(); ++anIter, ++iN, ++iT, ++iC) {
+    Standard_Integer aType = aTypes->Value(iT);
+    TopoDS_Shape     aSection;
+
+    if (aType == GEOMImpl_ICurvesOperations::Polyline) {
+      aSection = Sketcher_Utils::MakePolyline
+          (*anIter, aClosedFlags->Value(iC), aWPlane);
+    } else if (aType == GEOMImpl_ICurvesOperations::Interpolation) {
+      aSection = Sketcher_Utils::MakeInterpolation
+        (*anIter, aClosedFlags->Value(iC), aWPlane);
+    }
+
+    if (aNbSections > 1) {
+      // There are multiple sections.
+      if (aSection.IsNull() == Standard_False) {
+        aBuilder.Add(aShape, aSection);
+        isEmpty = Standard_False;
+      }
+    } else {
+      // There is only one section.
+      isEmpty = aSection.IsNull();
+      aShape  = aSection;
+    }
+  }
+
+  if (isEmpty) {
+    return 0;
+  }
+
+  aFunction->SetValue(aShape);
+  log.SetTouched(Label()); 
+
+  return 1;
+}
+
 //=======================================================================
 //function : Execute
 //purpose  :
@@ -67,9 +192,13 @@ Standard_Integer GEOMImpl_PolylineDriver::Execute(TFunction_Logbook& log) const
 {
   if (Label().IsNull()) return 0;    
   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
+  Standard_Integer aType = aFunction->GetType();
+
+  if (aType == POLYLINE2D_PLN_COORDS || aType == POLYLINE2D_PLN_OBJECT) {
+    return MakePolyline2D(log);
+  }
 
   GEOMImpl_IPolyline aCI (aFunction);
-  Standard_Integer aType = aFunction->GetType();
   
   TopoDS_Shape aShape;
 
@@ -166,10 +295,9 @@ GetCreationInformation(std::string&             theOperationName,
   GEOMImpl_ICurveParametric aIP( function );
   Standard_Integer aType = function->GetType();
 
-  theOperationName = "CURVE";
-
   switch ( aType ) {
   case POLYLINE_POINTS:
+    theOperationName = "CURVE";
     AddParam( theParams, "Type", "Polyline");
     if ( aIP.HasData() )
     {
@@ -206,6 +334,103 @@ GetCreationInformation(std::string&             theOperationName,
       AddParam( theParams, "Is closed", aCI.GetIsClosed() );
     }
     break;
+  case POLYLINE2D_PLN_COORDS:
+  case POLYLINE2D_PLN_OBJECT:
+    {
+      theOperationName = "SKETCH";
+
+      GEOMImpl_IPolyline2D                    aP2d(function);
+      Handle(TColStd_HArray1OfExtendedString) aNames = aP2d.GetNames();
+
+      if (aNames.IsNull() == Standard_False) {
+        if (aNames->Length() == 1) {
+          // This is the single curve. Make its full dump.
+          AddParam(theParams, "Name", aNames->Value(aNames->Lower()));
+
+          Handle(TColStd_HArray1OfByte) aTypes = aP2d.GetTypes();
+
+          if (aTypes.IsNull() == Standard_False && aTypes->Length() == 1) {
+            Standard_Integer aType = aTypes->Value(aTypes->Lower());
+
+            if (aType == GEOMImpl_ICurvesOperations::Polyline) {
+              AddParam(theParams, "Type") << "Polyline";
+            } else if (aType == GEOMImpl_ICurvesOperations::Interpolation) {
+              AddParam(theParams, "Type") << "Interpolation";
+            }
+          }
+
+          Handle(TColStd_HArray1OfByte) aCloseds = aP2d.GetClosedFlags();
+
+          if (aCloseds.IsNull() == Standard_False && aCloseds->Length() == 1) {
+            const char *aYesNo =
+              aCloseds->Value(aCloseds->Lower()) ? "Yes" : "No";
+
+            AddParam(theParams, "Is closed", aYesNo);
+          }
+
+          std::list <std::list <double> > aCoords;
+
+          aP2d.GetCoords(aCoords);
+
+          if (aCoords.size() == 1) {
+            AddParam(theParams, "Number of points", aCoords.front().size()/2);
+          }
+        } else {
+          // There are more than 1 curve.
+          Standard_Integer                aNbCurves = aNames->Length();
+          Standard_Integer                i;
+          std::list <std::list <double> > aCoords;
+
+          AddParam(theParams, "Number of curves", aNbCurves);
+          aP2d.GetCoords(aCoords);
+
+          Standard_Integer aNbCoords = aCoords.size();
+          std::list <std::list <double> >::const_iterator
+                           anIt      = aCoords.begin();
+
+          for (i = 0; i < aNbCurves; i++) {
+            TCollection_AsciiString aName("Curve ");
+            TCollection_ExtendedString
+              aValue(aNames->Value(aNames->Lower() + i));
+
+            aName.AssignCat(i + 1);
+
+            if (anIt != aCoords.end()) {
+              aValue.AssignCat(" (");
+              aValue.AssignCat(Standard_Integer(anIt->size()));
+              aValue.AssignCat(" points)");
+              anIt++;
+            }
+
+            AddParam(theParams, aName.ToCString(), aValue);
+          }
+        }
+      }
+
+      if (aType == POLYLINE2D_PLN_COORDS) {
+        Handle(TColStd_HArray1OfReal) aPln = aP2d.GetWorkingPlaneDbls();
+
+        if (aPln.IsNull() == Standard_False && aPln->Length() == 9) {
+          Standard_Integer i = aPln->Lower();
+
+          AddParam( theParams, "Origin")
+            << aPln->Value(i)     << " "
+            << aPln->Value(i + 1) << " "
+            << aPln->Value(i + 2);
+          AddParam( theParams, "OZ")
+            << aPln->Value(i + 3) << " "
+            << aPln->Value(i + 4) << " "
+            << aPln->Value(i + 5);
+          AddParam( theParams, "OX")
+            << aPln->Value(i + 6) << " "
+            << aPln->Value(i + 7) << " "
+            << aPln->Value(i + 8);
+        }
+      } else {
+        AddParam(theParams, "Working plane", aP2d.GetWorkingPlane(), "XOY");
+      }
+    }
+    break;
   default:
     return false;
   }
index 3f816553790ac3299660e74d229a30a3a69b724a..b3f89d91e817c5cad7c847e684ccbdf801bd8520 100644 (file)
@@ -80,6 +80,9 @@ Standard_EXPORT ~GEOMImpl_PolylineDriver() {};
   Standard_EXPORT virtual
   bool GetCreationInformation(std::string&             theOperationName,
                               std::vector<GEOM_Param>& params);
+private:
+
+  Standard_Integer MakePolyline2D(TFunction_Logbook& log) const;
 
 DEFINE_STANDARD_RTTI( GEOMImpl_PolylineDriver )
 };
diff --git a/src/GEOMImpl/GEOMImpl_PolylineDumper.cxx b/src/GEOMImpl/GEOMImpl_PolylineDumper.cxx
new file mode 100644 (file)
index 0000000..05fb9a6
--- /dev/null
@@ -0,0 +1,251 @@
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  File   : GEOMImpl_PolylineDumper.cxx
+//  Author : Sergey KHROMOV
+//  Module : GEOM
+
+
+#include "GEOMImpl_PolylineDumper.hxx"
+#include "GEOMImpl_ICurvesOperations.hxx"
+
+#include <GEOM_PythonDump.hxx>
+
+
+//=======================================================================
+// function : Constructor
+// purpose  : 
+//=======================================================================
+GEOMImpl_PolylineDumper::GEOMImpl_PolylineDumper
+            (const std::list <std::list <double> >         &theCoords,
+             const Handle(TColStd_HArray1OfExtendedString) &theNames,
+             const Handle(TColStd_HArray1OfByte)           &theTypes,
+             const Handle(TColStd_HArray1OfByte)           &theCloseds,
+             const Handle(TColStd_HArray1OfReal)           &thePlnCoords)
+             : myCoords    (theCoords),
+               myNames     (theNames),
+               myTypes     (theTypes),
+               myCloseds   (theCloseds),
+               myPlnCoords (thePlnCoords),
+               myIsDone    (Standard_False)
+{
+  init();
+}
+
+
+//=======================================================================
+// function : Constructor
+// purpose  : 
+//=======================================================================
+GEOMImpl_PolylineDumper::GEOMImpl_PolylineDumper
+            (const std::list <std::list <double> >         &theCoords,
+             const Handle(TColStd_HArray1OfExtendedString) &theNames,
+             const Handle(TColStd_HArray1OfByte)           &theTypes,
+             const Handle(TColStd_HArray1OfByte)           &theCloseds,
+             const Handle(GEOM_Object)                     &theWorkingPlane)
+             : myCoords       (theCoords),
+               myNames        (theNames),
+               myTypes        (theTypes),
+               myCloseds      (theCloseds),
+               myWorkingPlane (theWorkingPlane),
+               myIsDone       (Standard_False)
+{
+  init();
+}
+
+//=======================================================================
+// function : Dump
+// purpose  : 
+//=======================================================================
+Standard_Boolean GEOMImpl_PolylineDumper::Dump
+        (const Handle(GEOM_Object) &theObject)
+{
+  if (theObject.IsNull()) {
+    return Standard_False;
+  }
+
+  if (myIsDone) {
+    Handle(GEOM_Function) aFunction = theObject->GetLastFunction();
+    GEOM::TPythonDump aPD(aFunction);
+
+    aPD << myDescr;
+    aPD << theObject << " = pl.result(";
+
+    if (myWorkingPlane.IsNull()) {
+      // Add coodinates of working plane.
+      Standard_Integer i;
+
+      aPD << "[";
+      for (i = 0; i < 9; ++i) {
+        aPD << myPlnCoords->Value(myPlnCoords->Lower() + i);
+
+        if (i < 8) {
+          aPD << ", ";
+        }
+      }
+      aPD << "]";
+    } else {
+      aPD << myWorkingPlane;
+    }
+
+    aPD << ")";
+  }
+
+  return myIsDone;
+}
+
+//=======================================================================
+// function : init
+// purpose  : 
+//=======================================================================
+void GEOMImpl_PolylineDumper::init()
+{
+  // Check input parameters.
+  if (myCoords.empty() || myNames.IsNull() ||
+      myTypes.IsNull() || myCloseds.IsNull()) {
+    // One or more input parameters are null or empty()
+    return;
+  }
+
+  const Standard_Integer aNbSec = myCoords.size();
+
+  if (aNbSec != myNames->Length() || aNbSec != myTypes->Length() ||
+      aNbSec != myCloseds->Length()) {
+    // Inconsistent data.
+    return;
+  }
+
+  // Check the reference plane
+  if (myPlnCoords.IsNull()) {
+    if (myWorkingPlane.IsNull()) {
+      // Null working plane
+      return;
+    }
+  } else {
+    if (myWorkingPlane.IsNull() == Standard_False) {
+      // Ambiguous working plane
+      return;
+    }
+
+    if (myPlnCoords->Length() != 9) {
+      // Invalid number of plane coordinates.
+      return;
+    }
+  }
+
+  char *aSeparator = "\n\t";
+  Standard_Integer i;
+  std::list <std::list <double> >::const_iterator anIt = myCoords.begin();
+
+  myDescr += "pl = geompy.Polyline2D()";
+
+  // Add sections.
+  for (i = 0; i < aNbSec && anIt != myCoords.end(); ++i, ++anIt) {
+    myDescr += aSeparator;
+    myDescr += "pl.addSection(";
+    // Add name
+    myDescr += "\"";
+    myDescr += myNames->Value(myNames->Lower() + i) + "\", ";
+    // Add type
+    const Standard_Integer aType = myTypes->Value(myTypes->Lower() + i);
+
+    switch (aType) {
+      case GEOMImpl_ICurvesOperations::Polyline:
+        myDescr += "GEOM.Polyline, ";
+        break;
+      case GEOMImpl_ICurvesOperations::Interpolation:
+        myDescr += "GEOM.Interpolation, ";
+        break;
+      default:
+        myDescr.Clear();
+        return;
+        break; // NEVERREACHED
+    }
+
+    // Add Closed flag.
+    if (myCloseds->Value(myCloseds->Lower() + i)) {
+      myDescr += "True";
+    } else {
+      myDescr += "False";
+    }
+
+    // Add points.
+    const Standard_Integer aNbCoords = anIt->size();
+
+    if (aNbCoords > 0) {
+      if (aNbCoords % 2) {
+        // Odd number of coordinates.
+        myDescr.Clear();
+        return;
+      }
+
+      if (aNbCoords <= 4) {
+        // Add 2 points to the same command addSection.
+        myDescr += ", [";
+
+        std::list <double>::const_iterator aCIt = anIt->begin();
+
+        while (aCIt != anIt->end()) {
+          myDescr += *aCIt;
+
+          if (++aCIt != anIt->end()) {
+            myDescr += ", ";
+          }
+        }
+      } else {
+        // Add points to a separate command addPoints.
+        // Add maximum 4 points in a command.
+        std::list <double>::const_iterator aCIt        = anIt->begin();
+        Standard_Integer                   aMaxNbCoord = 8;
+        Standard_Integer                   j           = 1;
+
+        myDescr += ")";
+        myDescr += aSeparator;
+        myDescr += "pl.addPoints([";
+
+        while (aCIt != anIt->end()) {
+          myDescr += *aCIt;
+
+          if (++aCIt != anIt->end()) {
+            if (j == aMaxNbCoord) {
+              // 4 points are added. Add a new command.
+              myDescr += "])";
+              myDescr += aSeparator;
+              myDescr += "pl.addPoints([";
+              j        = 1;
+            } else {
+              myDescr += ", ";
+              j++;
+            }
+          }
+        }
+      }
+
+      myDescr += "]";
+    }
+
+    myDescr += ")";
+  }
+
+  myDescr  += aSeparator;
+  myIsDone  = Standard_True;
+}
diff --git a/src/GEOMImpl/GEOMImpl_PolylineDumper.hxx b/src/GEOMImpl/GEOMImpl_PolylineDumper.hxx
new file mode 100644 (file)
index 0000000..1fe396b
--- /dev/null
@@ -0,0 +1,132 @@
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  File   : GEOMImpl_PolylineDumper.h
+//  Author : Sergey KHROMOV
+
+
+#ifndef _GEOMImpl_PolylineDumper_HXX_
+#define _GEOMImpl_PolylineDumper_HXX_
+
+
+#include "GEOM_GEOMImpl.hxx"
+
+#include <GEOM_Object.hxx>
+
+#include <TColStd_HArray1OfExtendedString.hxx>
+#include <TColStd_HArray1OfByte.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+
+#include <list>
+
+
+/**
+ * This is a helper class to form a dump of a polyline 2d curves creation
+ * algorithm.
+ */
+class GEOMIMPL_EXPORT GEOMImpl_PolylineDumper
+{
+
+public:
+
+  /**
+   * This construcor initializes the object with 2D polyline creation
+   * parameters.
+   *
+   *  \param theCoords the list of coordinates list. theCoordsList[0]
+   *         is the coordinates list of the first section. theCoordsList[1]
+   *         is for the second section etc.
+   *  \param theNames the list of names. The order corresponds to theCoords.
+   *  \param theTypes the list of curve types. The order corresponds to
+   *         theCoords.
+   *  \param theCloseds the list of Closed flags. The order corresponds to
+   *         theCoords.
+   *  \param thePlnCoords 9 double values, defining origin,
+   *         OZ and OX directions of the working plane.
+   */
+  GEOMImpl_PolylineDumper
+            (const std::list <std::list <double> >        &theCoords,
+             const Handle_TColStd_HArray1OfExtendedString &theNames,
+             const Handle_TColStd_HArray1OfByte           &theTypes,
+             const Handle_TColStd_HArray1OfByte           &theCloseds,
+             const Handle_TColStd_HArray1OfReal           &thePlnCoords);
+
+  /**
+   * This construcor initializes the object with 2D polyline creation
+   * parameters.
+   *
+   *  \param theCoords the list of coordinates list. theCoordsList[0]
+   *         is the coordinates list of the first section. theCoordsList[1]
+   *         is for the second section etc.
+   *  \param theNames the list of names. The order corresponds to theCoords.
+   *  \param theTypes the list of curve types. The order corresponds to
+   *         theCoords.
+   *  \param theCloseds the list of Closed flags. The order corresponds to
+   *         theCoords.
+   *  \param theWorkingPlane planar Face or LCS(Marker) of the working plane.
+   */
+  GEOMImpl_PolylineDumper
+            (const std::list <std::list <double> >        &theCoords,
+             const Handle_TColStd_HArray1OfExtendedString &theNames,
+             const Handle_TColStd_HArray1OfByte           &theTypes,
+             const Handle_TColStd_HArray1OfByte           &theCloseds,
+             const Handle_GEOM_Object                     &theWorkingPlane);
+
+  /**
+   * This method returns Standard_True if the dump description is created
+   * successfully.
+   *
+   * \return Standard_True in case of success; Standard_False otherwise.
+   */
+  Standard_Boolean IsDone() const
+  { return myIsDone; }
+
+  /**
+   * This method performs dump of the polyline.
+   *
+   * \param theObject the newly created object.
+   * \return Standard_True in case of success; Standard_False otherwise.
+   */
+  Standard_Boolean Dump(const Handle_GEOM_Object &theObject);
+
+protected:
+
+  /**
+   * This method generates the description required for python dump.
+   * It is called from constructor.
+   */
+  void init();
+
+private:
+
+  const std::list <std::list <double> >  &myCoords;
+  Handle_TColStd_HArray1OfExtendedString  myNames;
+  Handle_TColStd_HArray1OfByte            myTypes;
+  Handle_TColStd_HArray1OfByte            myCloseds;
+  Handle_TColStd_HArray1OfReal            myPlnCoords;
+  Handle_GEOM_Object                      myWorkingPlane;
+  Standard_Boolean                        myIsDone;
+  TCollection_ExtendedString              myDescr;
+
+};
+
+#endif
old mode 100755 (executable)
new mode 100644 (file)
index 0bc7505..0ea9449
 
 #define GEOM_ISOLINE   55
 
+#define GEOM_POLYLINE2D 56
+
 //GEOM_Function types
 
 #define COPY_WITH_REF    1
 #define PARTITION_HALF      2
 #define PARTITION_NO_SELF_INTERSECTIONS 3
 
-#define POLYLINE_POINTS 1
+#define POLYLINE_POINTS       1
+#define POLYLINE2D_PLN_COORDS 2
+#define POLYLINE2D_PLN_OBJECT 3
 
 #define SPLINE_BEZIER            1
 #define SPLINE_INTERPOLATION     2
index f1d2469c0e60293037538300dda6fc8c44754fb2..06d9b66d3bd64a1cf4a6e399f2e92e1a7be69b8e 100644 (file)
@@ -30,6 +30,9 @@
 #include "GEOM_Engine.hxx"
 #include "GEOM_Object.hxx"
 
+#include <TColStd_HArray1OfByte.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+
 //=============================================================================
 /*!
  *   constructor:
@@ -667,3 +670,189 @@ GEOM::GEOM_Object_ptr GEOM_ICurvesOperations_i::Make3DSketcher
 
   return GetObject(anObject);
 }
+
+//=============================================================================
+/*!
+ *  MakePolyline2D
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_ICurvesOperations_i::MakePolyline2D
+                (const GEOM::ListOfListOfDouble &theCoordsList,
+                 const GEOM::string_array       &theNamesList,
+                 const GEOM::short_array        &theTypesList,
+                 const GEOM::ListOfBool         &theClosedList,
+                 const GEOM::ListOfDouble       &theWorkingPlane)
+{
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  // Convert input data
+  Handle(TColStd_HArray1OfExtendedString) aNames   =
+    ConvertStringArray(theNamesList);
+  Handle(TColStd_HArray1OfByte)           aTypes   =
+    ConvertEnumArray(theTypesList);
+  Handle(TColStd_HArray1OfByte)           aCloseds =
+    ConvertBoolArray(theClosedList);
+  std::list <std::list <double> >         aCoords;
+
+  ConvertListListDouble(theCoordsList, aCoords);
+
+  Handle(TColStd_HArray1OfReal) aWorkingPlane;
+  const int                     n = theWorkingPlane.length();
+  int                           i;
+
+  if (n > 0) {
+    aWorkingPlane = new TColStd_HArray1OfReal(1, n);
+
+    for (i = 0; i < n; i++) {
+      aWorkingPlane->SetValue(i + 1, theWorkingPlane[i]);
+    }
+  }
+
+  // Make Polyline
+  Handle(GEOM_Object) anObject = GetOperations()->MakePolyline2D
+            (aCoords, aNames, aTypes, aCloseds, aWorkingPlane);
+
+  if (!GetOperations()->IsDone() || anObject.IsNull()) {
+    return GEOM::GEOM_Object::_nil();
+  }
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  MakePolylineOnPlane
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_ICurvesOperations_i::MakePolyline2DOnPlane
+                (const GEOM::ListOfListOfDouble &theCoordsList,
+                 const GEOM::string_array       &theNamesList,
+                 const GEOM::short_array        &theTypesList,
+                 const GEOM::ListOfBool         &theClosedList,
+                 GEOM::GEOM_Object_ptr           theWorkingPlane)
+{
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  // Convert input data
+  Handle(TColStd_HArray1OfExtendedString) aNames        =
+    ConvertStringArray(theNamesList);
+  Handle(TColStd_HArray1OfByte)           aTypes        =
+    ConvertEnumArray(theTypesList);
+  Handle(TColStd_HArray1OfByte)           aCloseds      =
+    ConvertBoolArray(theClosedList);
+  std::list <std::list <double> >         aCoords;
+  Handle(GEOM_Object)                     aWorkingPlane =
+    GetObjectImpl(theWorkingPlane);
+
+  ConvertListListDouble(theCoordsList, aCoords);
+
+  // Make Polyline
+  Handle(GEOM_Object) anObject = GetOperations()->MakePolyline2DOnPlane
+            (aCoords, aNames, aTypes, aCloseds, aWorkingPlane);
+
+  if (!GetOperations()->IsDone() || anObject.IsNull()) {
+    return GEOM::GEOM_Object::_nil();
+  }
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  ConvertEnumArray
+ */
+//=============================================================================
+Handle(TColStd_HArray1OfByte) GEOM_ICurvesOperations_i::ConvertEnumArray
+                (const GEOM::short_array &theInArray)
+{
+  Handle(TColStd_HArray1OfByte) anOutArray;
+  const int                     n = theInArray.length();
+  int                           i;
+
+  if (n <= 0) {
+    return anOutArray;
+  }
+
+  anOutArray = new TColStd_HArray1OfByte(1, n);
+
+  for (i = 0; i < n; i++) {
+    bool                                  isOK = true;
+    GEOMImpl_ICurvesOperations::CurveType aType;
+
+    switch(theInArray[i]) {
+      case GEOM::Polyline:
+        aType = GEOMImpl_ICurvesOperations::Polyline;
+        break;
+      case GEOM::Bezier:
+        aType = GEOMImpl_ICurvesOperations::Bezier;
+        break;
+      case GEOM::Interpolation:
+        aType = GEOMImpl_ICurvesOperations::Interpolation;
+        break;
+      default:
+        isOK = false;
+        break;
+    }
+
+    if (isOK) {
+      anOutArray->SetValue(i + 1, aType);
+    } else {
+      anOutArray.Nullify();
+      break;
+    }
+  }
+
+  return anOutArray;
+}
+
+//=============================================================================
+/*!
+ *  ConvertBoolArray
+ */
+//=============================================================================
+Handle(TColStd_HArray1OfByte) GEOM_ICurvesOperations_i::ConvertBoolArray
+                (const GEOM::ListOfBool &theInArray)
+{
+  Handle(TColStd_HArray1OfByte) anOutArray;
+  const int                     n = theInArray.length();
+  int                           i;
+
+  if (n <= 0) {
+    return anOutArray;
+  }
+
+  anOutArray = new TColStd_HArray1OfByte(1, n);
+
+  for (i = 0; i < n; i++) {
+    anOutArray->SetValue(i + 1, theInArray[i]);
+  }
+
+  return anOutArray;
+}
+
+//=============================================================================
+/*!
+ *  ConvertListListDouble
+ */
+//=============================================================================
+void GEOM_ICurvesOperations_i::ConvertListListDouble
+            (const GEOM::ListOfListOfDouble        &theInList,
+                   std::list <std::list <double> > &theOutList)
+{
+  const int          n = theInList.length();
+  int                i;
+  std::list <double> anEmptyList;
+
+  for (i = 0; i < n; i++) {
+    theOutList.push_back(anEmptyList);
+
+    const int m = theInList[i].length();
+    int       j;
+
+    for (j = 0; j < m; j++) {
+      theOutList.back().push_back(theInList[i][j]);
+    }
+  }
+}
index c08cb01563848578f94e4282e57082eafcd9d22a..90cbb211497690543ba44c1cd8c47723ac3090a4 100644 (file)
@@ -112,8 +112,35 @@ class GEOM_I_EXPORT GEOM_ICurvesOperations_i :
 
   GEOM::GEOM_Object_ptr Make3DSketcher (const GEOM::ListOfDouble& theCoordinates);
 
+  GEOM::GEOM_Object_ptr MakePolyline2D
+                (const GEOM::ListOfListOfDouble &theCoordsList,
+                 const GEOM::string_array       &theNamesList,
+                 const GEOM::short_array        &theTypesList,
+                 const GEOM::ListOfBool         &theClosedList,
+                 const GEOM::ListOfDouble       &theWorkingPlane);
+
+  GEOM::GEOM_Object_ptr MakePolyline2DOnPlane
+                (const GEOM::ListOfListOfDouble &theCoordsList,
+                 const GEOM::string_array       &theNamesList,
+                 const GEOM::short_array        &theTypesList,
+                 const GEOM::ListOfBool         &theClosedList,
+                 GEOM::GEOM_Object_ptr           theWorkingPlane);
+
   ::GEOMImpl_ICurvesOperations* GetOperations()
   { return (::GEOMImpl_ICurvesOperations*)GetImpl(); }
+
+private:
+
+  Handle(TColStd_HArray1OfByte)
+        ConvertEnumArray(const GEOM::short_array &theInArray);
+
+  Handle(TColStd_HArray1OfByte)
+        ConvertBoolArray(const GEOM::ListOfBool &theInArray);
+
+  void ConvertListListDouble
+            (const GEOM::ListOfListOfDouble        &theCoordsList,
+                   std::list <std::list <double> > &theCoords);
+
 };
 
 #endif
index af7cb5cd4be92d00fff4e67b6fc3960db452f426..51fe6c46e7dc406265bbcbb7d3e5f762b6f12f4e 100644 (file)
@@ -78,25 +78,6 @@ Handle(TColStd_HArray1OfInteger) GEOM_IHealingOperations_i::Convert
   return anOutArray;
 }
 
-//=============================================================================
-/*!
- *  Convert
- */
-//=============================================================================
-Handle(TColStd_HArray1OfExtendedString) GEOM_IHealingOperations_i::Convert
-                                         (const GEOM::string_array& theInArray)
-{
-  Handle(TColStd_HArray1OfExtendedString) anOutArray;
-  int n = theInArray.length();
-  if ( n <= 0 )
-    return anOutArray;
-  anOutArray = new TColStd_HArray1OfExtendedString( 1, n );
-  for ( int i = 0; i < n; i++ )
-    anOutArray->SetValue( i+1, TCollection_ExtendedString( theInArray[i].in() ) );
-
-  return anOutArray;
-}
-
 //=============================================================================
 /*!
  *  ProcessShape
@@ -125,7 +106,8 @@ GEOM::GEOM_Object_ptr GEOM_IHealingOperations_i::ProcessShape (GEOM::GEOM_Object
 
   // Perform
   Handle(GEOM_Object) aNewObject = GetOperations()->ShapeProcess( anObject,
-    Convert( theOperations ), Convert( theParams ), Convert( theValues ) );
+    ConvertStringArray( theOperations ), ConvertStringArray( theParams ),
+    ConvertStringArray( theValues ) );
   if ( !GetOperations()->IsDone() || aNewObject.IsNull() )
     return aGEOMObject._retn();
 
index 8b30c9530dfa9eed8d324a80aa62446dbd5a8591..091358771536e48cda4c46ae4cf760bc23b99c84 100644 (file)
@@ -33,9 +33,6 @@
 
 #include "GEOMImpl_IHealingOperations.hxx"
 
-#include <TColStd_HArray1OfExtendedString.hxx>
-#include <TColStd_HArray1OfInteger.hxx>
-
 class GEOM_I_EXPORT GEOM_IHealingOperations_i :
     public virtual POA_GEOM::GEOM_IHealingOperations,
     public virtual GEOM_IOperations_i
@@ -101,7 +98,6 @@ class GEOM_I_EXPORT GEOM_IHealingOperations_i :
    ::GEOMImpl_IHealingOperations* GetOperations() { return (::GEOMImpl_IHealingOperations*)GetImpl(); }
 
 private:
-         Handle(TColStd_HArray1OfExtendedString) Convert( const GEOM::string_array& );
          Handle(TColStd_HArray1OfInteger)        Convert( const GEOM::short_array& );
 
 };
index 12184fd170ba6f1f4a07ee90fd16c89a9c0df446..9cb5b846978565cf7fc4b41c872b87bed07f9002 100644 (file)
@@ -237,3 +237,28 @@ void GEOM_IOperations_i::UpdateGUIForObject(GEOM::GEOM_Object_ptr theObj)
     }
   }
 }
+
+//=============================================================================
+/*!
+ *  ConvertStringArray
+ */
+//=============================================================================
+Handle(TColStd_HArray1OfExtendedString) GEOM_IOperations_i::ConvertStringArray
+        (const GEOM::string_array &theInArray)
+{
+  Handle(TColStd_HArray1OfExtendedString) anOutArray;
+  const int                               n = theInArray.length();
+  int                                     i;
+
+  if (n <= 0) {
+    return anOutArray;
+  }
+
+  anOutArray = new TColStd_HArray1OfExtendedString( 1, n );
+
+  for (i = 0; i < n; i++) {
+    anOutArray->SetValue(i + 1, TCollection_ExtendedString(theInArray[i].in()));
+  }
+
+  return anOutArray;
+}
index 1d5b7fd5647d237f2fb90d4cf286d59da7295e77..b82b36c68ab7d3f450d37426c6c298e0912fb921 100644 (file)
@@ -52,9 +52,6 @@ class GEOM_I_EXPORT GEOM_IOperations_i : public virtual POA_GEOM::GEOM_IOperatio
   virtual GEOM::GEOM_Object_ptr GetObject(Handle(GEOM_Object) theObject);
   virtual Handle(GEOM_Object) GetObjectImpl(GEOM::GEOM_Object_ptr theObject);
 
-  virtual Handle(TColStd_HSequenceOfTransient)
-               GetListOfObjectsImpl(const GEOM::ListOfGO& theObjects);
-
   virtual void StartOperation();
 
   virtual void FinishOperation();
@@ -66,6 +63,14 @@ class GEOM_I_EXPORT GEOM_IOperations_i : public virtual POA_GEOM::GEOM_IOperatio
 
   virtual void UpdateGUIForObject(GEOM::GEOM_Object_ptr theObj);
 
+protected:
+
+  Handle(TColStd_HSequenceOfTransient)
+               GetListOfObjectsImpl(const GEOM::ListOfGO& theObjects);
+
+  Handle(TColStd_HArray1OfExtendedString)
+               ConvertStringArray(const GEOM::string_array &theInArray);
+
  private:
  
   ::GEOM_IOperations* _impl;
index c0cd25a603a1e2946fdd62bc9c395b403650d9fe..27b194dc265bd449f3335bac5cba121c46dd8caa 100644 (file)
@@ -256,7 +256,7 @@ import math
 import os
 import functools
 
-from salome.geom.gsketcher import Sketcher3D, Sketcher2D
+from salome.geom.gsketcher import Sketcher3D, Sketcher2D, Polyline2D
 
 # service function
 def _toListOfNames(_names, _size=-1):
@@ -2667,6 +2667,25 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
             sk = Sketcher3D (self)
             return sk
 
+        ## Obtain a 2D polyline creation interface
+        #  @return An instance of @ref gsketcher.Polyline2D "Polyline2D" interface
+        #
+        #  @ref tui_3dsketcher_page "Example"
+        def Polyline2D (self):
+            """
+            Obtain a 2D polyline creation interface.
+
+            Example of usage:
+                pl = geompy.Polyline2D()
+                pl.addSection("section 1", GEOM.Polyline, True)
+                pl.addPoints(0, 0, 10, 0, 10, 10)
+                pl.addSection("section 2", GEOM.Interpolation, False)
+                pl.addPoints(20, 0, 30, 0, 30, 10)
+                resultObj = pl.result(WorkingPlane)
+            """
+            pl = Polyline2D (self)
+            return pl
+
         # end of l3_sketcher
         ## @}
 
index 783bfffca5303e43055b84498232295c01838eb9..004e8e63e9a171e558b218f351f3988ee00da3bb 100644 (file)
@@ -1211,3 +1211,145 @@ class Sketcher2D:
         self.myCommand = "Sketcher"
         self.geompyD._autoPublish(face, theName, "face")
         return face
+
+## An interface to build a 2D polyline step-by-step. The polyline can contain
+#  several sections. Each section represents a list of 2d points. As well it
+#  has a name, curve type, either polyline or interpolation (BSpline curve) and
+#  Closed flag.
+#  Use geompy.Polyline2D() method to obtain an instance of this class.
+#  @ingroup sketcher
+class Polyline2D:
+    """
+    An interface to build a 2D polyline step-by-step. The polyline can contain
+    several sections. Each section represents a list of 2d points. As well it
+    has a name, curve type, either polyline or interpolation (BSpline curve) and
+    Closed flag.
+    Use geompy.Polyline2D() method to obtain an instance of this class.
+
+    Example of usage:
+        pl = geompy.Polyline2D()
+        pl.addSection("section 1", GEOM.Polyline, True, [0, 0, 10, 0, 10, 10])
+        pl.addSection("section 2", GEOM.Interpolation, False)
+        pl.addPoints([20, 0, 30, 0, 30, 10])
+        resultObj = pl.result(WorkingPlane)
+    """
+
+    def __init__(self, geompyD):
+        self.geompyD      = geompyD
+        self.myNameList   = []
+        self.myTypeList   = []
+        self.myClosedList = []
+        self.myCoordsList = []
+        pass
+
+    ## Add a new section to the polyline.
+    #
+    #  @param theName the name
+    #  @param theType the type. It can have either CORBA enumeration type
+    #         GEOM.curve_type or a value of type long. Possible input values
+    #         are: GEOM.Polyline(0) and GEOM.Interpolation(2).
+    #  @param theClosed True for closed section; False otherwise
+    #  @param thePoints the list of 2D points coordinates in the form:
+    #         [x1, y1, x2, y2, ..., xN, yN] for N points.
+    def addSection(self, theName, theType, theClosed, thePoints = None):
+        """
+        Add a new section to the polyline.
+
+        Parameters:
+            theName the name
+            theType the type. It can have either CORBA enumeration type
+                    GEOM.curve_type or a value of type long. Possible input
+                    values are: GEOM.Polyline(0) and GEOM.Interpolation(2).
+            theClosed True for closed section; False otherwise
+            thePoints the list of 2D points coordinates in the form:
+                      [x1, y1, x2, y2, ..., xN, yN] for N points.
+
+        Example of usage:
+            pl = geompy.Polyline2D()
+            pl.addSection("section 1", GEOM.Polyline, True, [0, 0, 10, 0, 10, 10])
+            resultObj = pl.result(WorkingPlane)
+        """
+        from salome.geom.geomBuilder import EnumToLong
+        self.myNameList.append(theName)
+        self.myTypeList.append(EnumToLong(theType))
+        self.myClosedList.append(theClosed)
+        if thePoints is None:
+            self.myCoordsList.append([])
+        else:
+            self.myCoordsList.append(thePoints)
+        pass
+
+    ## Add a points to the last added section of the polyline. If there are
+    #  no sections in the polyline it does nothing.
+    #
+    #  @param thePoints the list of 2D points coordinates in the form:
+    #         [x1, y1, x2, y2, ..., xN, yN] for N points.
+    def addPoints(self, thePoints):
+        """
+        Add a points to the last added section of the polyline. If there are
+        no sections in the polyline it does nothing.
+
+        Parameters:
+            thePoints the list of 2D points coordinates in the form:
+                      [x1, y1, x2, y2, ..., xN, yN] for N points.
+
+        Example of usage:
+            pl = geompy.Polyline2D()
+            pl.addSection("section 1", GEOM.Polyline, True)
+            pl.addPoints([0, 0, 10, 0, 10, 10])
+            pl.addPoints([20, 0, 30, 0, 30, 10])
+            resultObj = pl.result(WorkingPlane)
+        """
+        if self.myNameList:
+            self.myCoordsList[-1].extend(thePoints)
+        pass
+
+    ## Obtain the 2D polyline result as a wire or a compound of wires in case
+    #  of several sections defined.
+    #
+    #  @param theWorkingPlane - current Working Plane used for this 2D polyline
+    #  @param theName Object name; when specified, this parameter is used
+    #         for result publication in the study. Otherwise, if automatic
+    #         publication is switched on, default value is used for result name.
+    #
+    #  @return New GEOM_Object, containing the created shape.
+    def result(self, theWorkingPlane=[0, 0, 0, 0, 0, 1, 1, 0, 0], theName=None):
+        """
+        Obtain the 2D polyline result as a wire or a compound of wires in case
+        of several sections defined.
+
+        Parameters:
+            theWorkingPlane current Working Plane used for this 2D polyline
+            theName Object name; when specified, this parameter is used
+                    for result publication in the study. Otherwise, if automatic
+                    publication is switched on, default value is used for result name.
+
+        Returns:
+            New GEOM_Object, containing the created shape.
+
+        Example of usage:
+            pl = geompy.Polyline2D()
+            pl.addSection("section 1", GEOM.Polyline, True, [0, 0, 10, 0, 10, 10])
+            pl.addSection("section 2", GEOM.Interpolation, False)
+            pl.addPoints([20, 0, 30, 0, 30, 10])
+            resultObj = pl.result(WorkingPlane)
+        """
+        from salome.geom.geomBuilder import RaiseIfFailed
+        import GEOM
+        if isinstance(theWorkingPlane, list):
+            aResult = self.geompyD.CurvesOp.MakePolyline2D(
+                         self.myCoordsList, self.myNameList, self.myTypeList,
+                         self.myClosedList, theWorkingPlane)
+        if isinstance(theWorkingPlane, GEOM._objref_GEOM_Object):
+            aResult = self.geompyD.CurvesOp.MakePolyline2DOnPlane(
+                        self.myCoordsList, self.myNameList, self.myTypeList,
+                        self.myClosedList, theWorkingPlane)
+
+        self.myNameList   = []
+        self.myTypeList   = []
+        self.myClosedList = []
+        self.myCoordsList = []
+        RaiseIfFailed("Polyline2D.result", self.geompyD.CurvesOp)
+        self.geompyD._autoPublish(aResult, theName, "polyline")
+
+        return aResult
index f176f9d0b3d59ad345787291d2d6d3393758c36a..0f8ae114eff9e5a19b7626f3879a1693e94cfa6e 100755 (executable)
@@ -45,11 +45,6 @@ INCLUDE_DIRECTORIES(
   ${CMAKE_CURRENT_BINARY_DIR}
   )
 
-IF(SALOME_GEOM_DEBUG_CC)
-  # for debug purposes, to be removed
-  INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/CurveCreator)
-ENDIF()
-
 # additional preprocessor / compiler flags
 ADD_DEFINITIONS(
   ${CAS_DEFINITIONS}
@@ -61,10 +56,6 @@ ADD_DEFINITIONS(
 SET(_link_LIBRARIES
   GEOMBase
   )
-IF(SALOME_GEOM_DEBUG_CC)
-  # for debug purposes, to be removed
-  LIST(APPEND _link_LIBRARIES CurveCreator) 
-ENDIF()
 
 # --- resources ---
 
index c84dc1cf3387ccaf7f7ce87a48548f4f749a6560..a705e0ae2a02f96d0e57cf0c30abc2da149bb174 100644 (file)
 #include <GeometryGUI.h>
 #include "GeometryGUI_Operations.h"
 
-#include <SUIT_Session.h>
 #include <SUIT_Desktop.h>
-#include <SUIT_ViewManager.h>
 #include <SalomeApp_Application.h>
-#include <OCCViewer_ViewWindow.h>
-
-#include <TopTools_MapOfShape.hxx>
-#include <TopExp_Explorer.hxx>
-#include <Precision.hxx>
 
 #include "OperationGUI_PartitionDlg.h"   // Method PARTITION
 #include "OperationGUI_ArchimedeDlg.h"   // Method ARCHIMEDE
 #include "OperationGUI_GetSharedShapesDlg.h"
 #include "OperationGUI_ExtrudedFeatureDlg.h" // Methods EXTRUDED BOSS / CUT
 
-#ifdef DEBUG_CURVE_CREATOR
-// for debug purposes, to be removed
-#include "CurveCreator_Widget.h"
-#include <QVBoxLayout>
-#include <QPushButton>
-#endif
-
 //=======================================================================
 // function : OperationGUI()
 // purpose  : Constructor
@@ -95,36 +81,6 @@ bool OperationGUI::OnGUIEvent (int theCommandID, SUIT_Desktop* parent)
   case GEOMOp::OpExtrudedCut:   (new OperationGUI_ExtrudedFeatureDlg (CUT, getGeometryGUI(), parent))->show(); break;
   case GEOMOp::OpFillet1d:      (new OperationGUI_Fillet1d2dDlg      (getGeometryGUI(), parent, true))->show(); break;
   case GEOMOp::OpFillet2d:      (new OperationGUI_Fillet1d2dDlg      (getGeometryGUI(), parent, false))->show(); break;
-#ifdef DEBUG_CURVE_CREATOR
-  // for debug purposes, to be removed
-  case GEOMOp::OpCurveCreator:
-    {
-      static CurveCreator_Curve *aStaticCurve = NULL;
-
-      if (aStaticCurve == NULL) {
-        aStaticCurve = new CurveCreator_Curve(CurveCreator::Dim2d);
-      }
-      if (CurveCreator::Dim2d == aStaticCurve->getDimension()) {
-        OCCViewer_ViewWindow* vw = (OCCViewer_ViewWindow*)getGeometryGUI()->getApp()->activeViewManager()->getActiveView();
-        vw->onTopView();
-      }
-
-      QDialog     *aDialog     = new QDialog(parent);
-      QVBoxLayout *aMainLO     = new QVBoxLayout;
-      QPushButton *aQuitButton = new QPushButton(tr("Close"));
-      CurveCreator_Widget *aWidget =
-        new CurveCreator_Widget (aDialog, aStaticCurve);
-
-      connect(aQuitButton, SIGNAL(clicked()), aDialog, SLOT(close()));
-      aMainLO->addWidget(aWidget);
-      aMainLO->addWidget(aQuitButton);
-
-      aDialog->setLayout(aMainLO);
-      aDialog->setAttribute(Qt::WA_DeleteOnClose);
-      aDialog->show();
-    }
-    break;
-#endif
   default:
     app->putInfo(tr("GEOM_PRP_COMMAND").arg(theCommandID));
   }
index 257c2dd1e3127eb4575124d15b109ce38b8baeca..ef7e8748005e966c6d7dc52dd57c5700e7ab1ec7 100755 (executable)
@@ -43,13 +43,16 @@ SET(_link_LIBRARIES
 # --- headers ---
 
 SET(SKETCHER_HEADERS
+  Sketcher.hxx
   Sketcher_Profile.hxx
+  Sketcher_Utils.hxx
   )
 
 # --- sources ---
 
 SET(SKETCHER_SOURCES
   Sketcher_Profile.cxx
+  Sketcher_Utils.cxx
   )
 
 # --- rules ---
diff --git a/src/SKETCHER/Sketcher.hxx b/src/SKETCHER/Sketcher.hxx
new file mode 100644 (file)
index 0000000..09602ce
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  File   : Sketcher.hxx
+//  Author : Sergey KHROMOV
+
+#ifndef _SKETCHER_HXX_
+#define _SKETCHER_HXX_
+
+#if defined WIN32
+#  if defined SKETCHER_SALOME_EXPORTS || defined SKETCHER_EXPORTS || defined GEOMSketcher_EXPORTS || defined GEOMSKETCHER_EXPORTS
+#    define SKETCHER_SALOME_EXPORT _declspec( dllexport )
+#  else
+#    define SKETCHER_SALOME_EXPORT _declspec( dllimport )
+#  endif
+#else
+#  define SKETCHER_SALOME_EXPORT
+#endif
+
+#endif // SKETCHER_HXX
\ No newline at end of file
index ed792f83b2042950b09e3a95685a5917dfec5a31..8d36b639b20442dc9282bc1f4fd6e045144b7e79 100644 (file)
 //  File   : Sketcher_Profile.h
 //  Author : Damien COQUERET
 
-#if defined WIN32
-#  if defined SKETCHER_SALOME_EXPORTS || defined SKETCHER_EXPORTS || defined GEOMSketcher_EXPORTS || defined GEOMSKETCHER_EXPORTS
-#    define SKETCHER_SALOME_EXPORT _declspec( dllexport )
-#  else
-#    define SKETCHER_SALOME_EXPORT _declspec( dllimport )
-#  endif
-#else
-#  define SKETCHER_SALOME_EXPORT
-#endif
 
+#ifndef _Sketcher_Profile_HXX_
+#define _Sketcher_Profile_HXX_
+
+
+#include "Sketcher.hxx"
 #include <TopoDS_Shape.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TColStd_Array1OfAsciiString.hxx>
@@ -63,3 +59,5 @@ private:
 private:
   TCollection_AsciiString myCommand;
 };
+
+#endif
diff --git a/src/SKETCHER/Sketcher_Utils.cxx b/src/SKETCHER/Sketcher_Utils.cxx
new file mode 100644 (file)
index 0000000..725a985
--- /dev/null
@@ -0,0 +1,187 @@
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  File   : Sketcher_Utils.cxx
+//  Author : Sergey KHROMOV
+//  Module : GEOM
+
+
+#include "Sketcher_Utils.hxx"
+
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <ElSLib.hxx>
+#include <GeomAPI_Interpolate.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+#include <TopoDS_Wire.hxx>
+
+const double POINT_CONFUSION_TOLERANCE = 0.0001;
+
+
+//=======================================================================
+// function : MakePolyline
+// purpose  : 
+//=======================================================================
+TopoDS_Shape Sketcher_Utils::MakePolyline
+                              (const std::list <double> &theCoords2D,
+                               const Standard_Boolean    IsClosed,
+                               const gp_Ax3             &thePlane)
+{
+  std::list <gp_Pnt> aPoints;
+  TopoDS_Shape       aResult;
+
+  To3D(theCoords2D, thePlane, aPoints);
+
+  Standard_Integer aNbPnts = aPoints.size();
+
+  if (aNbPnts > 1) {
+    if (IsClosed &&
+        aPoints.front().IsEqual(aPoints.back(), POINT_CONFUSION_TOLERANCE)) {
+      // The polyline should be closed, first and last points are confused.
+      // Remove the last point.
+      aPoints.pop_back();
+      --aNbPnts;
+    }
+  }
+
+  if (aNbPnts == 1) {
+    // The result is vertex.
+    aResult = BRepBuilderAPI_MakeVertex(aPoints.front()).Vertex();
+  } else if (aNbPnts > 1) {
+    // There are several points. Make a polyline.
+    std::list <gp_Pnt>::const_iterator anIter    = aPoints.begin();
+    TopoDS_Vertex                      aVtxFirst =
+                       BRepBuilderAPI_MakeVertex(*anIter).Vertex();
+    TopoDS_Vertex                      aVtx[2];
+    TopoDS_Edge                        aSegment;
+    BRepBuilderAPI_MakeWire            aMkWire;
+
+    aVtx[0] = aVtxFirst;
+
+    for (++anIter; anIter != aPoints.end(); ++anIter) {
+      aVtx[1]  = BRepBuilderAPI_MakeVertex(*anIter).Vertex();
+      aSegment = BRepBuilderAPI_MakeEdge(aVtx[0], aVtx[1]).Edge();
+      aMkWire.Add(aSegment);
+      aVtx[0]  = aVtx[1];
+    }
+
+    if (IsClosed) {
+      // Create a closing segment.
+      aSegment = BRepBuilderAPI_MakeEdge(aVtx[0], aVtxFirst).Edge();
+      aMkWire.Add(aSegment);
+    }
+
+    aResult = aMkWire.Wire();
+  }
+
+  return aResult;
+}
+
+//=======================================================================
+// function : MakeInterpolation
+// purpose  : 
+//=======================================================================
+TopoDS_Shape Sketcher_Utils::MakeInterpolation
+                              (const std::list <double> &theCoords2D,
+                               const Standard_Boolean    IsClosed,
+                               const gp_Ax3             &thePlane)
+{
+  std::list <gp_Pnt> aPoints;
+  TopoDS_Shape       aResult;
+
+  To3D(theCoords2D, thePlane, aPoints);
+
+  Standard_Integer aNbPnts = aPoints.size();
+
+  if (aNbPnts > 1) {
+    if (IsClosed &&
+        aPoints.front().IsEqual(aPoints.back(), POINT_CONFUSION_TOLERANCE)) {
+      // The polyline should be closed, first and last points are confused.
+      // Remove the last point.
+      aPoints.pop_back();
+      --aNbPnts;
+    }
+  }
+
+  if (aNbPnts == 1) {
+    // The result is vertex.
+    aResult = BRepBuilderAPI_MakeVertex(aPoints.front()).Vertex();
+  } else if (aNbPnts > 1) {
+    std::list <gp_Pnt>::const_iterator anIter        = aPoints.begin();
+    Handle(TColgp_HArray1OfPnt)        aHCurvePoints =
+      new TColgp_HArray1OfPnt(1, aNbPnts);
+    Standard_Integer                   i;
+
+    for (i = 1; anIter != aPoints.end(); ++anIter, ++i) {
+      aHCurvePoints->SetValue(i, *anIter);
+    }
+
+    // Compute BSpline
+    Standard_Real       aTol = Precision::Confusion();
+    GeomAPI_Interpolate aGBC(aHCurvePoints, IsClosed, aTol);
+
+    aGBC.Perform();
+
+    if (aGBC.IsDone()) {
+      TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aGBC.Curve()).Edge();
+      aResult = BRepBuilderAPI_MakeWire(anEdge).Wire();
+    }
+  }
+
+  return aResult;
+}
+
+//=======================================================================
+// function : To3D
+// purpose  : 
+//=======================================================================
+void Sketcher_Utils::To3D(const std::list <double> &theCoords2D,
+                          const gp_Ax3             &thePlane,
+                                std::list <gp_Pnt> &thePoints)
+{
+  thePoints.clear();
+
+  if (theCoords2D.empty() || theCoords2D.size() % 2 == 1) {
+    // Odd number of coordinates or empty list. Invalid case.
+    return;
+  }
+
+  std::list <double>::const_iterator anIter = theCoords2D.begin();
+  Standard_Real    aX     = *anIter;
+  Standard_Real    aY     = *(++anIter);
+  gp_Pnt           aPLast = ElSLib::PlaneValue (aX, aY, thePlane);
+  gp_Pnt           aPnt;
+
+  thePoints.push_back(aPLast);
+
+  for (++anIter; anIter != theCoords2D.end(); ++anIter) {
+    aX   = *anIter;
+    aY   = *(++anIter);
+    aPnt =  ElSLib::PlaneValue (aX, aY, thePlane);
+
+    if (!aPLast.IsEqual(aPnt, POINT_CONFUSION_TOLERANCE)) {
+      thePoints.push_back(aPnt);
+      aPLast = aPnt;
+    }
+  }
+}
diff --git a/src/SKETCHER/Sketcher_Utils.hxx b/src/SKETCHER/Sketcher_Utils.hxx
new file mode 100644 (file)
index 0000000..7536011
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  File   : Sketcher_Utils.h
+//  Author : Sergey KHROMOV
+
+
+#ifndef _Sketcher_Utils_HXX_
+#define _Sketcher_Utils_HXX_
+
+
+#include "Sketcher.hxx"
+
+#include <gp_Pnt.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include <list>
+
+
+class gp_Ax3;
+
+
+/**
+ * This class represents a set of utils needed to compute sketcher geometry.
+ */
+class SKETCHER_SALOME_EXPORT Sketcher_Utils
+{
+
+public:
+
+  /**
+   * This method makes a shape from the list of 2D coordinates on the working
+   * plane. The result represents a vertex if there is only one point
+   * in the contour. If there are more then one points the result is a wire
+   * consisting of linear segments between points. It is either closed or not
+   * depending on the flag IsClosed. In case of failure the result is a null
+   * shape.
+   *
+   * \param theCoords2D is the list of coordinates in the form x1, y1, x2, y2,
+   *        ..., xN, yN for N 2D points.
+   * \param IsClosed if Standard_True the first and last points are connected
+   *        to form the closed contour.
+   * \param thePlane the working plane coordinate system.
+   * \return the result polyline.
+   */
+  static TopoDS_Shape MakePolyline(const std::list <double> &theCoords2D,
+                                   const Standard_Boolean    IsClosed,
+                                   const gp_Ax3             &thePlane);
+
+  /**
+   * This method makes a shape from the list of 2D coordinates on the working
+   * plane. The result represents a vertex if there is only one point
+   * in the contour. If there are more then one points the result is a wire
+   * consisting of a points interpolation BSpline curve. It is either closed
+   * or not depending on the flag IsClosed. In case of failure the result is
+   * a null shape.
+   *
+   * \param theCoords2D is the list of coordinates in the form x1, y1, x2, y2,
+   *        ..., xN, yN for N 2D points.
+   * \param IsClosed if Standard_True the first and last points are connected
+   *        to form the closed contour.
+   * \param thePlane the working plane coordinate system.
+   * \return the result interpolation wire.
+   */
+  static TopoDS_Shape MakeInterpolation(const std::list <double> &theCoords2D,
+                                        const Standard_Boolean    IsClosed,
+                                        const gp_Ax3             &thePlane);
+
+  /**
+   * This method converts the list of 2D point coordinates into 3D points
+   * basing on the working plane. The result list contains not confused points.
+   *
+   * \param theCoords2D is the list of coordinates in the form x1, y1, x2, y2,
+   *        ..., xN, yN for N 2D points.
+   * \param thePlane the working plane coordinate system.
+   * \param thePoints the list of 3D points.
+   */
+  static void To3D(const std::list <double> &theCoords2D,
+                   const gp_Ax3             &thePlane,
+                         std::list <gp_Pnt> &thePoints);
+
+};
+
+#endif