From: skv Date: Mon, 8 Sep 2014 12:07:16 +0000 (+0400) Subject: 0022661: EDF GEOM: [HYDRO] Integration of the polyline editor in GEOM X-Git-Tag: V7_5_0a1~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=8866b5fcd5529bf033ebfb845dafdbaf33d3899c;p=modules%2Fgeom.git 0022661: EDF GEOM: [HYDRO] Integration of the polyline editor in GEOM --- diff --git a/CMakeLists.txt b/CMakeLists.txt index d741a55cc..91ef62ccb 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 index 000000000..8b7925607 --- /dev/null +++ b/doc/salome/examples/polyline.py @@ -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 index 000000000..532817c40 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 index 000000000..9a6c1b9e5 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 index 000000000..69df41e8f Binary files /dev/null and b/doc/salome/gui/GEOM/images/polyline_dlg_edit_section.png differ diff --git a/doc/salome/gui/GEOM/input/creating_basic_go.doc b/doc/salome/gui/GEOM/input/creating_basic_go.doc index 6693b469d..efdff9511 100644 --- a/doc/salome/gui/GEOM/input/creating_basic_go.doc +++ b/doc/salome/gui/GEOM/input/creating_basic_go.doc @@ -15,6 +15,7 @@ geometrical objects as:
  • \subpage create_isoline_page
  • \subpage create_sketcher_page
  • \subpage create_3dsketcher_page
  • +
  • \subpage create_polyline_page
  • \subpage create_vector_page
  • \subpage create_plane_page
  • \subpage create_lcs_page
  • diff --git a/doc/salome/gui/GEOM/input/creating_polyline.doc b/doc/salome/gui/GEOM/input/creating_polyline.doc new file mode 100644 index 000000000..7ec36434d --- /dev/null +++ b/doc/salome/gui/GEOM/input/creating_polyline.doc @@ -0,0 +1,107 @@ +/*! + +\page create_polyline_page 2D Polyline + +The 2D Polyline allows drawing arbitrary 2D shapes. + +To create a 2D Polyline select in the main menu New Entity -> Basic -> 2D Polyline. + +\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 Global coordinate system +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 Import polyline 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 +- Insert new section +- Addition mode +- Modification mode - not implemented +- Detection mode - not implemented +- \b Remove +- Join selected sections + +Undo/Redo buttons allows to undo/redo changes of the polyline. + +Insert new section 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. + +Addition mode 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. + +Modification mode and Detection mode 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. + +Join selected sections 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: +- Join all sections - join all defined sections into the first one. +- \b Join - join sections. Available if two or more sections are selected. + +In Addition mode: +- Join all sections - join all defined sections into the first one. + +In Modification mode: +- Join all sections - join all defined sections into the first one. +- \b Join - join sections. Available if two or more sections are selected. +- Clear all - remove all sections. Available if at least one section is selected. +- Set closed - set all selected section's Closed flag. Available if at least one section is selected. +- Set open - reset all selected section's Closed flag. Available if at least one section is selected. +- Set polyline - set all selected section's type to Polyline. Available if at least one section is selected. +- Set spline - set all selected section's type to Spline. Available if at least one section is selected. + +In Detection mode: +- Join all sections - join all defined sections into the first one. +- \b Join - join sections. Available if two or more sections are selected. + +

    TUI Commands

    + + +To create the 2D polyline in TUI Polyline2D interface is used. + +pl = geompy.Polyline2D() - returns an instance of Polyline2D interface pl. + +See the \ref gsketcher.Polyline2D "Polyline2D" interface documentation for more information. + +Our TUI Scripts 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 index 000000000..ff83b9053 --- /dev/null +++ b/doc/salome/gui/GEOM/input/tui_polyline.doc @@ -0,0 +1,6 @@ +/*! + +\page tui_polyline_page 2D Polyline +\tui_script{polyline.py} + +*/ diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 076f4fed4..8863bae26 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -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_array; - typedef sequence short_array; - typedef sequence ListOfBool; - typedef sequence ListOfLong; - typedef sequence ListOfDouble; + typedef sequence string_array; + typedef sequence short_array; + typedef sequence ListOfBool; + typedef sequence ListOfLong; + typedef sequence ListOfDouble; + typedef sequence 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: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7c10ef0d4..b4f792af1 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 ) diff --git a/src/CurveCreator/CMakeLists.txt b/src/CurveCreator/CMakeLists.txt index 34582d31c..15677b68c 100644 --- a/src/CurveCreator/CMakeLists.txt +++ b/src/CurveCreator/CMakeLists.txt @@ -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) diff --git a/src/CurveCreator/CurveCreator.hxx b/src/CurveCreator/CurveCreator.hxx index 74a3faec4..9cd7ec720 100644 --- a/src/CurveCreator/CurveCreator.hxx +++ b/src/CurveCreator/CurveCreator.hxx @@ -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 @@ -24,29 +24,30 @@ #define _CurveCreator_HeaderFile #include +#include +#include + +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 Coordinates; + //! List of sections + typedef std::deque Sections; + + // List of positioned points (points with coordinates) + typedef std::list PosPointsList; + //! Map of sections with positioned points + typedef std::map SectionsMap; }; #endif diff --git a/src/CurveCreator/CurveCreator_Curve.cxx b/src/CurveCreator/CurveCreator_Curve.cxx index b4fa90ffc..e20705c46 100644 --- a/src/CurveCreator/CurveCreator_Curve.cxx +++ b/src/CurveCreator/CurveCreator_Curve.cxx @@ -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 @@ -21,8 +21,21 @@ // 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 +#include +#include +#include +#include +#include +#include +#include #include @@ -30,24 +43,995 @@ // 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& theSections ) +{ + bool res = false; + if ( theSections.empty() ) + return res; + + int anISectionMain = theSections.front(); + CurveCreator_Section* aSectionMain = getSection( anISectionMain ); + + std::list 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::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& 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 > aConvPoints; + convert( thePoints, aConvPoints ); + std::map >::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& thePointIds ) +{ + bool aRes = false; + + CurveCreator_Section* aSection = getSection( theSectionId ); + if ( !aSection ) + return aRes; + + std::list aSectionPoints = thePointIds; + aSectionPoints.sort(); + std::list::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 >& 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 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; + } } diff --git a/src/CurveCreator/CurveCreator_Curve.hxx b/src/CurveCreator/CurveCreator_Curve.hxx index 309d06a84..adcfc87a8 100644 --- a/src/CurveCreator/CurveCreator_Curve.hxx +++ b/src/CurveCreator/CurveCreator_Curve.hxx @@ -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 @@ -23,23 +23,32 @@ #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 +#include + +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 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& 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& 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& 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 > &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 index 559eabd5a..000000000 --- a/src/CurveCreator/CurveCreator_CurveEditor.cxx +++ /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 index 32aa00948..000000000 --- a/src/CurveCreator/CurveCreator_CurveEditor.hxx +++ /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 - -/** - * The CurveCreator_CurveEditor is designed to manage of - * editing operations of CurveCreator_Curve class. - */ -class CURVECREATOR_EXPORT CurveCreator_CurveEditor -{ - -private: - - typedef std::list 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 diff --git a/src/CurveCreator/CurveCreator_Diff.cxx b/src/CurveCreator/CurveCreator_Diff.cxx index 22f099e11..d1a7dc322 100644 --- a/src/CurveCreator/CurveCreator_Diff.cxx +++ b/src/CurveCreator/CurveCreator_Diff.cxx @@ -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& 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 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::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 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::iterator anIter = aListOfInd.begin(); if (isSetType) { - aValue = theCurve->getType(*anIter); + aValue = theCurve->getSectionType(*anIter); } else { aValue = theCurve->isClosed(*anIter); } diff --git a/src/CurveCreator/CurveCreator_Diff.hxx b/src/CurveCreator/CurveCreator_Diff.hxx index e56b294f2..f55f5306f 100644 --- a/src/CurveCreator/CurveCreator_Diff.hxx +++ b/src/CurveCreator/CurveCreator_Diff.hxx @@ -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: *
      *
    • Clear
    • - *
    • Join (without arguments)
    • *
    */ - 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: *
  • SetType
  • *
  • SetClosed
  • *
  • MoveSection
  • - *
  • Join (with 2 int arguments)
  • * */ 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: *
      - *
    • RemovePoints
    • + *
    • Join (with a list of int arguments)
    • *
    */ bool init(const CurveCreator_Curve *theCurve, const CurveCreator_Operation::Type theType, - const int theIntParam1, - const int theIntParam2, - const int theIntParam3); + const std::list& 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: *
      - *
    • AddPoints
    • + *
    • AddSection
    • *
    */ 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: *
      - *
    • InsertPoints
    • - *
    • SetCoordinates
    • + *
    • RenameSection
    • *
    */ 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: *
      - *
    • AddSection
    • + *
    • RemovePoints
    • *
    */ 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: *
      - *
    • RenameSection
    • + *
    • RemovePoints
    • *
    */ 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 index 000000000..22ae3990c --- /dev/null +++ b/src/CurveCreator/CurveCreator_Displayer.cxx @@ -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 index 000000000..f65e9d2ec --- /dev/null +++ b/src/CurveCreator/CurveCreator_Displayer.hxx @@ -0,0 +1,33 @@ +#ifndef CURVECREATOR_DISPLAYER_H +#define CURVECREATOR_DISPLAYER_H + +#include "CurveCreator_Macro.hxx" + +#include +#include + +#include + +class CURVECREATOR_EXPORT CurveCreator_Displayer +{ +typedef std::vector 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 index fc73f56e7..000000000 --- a/src/CurveCreator/CurveCreator_ICurve.cxx +++ /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 - -//======================================================================= -// 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; -} diff --git a/src/CurveCreator/CurveCreator_ICurve.hxx b/src/CurveCreator/CurveCreator_ICurve.hxx index ca662be1d..9effa478a 100644 --- a/src/CurveCreator/CurveCreator_ICurve.hxx +++ b/src/CurveCreator/CurveCreator_ICurve.hxx @@ -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 @@ -17,170 +17,189 @@ // 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 +#include +#include +#include -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 SectionToPoint; + typedef std::deque SectionToPointList; - //! List of curves - typedef std::deque 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& 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& 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& 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 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 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 index 4fd4a29fa..000000000 --- a/src/CurveCreator/CurveCreator_Listener.hxx +++ /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 diff --git a/src/CurveCreator/CurveCreator_Macro.hxx b/src/CurveCreator/CurveCreator_Macro.hxx index 9e6c31c68..ec814eb49 100644 --- a/src/CurveCreator/CurveCreator_Macro.hxx +++ b/src/CurveCreator/CurveCreator_Macro.hxx @@ -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 index bb15571e8..000000000 --- a/src/CurveCreator/CurveCreator_NewPointDlg.cxx +++ /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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 index a86189e54..000000000 --- a/src/CurveCreator/CurveCreator_NewPointDlg.h +++ /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 - -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 diff --git a/src/CurveCreator/CurveCreator_NewSectionDlg.cxx b/src/CurveCreator/CurveCreator_NewSectionDlg.cxx old mode 100755 new mode 100644 index 275a94625..f5f602a3c --- a/src/CurveCreator/CurveCreator_NewSectionDlg.cxx +++ b/src/CurveCreator/CurveCreator_NewSectionDlg.cxx @@ -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 #include @@ -31,21 +31,27 @@ #include #include -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() diff --git a/src/CurveCreator/CurveCreator_NewSectionDlg.h b/src/CurveCreator/CurveCreator_NewSectionDlg.h old mode 100755 new mode 100644 index 7f028f20e..d37ed1176 --- a/src/CurveCreator/CurveCreator_NewSectionDlg.h +++ b/src/CurveCreator/CurveCreator_NewSectionDlg.h @@ -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 @@ -21,10 +21,11 @@ #define CURVECREATOR_NEWSECTION_H #include "CurveCreator.hxx" +#include "CurveCreator_ICurve.hxx" #include -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; }; diff --git a/src/CurveCreator/CurveCreator_Operation.cxx b/src/CurveCreator/CurveCreator_Operation.cxx index 2e4b6416a..173e1c881 100644 --- a/src/CurveCreator/CurveCreator_Operation.cxx +++ b/src/CurveCreator/CurveCreator_Operation.cxx @@ -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 #include @@ -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 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::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 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: diff --git a/src/CurveCreator/CurveCreator_Operation.hxx b/src/CurveCreator/CurveCreator_Operation.hxx index a74ac19ca..855d0da2a 100644 --- a/src/CurveCreator/CurveCreator_Operation.hxx +++ b/src/CurveCreator/CurveCreator_Operation.hxx @@ -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 @@ -24,8 +24,11 @@ #define _CurveCreator_Operation_HeaderFile #include "CurveCreator.hxx" +#include "CurveCreator_ICurve.hxx" +#include "CurveCreator_PosPoint.hxx" #include +#include class CurveCreator_Curve; @@ -74,7 +77,6 @@ public: * It is applicable to the following operations: *
      *
    • Clear
    • - *
    • Join (without arguments)
    • *
    * @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: *
      + *
    • Join (with a list of int arguments)
    • + *
    + * @return true in case of success; false otherwise. + */ + bool init(const Type theType, const std::list theParamList); + + /** + * This method initializes the object with an operation with + * list of pairs of integer parameters. + * It is applicable to the following operations: + *
      *
    • RemovePoints
    • *
    * @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: *
      - *
    • AddSection
    • *
    • InsertPoints
    • - *
    • SetCoordinates
    • *
    * @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 index 000000000..230137423 --- /dev/null +++ b/src/CurveCreator/CurveCreator_PosPoint.hxx @@ -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 diff --git a/src/CurveCreator/CurveCreator_Section.hxx b/src/CurveCreator/CurveCreator_Section.hxx index 0eafa0629..68b03aaa7 100644 --- a/src/CurveCreator/CurveCreator_Section.hxx +++ b/src/CurveCreator/CurveCreator_Section.hxx @@ -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 index 000000000..b40760511 --- /dev/null +++ b/src/CurveCreator/CurveCreator_TableView.cxx @@ -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 + +#include +#include + +#include + +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( 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( 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 index 000000000..4565ab5d7 --- /dev/null +++ b/src/CurveCreator/CurveCreator_TableView.h @@ -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 +#include + +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 diff --git a/src/CurveCreator/CurveCreator_TreeView.cxx b/src/CurveCreator/CurveCreator_TreeView.cxx old mode 100755 new mode 100644 index 1b7fa9587..36d1dfcfb --- a/src/CurveCreator/CurveCreator_TreeView.cxx +++ b/src/CurveCreator/CurveCreator_TreeView.cxx @@ -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 #include @@ -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 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(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(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& theList ) { CurveCreator_TreeViewModel* aModel = dynamic_cast(model()); @@ -378,19 +371,7 @@ void CurveCreator_TreeView::setSelectedSections( const QList& 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 >& thePointsList ) -{ - CurveCreator_TreeViewModel* aModel = dynamic_cast(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 &s1, const QPair &s2) return s1.second < s2.second; } -QList< QPair< int, int > > CurveCreator_TreeView::getSelectedPoints() const -{ - QList< QPair< int, int > > aPoints; - CurveCreator_TreeViewModel* aModel = dynamic_cast(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( 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(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(model()); if( aModel ) aModel->setCurve(theCurve); reset(); } + +void CurveCreator_TreeView::reset() +{ + QList aSelSections = getSelectedSections(); + QTreeView::reset(); + setSelectedSections(aSelSections); +} diff --git a/src/CurveCreator/CurveCreator_TreeView.h b/src/CurveCreator/CurveCreator_TreeView.h old mode 100755 new mode 100644 index 09929bf35..be00a75d3 --- a/src/CurveCreator/CurveCreator_TreeView.h +++ b/src/CurveCreator/CurveCreator_TreeView.h @@ -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 @@ -23,12 +23,12 @@ #include #include -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 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 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& theList ); - void setSelectedPoints( const QList< QPair >& 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 index ec8fd5898..000000000 --- a/src/CurveCreator/CurveCreator_UndoOptsDlg.cxx +++ /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 -#include -#include -#include -#include -#include -#include - -#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 index 86aa87aa3..000000000 --- a/src/CurveCreator/CurveCreator_UndoOptsDlg.h +++ /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 - -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 index 000000000..146676c95 --- /dev/null +++ b/src/CurveCreator/CurveCreator_Utils.cxx @@ -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 + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#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 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::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 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::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 aSelectedPoints; + gp_Pnt aPnt; + std::map 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 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; iAddOrRemoveSelected( 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 index 000000000..8dddaf2ff --- /dev/null +++ b/src/CurveCreator/CurveCreator_Utils.hxx @@ -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 +#include // TODO: remove +#include +#include +#include +#include +#include + +#include +#include // 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.
    + * - 1 origin of the plane is fixed. The plane is defined by 1 or several + * coincident points.
    + * - 2 origin + OX axis of the plane is fixed. The plane is defined by 2 + * or more points that lie on a particular line.
    + * - 3 plane is fixed. Plane is defined by 3 not coincident points.
    + * + * \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 index 000000000..d11598e25 --- /dev/null +++ b/src/CurveCreator/CurveCreator_UtilsICurve.cxx @@ -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 + +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 >& theConvPoints ) +{ + theConvPoints.clear(); + + CurveCreator_ICurve::SectionToPointList::const_iterator anIt = thePoints.begin(), + aLast = thePoints.end(); + QList 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( 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 index 000000000..96b4e454b --- /dev/null +++ b/src/CurveCreator/CurveCreator_UtilsICurve.hxx @@ -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 + +#include +#include + +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 >& 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 diff --git a/src/CurveCreator/CurveCreator_Widget.cxx b/src/CurveCreator/CurveCreator_Widget.cxx index 180284fc1..9cd21e3b7 100644 --- a/src/CurveCreator/CurveCreator_Widget.cxx +++ b/src/CurveCreator/CurveCreator_Widget.cxx @@ -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 @@ -19,25 +19,21 @@ #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 +#include "CurveCreator_Utils.hxx" +#include "CurveCreator_UtilsICurve.hxx" +#include "CurveCreator_TableView.h" #include #include #include #include -#include #include #include - -#include -#include +#include #include #include @@ -50,204 +46,304 @@ #include #include #include +#include +#include + +//#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 + ( 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 + ( 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 anEnabledAct; if( myCurve ){ - anEnabledAct << NEW_SECTION_ID; + anEnabledAct << NEW_SECTION_ID << MODIFICATION_MODE_ID; + if ( removeEnabled() ) + anEnabledAct << REMOVE_ID; QList 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 aSelSection = mySectionView->getSelectedSections(); - if( aSelSection.size() > 0 ){ - mySection = aSelSection[0]; - myPointNum = myCurve->getNbPoints(mySection); + switch ( getActionMode() ) { + case AdditionMode: { + mySection = -1; + myPointNum = -1; + QList 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 > 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 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 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::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 > 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 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 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 > 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 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 > 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 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 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 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 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 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 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 CurveCreator_Widget::getSelectedSections() return mySectionView->getSelectedSections(); } -QList< QPair< int, int > > CurveCreator_Widget::getSelectedPoints() +void CurveCreator_Widget::setSelectedSections( const QList& 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 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 > 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 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 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 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 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 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 >& 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 ); } diff --git a/src/CurveCreator/CurveCreator_Widget.h b/src/CurveCreator/CurveCreator_Widget.h index 7f335e8db..e15e92309 100644 --- a/src/CurveCreator/CurveCreator_Widget.h +++ b/src/CurveCreator/CurveCreator_Widget.h @@ -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 @@ -20,101 +20,212 @@ #ifndef CURVECREATOR_WIDGET_H #define CURVECREATOR_WIDGET_H -#include "CurveCreator_Curve.hxx" +#include "CurveCreator_Macro.hxx" #include "CurveCreator.hxx" +#include "CurveCreator_ICurve.hxx" #include #include +#include #include +#include +#include + +#include +#include +#include +#include // 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 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 getSelectedSections(); + void setSelectedSections( const QList& 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 >& theConvPoints ); + + bool contains( const CurveCreator_ICurve::SectionToPointList& theList, + const CurveCreator_ICurve::SectionToPoint& theValue ) const; + private: - QMap myActionMap; - CurveCreator_Curve* myCurve; - CurveCreator_CurveEditor* myEdit; - CurveCreator_TreeView* mySectionView; - CurveCreator_NewPointDlg* myNewPointEditor; - CurveCreator_NewSectionDlg* myNewSectionEditor; - int mySection; - int myPointNum; - QPoint myDragStartPosition; + QMap 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 myInitialDragPointsCoords; + bool myDragged; + QByteArray myGuiState; + int myPressedX; + int myPressedY; + OCCViewer_ViewWindow::Mode2dType myOld2DMode; }; #endif // CURVECREATOR_WIDGET_H diff --git a/src/EntityGUI/CMakeLists.txt b/src/EntityGUI/CMakeLists.txt index 865678ad3..79668add1 100755 --- a/src/EntityGUI/CMakeLists.txt +++ b/src/EntityGUI/CMakeLists.txt @@ -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 diff --git a/src/EntityGUI/EntityGUI.cxx b/src/EntityGUI/EntityGUI.cxx index b6f36c8ad..3a3bd6297 100644 --- a/src/EntityGUI/EntityGUI.cxx +++ b/src/EntityGUI/EntityGUI.cxx @@ -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 index 000000000..50c12462a --- /dev/null +++ b/src/EntityGUI/EntityGUI_PolylineDlg.cxx @@ -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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +//#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 + (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( 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( 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 index 000000000..6f7b009a5 --- /dev/null +++ b/src/EntityGUI/EntityGUI_PolylineDlg.h @@ -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 + +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 myLCSList; + QList myWPlaneList; + +}; + +#endif // ENTITYGUI_POLYLINEDLG_H diff --git a/src/GEOM/GEOM_Function.cxx b/src/GEOM/GEOM_Function.cxx index c141e2e4c..458e0a0bc 100644 --- a/src/GEOM/GEOM_Function.cxx +++ b/src/GEOM/GEOM_Function.cxx @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include #include @@ -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 diff --git a/src/GEOM/GEOM_Function.hxx b/src/GEOM/GEOM_Function.hxx index 702acb959..688324dae 100644 --- a/src/GEOM/GEOM_Function.hxx +++ b/src/GEOM/GEOM_Function.hxx @@ -32,6 +32,7 @@ #include #include +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); diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index 115e51e67..40c06a632 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -1215,6 +1215,10 @@ ICO_SHELL_SEL_ONLY build_shell.png + + ICO_CURVE_CREATOR + polyline.png + ICO_SKETCH sketch.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 89480676b..754afda3d 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -2366,7 +2366,15 @@ Please, select face, shell or solid and try again MEN_CURVE_CREATOR - Curve creator + 2D Polyline + + + TOP_CURVE_CREATOR + Create 2D polyline + + + STB_CURVE_CREATOR + Create 2D polyline MEN_ALL_SEL_ONLY @@ -5163,6 +5171,22 @@ shells and solids on the other hand. TOOL_IMPORTEXPORT Import / Export XAO + + TABLE_SECTION + Section + + + TABLE_INDEX + Index + + + TABLE_X + X + + + TABLE_Y + Y + BasicGUI_CurveDlg @@ -5404,74 +5428,39 @@ shells and solids on the other hand. Face 2 V - - CurveCreator_NewPointDlg - - ADD_NEW_POINT - Add new points - - - X_COORD - X - - - Y_COORD - Y - - - Z_COORD - Z - - - ADD_BTN - Add - - - ADD_CONTINUE_BTN - Add and continue - - - ADD_NEW_POINT_TO_%1 - Add new point to %1 - - - SET_POINT_COORDINATES - Set point coordinates - - CurveCreator_NewSectionDlg - NAME + SECTION_NAME Name - LINE_TYPE + SECTION_LINE_TYPE Type - POLYLINE_TYPE + SECTION_POLYLINE_TYPE Polyline - SPLINE_TYPE + SECTION_SPLINE_TYPE Spline - LINE_CLOSED + SECTION_LINE_CLOSED Closed - OK - Ok + SECTION_ADD_BTN + Add - ADD_BTN - Add + SECTION_OK_BTN + Ok - ADD_CONTINUE_BTN - Add and continue + SECTION_CANCEL_BTN + Cancel ADD_NEW_SECTION @@ -5496,11 +5485,7 @@ shells and solids on the other hand. CurveCreator_Widget - CURVE_NAME_TLT - Name - - - SECTION_GROUP_TLT + SECTION_GROUP_TITLE Sections @@ -5527,22 +5512,6 @@ shells and solids on the other hand. NEW_SECTION_TLT Insert new section - - INSERT_SECTION_BEFORE - Insert section before - - - INSERT_SECTION_BEFORE_TLT - Insert section before - - - INSERT_SECTION_AFTER - Insert section after - - - INSERT_SECTION_AFTER_TLT - Insert section after - ADDITION_MODE Addition mode @@ -5567,18 +5536,6 @@ shells and solids on the other hand. DETECTION_MODE_TLT Detection mode - - INSERT_POINT_BEFORE - Insert point before - - - INSERT_POINT_BEFORE_TLT - Insert point before - - - INSERT_POINT_AFTER - Insert point after - CLOSE_SECTIONS Set closed @@ -5627,22 +5584,6 @@ shells and solids on the other hand. JOIN_TLT Join selected sections - - STEP_UP - Move up - - - STEP_UP_TLT - Move selected objects up - - - STEP_DOWN - Move down - - - STEP_DOWN_TLT - Move selected objects down - CLEAR_ALL Clear all @@ -5660,6 +5601,33 @@ shells and solids on the other hand. Join all sections + + EntityGUI_PolylineDlg + + POLYLINE_DLG_TITLE + Polyline Construction + + + POLYLINE_TITLE + Polyline + + + POLYLINE_NAME + Polyline + + + POLYLINE_IMPORT + Import polyline + + + POLYLINE_ADD_SECTION + Add section + + + POLYLINE_EDIT_SECTION + Edit section + + EntityGUI_SketcherDlg diff --git a/src/GEOMGUI/GeometryGUI.cxx b/src/GEOMGUI/GeometryGUI.cxx index 2b3b7ca83..d3d37411c 100644 --- a/src/GEOMGUI/GeometryGUI.cxx +++ b/src/GEOMGUI/GeometryGUI.cxx @@ -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 ); diff --git a/src/GEOMGUI/GeometryGUI_Operations.h b/src/GEOMGUI/GeometryGUI_Operations.h index f392e4df6..f66c19df1 100644 --- a/src/GEOMGUI/GeometryGUI_Operations.h +++ b/src/GEOMGUI/GeometryGUI_Operations.h @@ -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 diff --git a/src/GEOMImpl/CMakeLists.txt b/src/GEOMImpl/CMakeLists.txt index 0fb145931..a09066811 100755 --- a/src/GEOMImpl/CMakeLists.txt +++ b/src/GEOMImpl/CMakeLists.txt @@ -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 diff --git a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx index df1c543e7..f6c452b95 100644 --- a/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_ICurvesOperations.cxx @@ -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" @@ -59,12 +60,14 @@ #include "GEOMImpl_I3DSketcher.hxx" #include "GEOMImpl_ICurveParametric.hxx" #include "GEOMImpl_IIsoline.hxx" +#include "GEOMImpl_PolylineDumper.hxx" #include #include "utilities.h" #include +#include #include #include @@ -1465,3 +1468,155 @@ Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeIsoline SetErrorCode(OK); return anIsoline; } + +//============================================================================= +/*! + * MakePolyline2D + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakePolyline2D + (const std::list > &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 > &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; +} diff --git a/src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx b/src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx index 15591a64f..fe4278cc6 100644 --- a/src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_ICurvesOperations.hxx @@ -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 > &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 > &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 index 000000000..eb1bcfdd7 --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_IPolyline2D.cxx @@ -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 + + +//============================================================================= +/*! + * SetCoords + */ +//============================================================================= +void GEOMImpl_IPolyline2D::SetCoords + (const std::list > &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 >::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::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 > &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 >::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 index 000000000..302e9f899 --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_IPolyline2D.hxx @@ -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 +#include + +#include + +#include +#include +#include + + +#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 > &theValue); + + void GetCoords(std::list > &theValue); + + private: + + Handle(GEOM_Function) _func; +}; + +#endif diff --git a/src/GEOMImpl/GEOMImpl_PolylineDriver.cxx b/src/GEOMImpl/GEOMImpl_PolylineDriver.cxx index 1eeeaf277..1a996c1e5 100644 --- a/src/GEOMImpl/GEOMImpl_PolylineDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_PolylineDriver.cxx @@ -23,12 +23,17 @@ #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 +#include #include #include +#include #include #include #include @@ -38,6 +43,7 @@ #include #include #include +#include #include //======================================================================= @@ -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 > 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 >::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 > 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 > aCoords; + + AddParam(theParams, "Number of curves", aNbCurves); + aP2d.GetCoords(aCoords); + + Standard_Integer aNbCoords = aCoords.size(); + std::list >::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; } diff --git a/src/GEOMImpl/GEOMImpl_PolylineDriver.hxx b/src/GEOMImpl/GEOMImpl_PolylineDriver.hxx index 3f8165537..b3f89d91e 100644 --- a/src/GEOMImpl/GEOMImpl_PolylineDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_PolylineDriver.hxx @@ -80,6 +80,9 @@ Standard_EXPORT ~GEOMImpl_PolylineDriver() {}; Standard_EXPORT virtual bool GetCreationInformation(std::string& theOperationName, std::vector& 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 index 000000000..05fb9a61a --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_PolylineDumper.cxx @@ -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 + + +//======================================================================= +// function : Constructor +// purpose : +//======================================================================= +GEOMImpl_PolylineDumper::GEOMImpl_PolylineDumper + (const std::list > &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 > &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 >::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 ::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 ::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 index 000000000..1fe396bfd --- /dev/null +++ b/src/GEOMImpl/GEOMImpl_PolylineDumper.hxx @@ -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 + +#include +#include +#include + +#include + + +/** + * 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 > &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 > &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 > &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 diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx old mode 100755 new mode 100644 index 0bc7505c1..0ea9449e2 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -111,6 +111,8 @@ #define GEOM_ISOLINE 55 +#define GEOM_POLYLINE2D 56 + //GEOM_Function types #define COPY_WITH_REF 1 @@ -250,7 +252,9 @@ #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 diff --git a/src/GEOM_I/GEOM_ICurvesOperations_i.cc b/src/GEOM_I/GEOM_ICurvesOperations_i.cc index f1d2469c0..06d9b66d3 100644 --- a/src/GEOM_I/GEOM_ICurvesOperations_i.cc +++ b/src/GEOM_I/GEOM_ICurvesOperations_i.cc @@ -30,6 +30,9 @@ #include "GEOM_Engine.hxx" #include "GEOM_Object.hxx" +#include +#include + //============================================================================= /*! * 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 > 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 > 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 > &theOutList) +{ + const int n = theInList.length(); + int i; + std::list 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]); + } + } +} diff --git a/src/GEOM_I/GEOM_ICurvesOperations_i.hh b/src/GEOM_I/GEOM_ICurvesOperations_i.hh index c08cb0156..90cbb2114 100644 --- a/src/GEOM_I/GEOM_ICurvesOperations_i.hh +++ b/src/GEOM_I/GEOM_ICurvesOperations_i.hh @@ -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 > &theCoords); + }; #endif diff --git a/src/GEOM_I/GEOM_IHealingOperations_i.cc b/src/GEOM_I/GEOM_IHealingOperations_i.cc index af7cb5cd4..51fe6c46e 100644 --- a/src/GEOM_I/GEOM_IHealingOperations_i.cc +++ b/src/GEOM_I/GEOM_IHealingOperations_i.cc @@ -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(); diff --git a/src/GEOM_I/GEOM_IHealingOperations_i.hh b/src/GEOM_I/GEOM_IHealingOperations_i.hh index 8b30c9530..091358771 100644 --- a/src/GEOM_I/GEOM_IHealingOperations_i.hh +++ b/src/GEOM_I/GEOM_IHealingOperations_i.hh @@ -33,9 +33,6 @@ #include "GEOMImpl_IHealingOperations.hxx" -#include -#include - 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& ); }; diff --git a/src/GEOM_I/GEOM_IOperations_i.cc b/src/GEOM_I/GEOM_IOperations_i.cc index 12184fd17..9cb5b8469 100644 --- a/src/GEOM_I/GEOM_IOperations_i.cc +++ b/src/GEOM_I/GEOM_IOperations_i.cc @@ -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; +} diff --git a/src/GEOM_I/GEOM_IOperations_i.hh b/src/GEOM_I/GEOM_IOperations_i.hh index 1d5b7fd56..b82b36c68 100644 --- a/src/GEOM_I/GEOM_IOperations_i.hh +++ b/src/GEOM_I/GEOM_IOperations_i.hh @@ -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; diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index c0cd25a60..27b194dc2 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -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 ## @} diff --git a/src/GEOM_SWIG/gsketcher.py b/src/GEOM_SWIG/gsketcher.py index 783bfffca..004e8e63e 100644 --- a/src/GEOM_SWIG/gsketcher.py +++ b/src/GEOM_SWIG/gsketcher.py @@ -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 diff --git a/src/OperationGUI/CMakeLists.txt b/src/OperationGUI/CMakeLists.txt index f176f9d0b..0f8ae114e 100755 --- a/src/OperationGUI/CMakeLists.txt +++ b/src/OperationGUI/CMakeLists.txt @@ -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 --- diff --git a/src/OperationGUI/OperationGUI.cxx b/src/OperationGUI/OperationGUI.cxx index c84dc1cf3..a705e0ae2 100644 --- a/src/OperationGUI/OperationGUI.cxx +++ b/src/OperationGUI/OperationGUI.cxx @@ -27,15 +27,8 @@ #include #include "GeometryGUI_Operations.h" -#include #include -#include #include -#include - -#include -#include -#include #include "OperationGUI_PartitionDlg.h" // Method PARTITION #include "OperationGUI_ArchimedeDlg.h" // Method ARCHIMEDE @@ -47,13 +40,6 @@ #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 -#include -#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)); } diff --git a/src/SKETCHER/CMakeLists.txt b/src/SKETCHER/CMakeLists.txt index 257c2dd1e..ef7e87480 100755 --- a/src/SKETCHER/CMakeLists.txt +++ b/src/SKETCHER/CMakeLists.txt @@ -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 index 000000000..09602cee5 --- /dev/null +++ b/src/SKETCHER/Sketcher.hxx @@ -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 diff --git a/src/SKETCHER/Sketcher_Profile.hxx b/src/SKETCHER/Sketcher_Profile.hxx index ed792f83b..8d36b639b 100644 --- a/src/SKETCHER/Sketcher_Profile.hxx +++ b/src/SKETCHER/Sketcher_Profile.hxx @@ -23,16 +23,12 @@ // 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 #include #include @@ -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 index 000000000..725a985cf --- /dev/null +++ b/src/SKETCHER/Sketcher_Utils.cxx @@ -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 +#include +#include +#include +#include +#include +#include + +const double POINT_CONFUSION_TOLERANCE = 0.0001; + + +//======================================================================= +// function : MakePolyline +// purpose : +//======================================================================= +TopoDS_Shape Sketcher_Utils::MakePolyline + (const std::list &theCoords2D, + const Standard_Boolean IsClosed, + const gp_Ax3 &thePlane) +{ + std::list 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 ::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 &theCoords2D, + const Standard_Boolean IsClosed, + const gp_Ax3 &thePlane) +{ + std::list 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 ::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 &theCoords2D, + const gp_Ax3 &thePlane, + std::list &thePoints) +{ + thePoints.clear(); + + if (theCoords2D.empty() || theCoords2D.size() % 2 == 1) { + // Odd number of coordinates or empty list. Invalid case. + return; + } + + std::list ::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 index 000000000..75360111d --- /dev/null +++ b/src/SKETCHER/Sketcher_Utils.hxx @@ -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 +#include + +#include + + +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 &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 &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 &theCoords2D, + const gp_Ax3 &thePlane, + std::list &thePoints); + +}; + +#endif