From: mpa Date: Wed, 19 Jun 2013 14:30:51 +0000 (+0000) Subject: 0022077: EDF 2272 : Selection with the Paraview interaction mode in GEOM/SMESH X-Git-Tag: B4KillOfAutomake~16 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=af07426a4bcf27234daf56881653080f64c4936e;p=modules%2Fgui.git 0022077: EDF 2272 : Selection with the Paraview interaction mode in GEOM/SMESH 0021950: EDF 2311 SMESH : Polyline selection in SMESH --- diff --git a/doc/salome/gui/images/occ_view_sync.png b/doc/salome/gui/images/occ_view_sync.png new file mode 100644 index 000000000..51ad5b346 Binary files /dev/null and b/doc/salome/gui/images/occ_view_sync.png differ diff --git a/doc/salome/gui/images/poly_selection1.png b/doc/salome/gui/images/poly_selection1.png new file mode 100644 index 000000000..f9601245d Binary files /dev/null and b/doc/salome/gui/images/poly_selection1.png differ diff --git a/doc/salome/gui/images/poly_selection2.png b/doc/salome/gui/images/poly_selection2.png new file mode 100644 index 000000000..7848a500a Binary files /dev/null and b/doc/salome/gui/images/poly_selection2.png differ diff --git a/doc/salome/gui/images/polyselection1.png b/doc/salome/gui/images/polyselection1.png deleted file mode 100755 index 1920e972d..000000000 Binary files a/doc/salome/gui/images/polyselection1.png and /dev/null differ diff --git a/doc/salome/gui/images/polyselection2.png b/doc/salome/gui/images/polyselection2.png deleted file mode 100755 index 8467a4df3..000000000 Binary files a/doc/salome/gui/images/polyselection2.png and /dev/null differ diff --git a/doc/salome/gui/images/pref_salome_3dviewer.png b/doc/salome/gui/images/pref_salome_3dviewer.png new file mode 100644 index 000000000..235b564e8 Binary files /dev/null and b/doc/salome/gui/images/pref_salome_3dviewer.png differ diff --git a/doc/salome/gui/images/pref_salome_directories.png b/doc/salome/gui/images/pref_salome_directories.png index c47b45788..a05653fb8 100644 Binary files a/doc/salome/gui/images/pref_salome_directories.png and b/doc/salome/gui/images/pref_salome_directories.png differ diff --git a/doc/salome/gui/images/pref_salome_general.png b/doc/salome/gui/images/pref_salome_general.png index db05ca064..5beafe264 100644 Binary files a/doc/salome/gui/images/pref_salome_general.png and b/doc/salome/gui/images/pref_salome_general.png differ diff --git a/doc/salome/gui/images/pref_salome_objbrowser.png b/doc/salome/gui/images/pref_salome_objbrowser.png index 9242935e8..8299d88bb 100644 Binary files a/doc/salome/gui/images/pref_salome_objbrowser.png and b/doc/salome/gui/images/pref_salome_objbrowser.png differ diff --git a/doc/salome/gui/images/pref_salome_occviewer.png b/doc/salome/gui/images/pref_salome_occviewer.png index 953d07211..00bf8a743 100644 Binary files a/doc/salome/gui/images/pref_salome_occviewer.png and b/doc/salome/gui/images/pref_salome_occviewer.png differ diff --git a/doc/salome/gui/images/pref_salome_plot2dviewer.png b/doc/salome/gui/images/pref_salome_plot2dviewer.png index f427aee9d..339dbf950 100644 Binary files a/doc/salome/gui/images/pref_salome_plot2dviewer.png and b/doc/salome/gui/images/pref_salome_plot2dviewer.png differ diff --git a/doc/salome/gui/images/pref_salome_shortcuts.png b/doc/salome/gui/images/pref_salome_shortcuts.png index 5f4c19454..76c30e617 100644 Binary files a/doc/salome/gui/images/pref_salome_shortcuts.png and b/doc/salome/gui/images/pref_salome_shortcuts.png differ diff --git a/doc/salome/gui/images/pref_salome_vtkviewer.png b/doc/salome/gui/images/pref_salome_vtkviewer.png index 29ac576dd..071457d0c 100644 Binary files a/doc/salome/gui/images/pref_salome_vtkviewer.png and b/doc/salome/gui/images/pref_salome_vtkviewer.png differ diff --git a/doc/salome/gui/images/rect_selection1.png b/doc/salome/gui/images/rect_selection1.png new file mode 100644 index 000000000..ef3fea419 Binary files /dev/null and b/doc/salome/gui/images/rect_selection1.png differ diff --git a/doc/salome/gui/images/rect_selection2.png b/doc/salome/gui/images/rect_selection2.png new file mode 100644 index 000000000..6fc042ab7 Binary files /dev/null and b/doc/salome/gui/images/rect_selection2.png differ diff --git a/doc/salome/gui/images/vtk_view_sync.png b/doc/salome/gui/images/vtk_view_sync.png new file mode 100644 index 000000000..51ad5b346 Binary files /dev/null and b/doc/salome/gui/images/vtk_view_sync.png differ diff --git a/doc/salome/gui/input/common_functionality.doc b/doc/salome/gui/input/common_functionality.doc new file mode 100644 index 000000000..7e4e2d73b --- /dev/null +++ b/doc/salome/gui/input/common_functionality.doc @@ -0,0 +1,130 @@ +/*! + +\page common_functionality_page Common functionality + +\anchor viewer_background +

Background

+ +Viewers background can be customized using the "Change background" +popup menu command that opens the following dialog box: + +\image html change_background_dlg.png + +The following types of the background are supported: + +- Single color: the background is colored with the solid color + specified by the user in the dialog box. + +- Gradient background: the background is gradiently colored according + to two colors and the gradient type specified in the dialog box. The + following types of background are supported: + + - Horizontal + + - Vertical + + - First diagonal + + - Second diagonal + + - First corner + + - Second corner + + - Third corner + + - Fourth corner + +- Image: allows to set image as viewer background and define filling type: + + - Center: the image is located at the center of the viewer backgound + + - Tile: the image fills the entire viewer backgound one by one + + - Stretch: the image is stretched to the entire viewer backgound. + +Default background for the OCC viewer is specified via the +\ref occ_preferences "OCC 3D Viewer Preferences" and for the +VTK viewer via the \ref vtk_preferences "VTK 3D Viewer Preferences". + +
+ +

Selection

+ +For selecting it is necessary to click by left mouse button on the required +element. Thus, this element will be selected. + +Also, holding down the Shift key while selecting objects will +produce multi selection. + +In the viewers there are two mechanism for selecting: rectangle and +polyline selection. + +

Rectangle selection

+ +The Rectangle Selection tool is designed to select rectangular regions: +it is the most basic of the selection tools and very commonly used. + +For selecting area by rectangle press left mouse button and draw it on +the viewer holding down the left mouse button. + +To add an area to the existing selection it is necessary to hold down +Shift key while selecting. + +\image html rectselectionvtk.png +As a result, only a rectangle is selected. +\image html rectselectionvtk2.png + +

Polyline selection

+ +OCC and VTK Viewers features a special Polyline Selection mechanism, +which allows selecting an arbitraty part of the graphic area using a +polygon frame (rubber band), instead of the usual selection with a +rectangular frame. + +To produce a Polyline Selection, lock the right mouse button and draw +the first side of the polygon, then change the direction by clicking +the left mouse button add draw another side, etc. The whole selection +frame is drawn with the locked right mouse button. + +To add an area to the existing selection it is necessary to hold down +Shift key while selecting. + +\image html polyselectionvtk11.png +As a result, only the faces within the frame are selected. +\image html polyselectionvtk21.png + +
+ +\anchor viewer_navigation_modes +

Navigation modes

+ +OCC and VTK 3D viewers support two different navigation modes: + +- Salome standard controls + + Rectangle selection in this mode is performed by left mouse button, + polyline selection is done by right mouse button; + multiple selection is available when \b Shift button is pressed. + + Also, holding \b Ctrl key pressed in conjunction with + mouse buttons performs view transformations: + - \b Ctrl + left mouse button - zooming; + - \b Ctrl + middle mouse button - panning; + - \b Ctrl + right mouse button - rotation. + +- Keyboard free style + + This mode allows to process all view transformations without using + keyboard (only by mouse): + - \b Left mouse button performs view rotation; + - \b Middle mouse button performs panning; + - \b Right mouse button makes zooming. + . + + In this style selection of objects in view is performed by pressing + "S" key or by left mouse button click. Rectangle selection is done + by left mouse button when holding \b Ctrl key; polyline selection + is done by right mouse button with \b Ctrl key pressed. + +*/ diff --git a/doc/salome/gui/input/occ_3d_viewer.doc b/doc/salome/gui/input/occ_3d_viewer.doc index e59aafe3f..e27d346d3 100644 --- a/doc/salome/gui/input/occ_3d_viewer.doc +++ b/doc/salome/gui/input/occ_3d_viewer.doc @@ -20,13 +20,9 @@ jpeg image format. \image html occ_view_style_switch.png -Interaction style switch - allows to switch between standard -and "keyboard free" interaction styles. "Keyboard free" style allows -to process all view transformations without using keyboard (only by -mouse) and perform selection in view by pressing "S" key. By default, -rotation in this mode is performed by left mouse button, panning - by -middle mouse button, zooming - by left and middle mouse buttons -pressed simultaneously. +Interaction style switch - allows to switch between "Salome +standard controls" and "Keyboard free" \ref viewer_navigation_modes "interaction styles". +
\image html occ_view_zooming_style_switch.png @@ -230,68 +226,5 @@ In addition, when this button is in the "checked" state, the dynamic synchronization of the views is performed, i.e. any zoom, pan, rotate or other view operation done in one view is automatically applied to the other view. -
- -\anchor occ_background -

Background

- -OCC Viewer background can be customized using the "Change background" -popup menu command that opens the following dialog box: - -\image html change_background_dlg.png - -The following types of the background are supported: - -- Single color: the background is colored with the solid color - specified by the user in the dialog box. - -- Gradient background: the background is gradiently colored according - to two colors and the gradient type specified in the dialog box. The - following types of background are supported: - - - Horizontal - - - Vertical - - - First diagonal - - - Second diagonal - - - First corner - - - Second corner - - - Third corner - - - Fourth corner - -- Image: allows to set image as viewer background and define filling type: - - - Center: the image is located at the center of the viewer backgound - - - Tile: the image fills the entire viewer backgound one by one - - - Stretch: the image is stretched to the entire viewer backgound. - -Default background for the viewer is specified via the -\ref occ_preferences "application preferences". - -

Polyline selection

- -OCC Viewer features a special Polyline Selection mechanism, -which allows selecting an arbitraty part of the graphic area using a -polygon frame (rubber band), instead of the usual selection with a -rectangular frame. - -To produce a Polyline Selection, lock the right mouse button and draw -the first side of the polygon, then change the direction by clicking -the left mouse button add draw another side, etc. The whole selection -frame is drawn with the locked right mouse button. - -\image html polyselection1.png - -As a result, only the nodes within the frame are selected. - -\image html polyselection2.png */ diff --git a/doc/salome/gui/input/setting_preferences.doc b/doc/salome/gui/input/setting_preferences.doc index c85fc8e29..546b5ee6d 100644 --- a/doc/salome/gui/input/setting_preferences.doc +++ b/doc/salome/gui/input/setting_preferences.doc @@ -93,29 +93,10 @@ items in Most Recently Used list and the Link type: - \b Auto - shows full paths to the files only if some files from different locations have the same name. -\anchor occ_preferences -

OCC 3D Viewer Preferences

+

3D Viewer Preferences

-\image html pref_salome_occviewer.png +\image html pref_salome_3dviewer.png -- Trihedron - viewer trihedron settings: - - Size - size of the coordinate axes (global trihedron) - displayed in the viewer. - - Relative size - if this option is switched on, trihedron - axes scale to fit the size of the scene displayed in 3D viewer. - - Show static trihedron - allows to show/hide the static - mini-trihedron located in the bottom-left corner of the viewer. -- Number of isolines - this submenu allows to specify the - number of isolines along the axes of coordinates: - - Along U and - - Along V -- Background - specifies the default background for the viewers, - separately for (for more details, refer to the \ref occ_background - "this page"): - - 3D View - - XZ View - - YZ View - - XY View - Navigation style - this option allows to choose one of the modes of work with mouse in OCC and VTK 3D viewers. - Salome Standard Controls - allows to manipulate objects in the @@ -133,6 +114,26 @@ different locations have the same name. relatively to its center. - Relative to the cursor - allows to zoom the view relatively to the current cursor position. +- Trihedron - viewer trihedron settings: + - Size - size of the coordinate axes (global trihedron) + displayed in the viewer. + - Relative size - if this option is switched on, trihedron + axes scale to fit the size of the scene displayed in 3D viewer. + - Show static trihedron - allows to show/hide the static + mini-trihedron located in the bottom-left corner of the viewer. + +\anchor occ_preferences +

OCC 3D Viewer Preferences

+ +\image html pref_salome_occviewer.png + +- Background - specifies the default background for the viewers, + separately for (for more details, refer to the \ref viewer_background + "this page"): + - 3D View + - XZ View + - YZ View + - XY View \anchor vtk_preferences

VTK 3D Viewer Preferences

@@ -142,24 +143,13 @@ different locations have the same name. - Projection mode - allows choosing between \b Orthogonal and \b Perspective projection mode. - Background - specifies the default background for the viewer; - for more details, refer to the \ref vtk_background "this page". -- Navigation style - this option allows to choose one of the - modes of work with mouse in OCC and VTK 3D viewers (for more details - see \ref occ_preferences "preferences for OCC Viewer 3d"). -- Zooming style - this option allows to choose a zooming mode - (for more details see \ref occ_preferences "preferences for OCC Viewer 3d"). + for more details, refer to the \ref viewer_background "this page". - Speed Increment - defines the number of units by which the speed increases or respectively decreases after pressing [+] or [-] keyboard buttons. - Modification Mode - allows choosing between \b Arithmetic and \b Geometrical progression used for zooming. - Dynamic pre-selection - switches dynamic pre-selection on/off. -- Trihedron - viewer trihedron settings: - - Size - size of the coordinate axes displayed in the viewer. - - Relative size - if this option is switched on, trihedron - axes scale to fit the size of the scene displayed in 3D viewer. - - Show static trihedron - allows to show/hide the static - mini-trihedron located in the bottom-left corner of the viewer. - Spacemouse - a mouse-like manipulator device specially designed for working with 3D presentations, objects, etc. You can reassign the actions listed below to any of its buttons. diff --git a/doc/salome/gui/input/viewers_chapter.doc b/doc/salome/gui/input/viewers_chapter.doc index b3a3b92de..fd493caab 100644 --- a/doc/salome/gui/input/viewers_chapter.doc +++ b/doc/salome/gui/input/viewers_chapter.doc @@ -31,4 +31,6 @@ directly, but can be used in custom modules for 2D visualization purposes. developed on the basis of Qt QGraphicsView scene. This viewer is used in SALOME YACS module for visualization of computation schemes. +- \subpage common_functionality_page used in OCC and VTK 3d viewers. + */ diff --git a/doc/salome/gui/input/vtk_3d_viewer.doc b/doc/salome/gui/input/vtk_3d_viewer.doc index 529bf3a39..1774bf1f5 100644 --- a/doc/salome/gui/input/vtk_3d_viewer.doc +++ b/doc/salome/gui/input/vtk_3d_viewer.doc @@ -20,13 +20,9 @@ jpeg image format. \image html vtk_view_style_switch.png -Interaction style switch - allows to switch between standard -and "keyboard free" interaction styles. "Keyboard free" style allows -to process all view transformations without using keyboard (only by -mouse) and perform selection in view by pressing "S" key. By default, -rotation in this mode is performed by left mouse button, panning - by -middle mouse button, zooming - by left and middle mouse buttons -pressed simultaneously. +Interaction style switch - allows to switch between "Salome +standard controls" and "Keyboard free" \ref viewer_navigation_modes "interaction styles". +
\image html vtk_view_zooming_style_switch.png @@ -283,51 +279,4 @@ the AVI format using external software (jpeg2yuv): - Stop recording - stop recording. -
- -\anchor vtk_background -

Background

- -VTK Viewer background can be customized using the "Change background" -popup menu command that opens the following dialog box: - -\image html change_background_dlg.png - -The following types of the background are supported: - -- Single color: the background is colored with the solid color - specified by the user in the dialog box. - -- Gradient background: the background is gradiently colored according - to two colors and the gradient type specified in the dialog - box. The following types of background are supported: - - - Horizontal - - - Vertical - - - First diagonal - - - Second diagonal - - - First corner - - - Second corner - - - Third corner - - - Fourth corner - -- Image: allows to set image as viewer background and define filling type: - - - Center: the image is located at the center of the viewer backgound - - - Tile: the image fills the entire viewer backgound one by one - - - Stretch: the image is stretched to the entire viewer backgound. - - -Default background for the viewer is specified via the -\ref vtk_preferences "application preferences". - */ diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 8dd648f27..889c6f2f3 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -1443,10 +1443,10 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType vm->setBackground( OCCViewer_ViewFrame::BOTTOM_RIGHT, resMgr->backgroundValue( "OCCViewer", "background", vm->background(OCCViewer_ViewFrame::MAIN_VIEW) ) ); - vm->setTrihedronSize( resMgr->doubleValue( "OCCViewer", "trihedron_size", vm->trihedronSize() ), - resMgr->booleanValue( "OCCViewer", "relative_size", vm->trihedronRelative() )); - vm->setInteractionStyle( resMgr->integerValue( "OCCViewer", "navigation_mode", vm->interactionStyle() ) ); - vm->setZoomingStyle( resMgr->integerValue( "OCCViewer", "zooming_mode", vm->zoomingStyle() ) ); + vm->setTrihedronSize( resMgr->doubleValue( "3DViewer", "trihedron_size", vm->trihedronSize() ), + resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() )); + vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) ); + vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) ); viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface new LightApp_OCCSelector( (OCCViewer_Viewer*)viewMgr->getViewModel(), mySelMgr ); } @@ -1465,11 +1465,11 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType { vm->setProjectionMode( resMgr->integerValue( "VTKViewer", "projection_mode", vm->projectionMode() ) ); vm->setBackground( resMgr->backgroundValue( "VTKViewer", "background", vm->background() ) ); - vm->setTrihedronSize( resMgr->doubleValue( "VTKViewer", "trihedron_size", vm->trihedronSize() ), - resMgr->booleanValue( "VTKViewer", "relative_size", vm->trihedronRelative() ) ); - vm->setStaticTrihedronVisible( resMgr->booleanValue( "VTKViewer", "show_static_trihedron", vm->isStaticTrihedronVisible() ) ); - vm->setInteractionStyle( resMgr->integerValue( "VTKViewer", "navigation_mode", vm->interactionStyle() ) ); - vm->setZoomingStyle( resMgr->integerValue( "VTKViewer", "zooming_mode", vm->zoomingStyle() ) ); + vm->setTrihedronSize( resMgr->doubleValue( "3DViewer", "trihedron_size", vm->trihedronSize() ), + resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() ) ); + vm->setStaticTrihedronVisible( resMgr->booleanValue( "3DViewer", "show_static_trihedron", vm->isStaticTrihedronVisible() ) ); + vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) ); + vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) ); vm->setDynamicPreSelection( resMgr->booleanValue( "VTKViewer", "dynamic_preselection", vm->dynamicPreSelection() ) ); vm->setIncrementalSpeed( resMgr->integerValue( "VTKViewer", "speed_value", vm->incrementalSpeed() ), resMgr->integerValue( "VTKViewer", "speed_mode", vm->incrementalSpeedMode() ) ); @@ -2094,22 +2094,46 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) // ... "MRU" preferences group <> // .. "General" preferences tab <> - // .. "OCC viewer" group <> - int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), salomeCat ); - + // .. "3D viewer" group <> + int Viewer3DGroup = pref->addPreference( tr( "PREF_GROUP_3DVIEWER" ), salomeCat ); + // ... -> navigation mode + int vtkStyleMode = pref->addPreference( tr( "PREF_NAVIGATION" ), Viewer3DGroup, + LightApp_Preferences::Selector, "3DViewer", "navigation_mode" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_STANDARD_STYLE") << tr("PREF_KEYFREE_STYLE"); + anIndicesList << 0 << 1; + pref->setItemProperty( "strings", aValuesList, vtkStyleMode ); + pref->setItemProperty( "indexes", anIndicesList, vtkStyleMode ); + // ... -> zooming mode + #if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version + int occZoomingStyleMode = pref->addPreference( tr( "PREF_ZOOMING" ), Viewer3DGroup, + LightApp_Preferences::Selector, "3DViewer", "zooming_mode" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_ZOOMING_AT_CENTER") << tr("PREF_ZOOMING_AT_CURSOR"); + anIndicesList << 0 << 1; + pref->setItemProperty( "strings", aValuesList, occZoomingStyleMode ); + pref->setItemProperty( "indexes", anIndicesList, occZoomingStyleMode ); + #endif // ... "Trihedron" group <> - int occTriGroup = pref->addPreference( tr( "PREF_TRIHEDRON" ), occGroup ); + int occTriGroup = pref->addPreference( tr( "PREF_TRIHEDRON" ), Viewer3DGroup ); pref->setItemProperty( "columns", 2, occTriGroup ); // .... -> trihedron size int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occTriGroup, - LightApp_Preferences::DblSpin, "OCCViewer", "trihedron_size" ); + LightApp_Preferences::DblSpin, "3DViewer", "trihedron_size" ); pref->setItemProperty( "min", 1.0E-06, occTS ); pref->setItemProperty( "max", 1000, occTS ); // .... -> relative size of trihedron - pref->addPreference( tr( "PREF_RELATIVE_SIZE" ), occTriGroup, LightApp_Preferences::Bool, "OCCViewer", "relative_size" ); + pref->addPreference( tr( "PREF_RELATIVE_SIZE" ), occTriGroup, LightApp_Preferences::Bool, "3DViewer", "relative_size" ); // .... -> show static trihedron - pref->addPreference( tr( "PREF_SHOW_STATIC_TRIHEDRON" ), occTriGroup, LightApp_Preferences::Bool, "OCCViewer", "show_static_trihedron" ); + pref->addPreference( tr( "PREF_SHOW_STATIC_TRIHEDRON" ), occTriGroup, LightApp_Preferences::Bool, "3DViewer", "show_static_trihedron" ); // ... "Trihedron" group <> + // .. "3D viewer" group <> + + // .. "OCC viewer" group <> + int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), salomeCat ); + // ... "Background" group <> int bgGroup = pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup ); // pref->setItemProperty( "columns", 2, bgGroup ); @@ -2168,26 +2192,6 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) int occGen = pref->addPreference( "", occGroup, LightApp_Preferences::Frame ); pref->setItemProperty( "margin", 0, occGen ); pref->setItemProperty( "columns", 2, occGen ); - // .... -> navigation mode - int occStyleMode = pref->addPreference( tr( "PREF_NAVIGATION" ), occGen, - LightApp_Preferences::Selector, "OCCViewer", "navigation_mode" ); - aValuesList.clear(); - anIndicesList.clear(); - aValuesList << tr("PREF_STANDARD_STYLE") << tr("PREF_KEYFREE_STYLE"); - anIndicesList << 0 << 1; - pref->setItemProperty( "strings", aValuesList, occStyleMode ); - pref->setItemProperty( "indexes", anIndicesList, occStyleMode ); - // .... -> zooming mode -#if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version - int occZoomingStyleMode = pref->addPreference( tr( "PREF_ZOOMING" ), occGen, - LightApp_Preferences::Selector, "OCCViewer", "zooming_mode" ); - aValuesList.clear(); - anIndicesList.clear(); - aValuesList << tr("PREF_ZOOMING_AT_CENTER") << tr("PREF_ZOOMING_AT_CURSOR"); - anIndicesList << 0 << 1; - pref->setItemProperty( "strings", aValuesList, occZoomingStyleMode ); - pref->setItemProperty( "indexes", anIndicesList, occZoomingStyleMode ); -#endif // ... -> empty frame (for layout) <> // .. "OCC viewer" group <> @@ -2222,24 +2226,6 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId ); pref->setItemProperty( "custom_enabled", false, bgId ); pref->setItemProperty( "image_formats", formats, bgId ); - // .... -> navigation mode - int vtkStyleMode = pref->addPreference( tr( "PREF_NAVIGATION" ), vtkGen, - LightApp_Preferences::Selector, "VTKViewer", "navigation_mode" ); - aValuesList.clear(); - anIndicesList.clear(); - aValuesList << tr("PREF_STANDARD_STYLE") << tr("PREF_KEYFREE_STYLE"); - anIndicesList << 0 << 1; - pref->setItemProperty( "strings", aValuesList, vtkStyleMode ); - pref->setItemProperty( "indexes", anIndicesList, vtkStyleMode ); - // .... -> zooming mode - int vtkZoomingStyleMode = pref->addPreference( tr( "PREF_ZOOMING" ), vtkGen, - LightApp_Preferences::Selector, "VTKViewer", "zooming_mode" ); - aValuesList.clear(); - anIndicesList.clear(); - aValuesList << tr("PREF_ZOOMING_AT_CENTER") << tr("PREF_ZOOMING_AT_CURSOR"); - anIndicesList << 0 << 1; - pref->setItemProperty( "strings", aValuesList, vtkZoomingStyleMode ); - pref->setItemProperty( "indexes", anIndicesList, vtkZoomingStyleMode ); // .... -> speed increment int vtkSpeed = pref->addPreference( tr( "PREF_INCREMENTAL_SPEED" ), vtkGen, LightApp_Preferences::IntSpin, "VTKViewer", "speed_value" ); @@ -2258,20 +2244,6 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) pref->addPreference( tr( "PREF_DYNAMIC_PRESELECTION" ), vtkGen, LightApp_Preferences::Bool, "VTKViewer", "dynamic_preselection" ); // ... -> empty frame (for layout) <> - // ... "Trihedron" group <> - int vtkTriGroup = pref->addPreference( tr( "PREF_TRIHEDRON" ), vtkGroup ); - pref->setItemProperty( "columns", 2, vtkTriGroup ); - // .... -> trihedron size - int vtkTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), vtkTriGroup, - LightApp_Preferences::DblSpin, "VTKViewer", "trihedron_size" ); - pref->setItemProperty( "min", 1.0E-06, vtkTS ); - pref->setItemProperty( "max", 150, vtkTS ); - // .... -> relative size of trihedron - pref->addPreference( tr( "PREF_RELATIVE_SIZE" ), vtkTriGroup, LightApp_Preferences::Bool, "VTKViewer", "relative_size" ); - // .... -> static trihedron - pref->addPreference( tr( "PREF_SHOW_STATIC_TRIHEDRON" ), vtkTriGroup, LightApp_Preferences::Bool, "VTKViewer", "show_static_trihedron" ); - // ... "Trihedron" group <> - // ... space mouse sub-group <> int vtkSM = pref->addPreference( tr( "PREF_FRAME_SPACEMOUSE" ), vtkGroup, LightApp_Preferences::GroupBox ); //pref->setItemProperty( "columns", 2, vtkSM ); @@ -2493,17 +2465,17 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString } } -#ifndef DISABLE_OCCVIEWER - if ( sec == QString( "OCCViewer" ) && (param == QString( "trihedron_size" ) || param == QString( "relative_size" ))) + if ( sec == QString( "3DViewer" ) && (param == QString( "trihedron_size" ) || param == QString( "relative_size" ))) { double sz = resMgr->doubleValue( sec, "trihedron_size", -1 ); bool relative = resMgr->booleanValue( sec, "relative_size", true ); QList lst; +#ifndef DISABLE_OCCVIEWER viewManagers( OCCViewer_Viewer::Type(), lst ); - QListIterator it( lst ); - while ( it.hasNext() && sz >= 0 ) + QListIterator itOCC( lst ); + while ( itOCC.hasNext() && sz >= 0 ) { - SUIT_ViewModel* vm = it.next()->getViewModel(); + SUIT_ViewModel* vm = itOCC.next()->getViewModel(); if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) continue; @@ -2511,163 +2483,142 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString occVM->setTrihedronSize( sz, relative ); occVM->getAISContext()->UpdateCurrentViewer(); } - } #endif - -#ifndef DISABLE_OCCVIEWER - if ( sec == QString( "OCCViewer" ) && param == QString( "show_static_trihedron" ) ) - { - bool isVisible = resMgr->booleanValue( "OCCViewer", "show_static_trihedron", true ); - QList lst; - viewManagers( OCCViewer_Viewer::Type(), lst ); - QListIterator it( lst ); - while ( it.hasNext() ) +#ifndef DISABLE_VTKVIEWER +#ifndef DISABLE_SALOMEOBJECT + viewManagers( SVTK_Viewer::Type(), lst ); + QListIterator itVTK( lst ); + while ( itVTK.hasNext() && sz >= 0 ) { - SUIT_ViewModel* vm = it.next()->getViewModel(); - if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) + SUIT_ViewModel* vm = itVTK.next()->getViewModel(); + if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) continue; - OCCViewer_Viewer* occVM = dynamic_cast( vm ); - if( occVM ) + SVTK_Viewer* vtkVM = dynamic_cast( vm ); + if( vtkVM ) { - occVM->setStaticTrihedronDisplayed( isVisible ); + vtkVM->setTrihedronSize( sz, relative ); + vtkVM->Repaint(); } } - } #endif - -#ifndef DISABLE_OCCVIEWER - if ( sec == QString( "OCCViewer" ) && param == QString( "navigation_mode" ) ) - { - int mode = resMgr->integerValue( "OCCViewer", "navigation_mode", 0 ); - QList lst; - viewManagers( OCCViewer_Viewer::Type(), lst ); - QListIterator it( lst ); - while ( it.hasNext() ) - { - SUIT_ViewModel* vm = it.next()->getViewModel(); - if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) - continue; - - OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm; - occVM->setInteractionStyle( mode ); - } - } #endif + } -#ifndef DISABLE_OCCVIEWER - if ( sec == QString( "OCCViewer" ) && param == QString( "zooming_mode" ) ) + if ( sec == QString( "3DViewer" ) && param == QString( "show_static_trihedron" ) ) { - int mode = resMgr->integerValue( "OCCViewer", "zooming_mode", 0 ); + bool isVisible = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true ); QList lst; +#ifndef DISABLE_OCCVIEWER viewManagers( OCCViewer_Viewer::Type(), lst ); - QListIterator it( lst ); - while ( it.hasNext() ) + QListIterator itOCC( lst ); + while ( itOCC.hasNext() ) { - SUIT_ViewModel* vm = it.next()->getViewModel(); + SUIT_ViewModel* vm = itOCC.next()->getViewModel(); if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) continue; - OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm; - occVM->setZoomingStyle( mode ); + OCCViewer_Viewer* occVM = dynamic_cast( vm ); + if( occVM ) + { + occVM->setStaticTrihedronDisplayed( isVisible ); + } } - } #endif - #ifndef DISABLE_VTKVIEWER - if ( sec == QString( "VTKViewer" ) && (param == QString( "trihedron_size" ) || param == QString( "relative_size" )) ) - { - double sz = resMgr->doubleValue( "VTKViewer", "trihedron_size", -1 ); - bool isRelative = resMgr->booleanValue( "VTKViewer", "relative_size", true ); - QList lst; #ifndef DISABLE_SALOMEOBJECT viewManagers( SVTK_Viewer::Type(), lst ); - QListIterator it( lst ); - while ( it.hasNext() && sz >= 0 ) + QListIterator itVTK( lst ); + while ( itVTK.hasNext() ) { - SUIT_ViewModel* vm = it.next()->getViewModel(); + SUIT_ViewModel* vm = itVTK.next()->getViewModel(); if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) continue; SVTK_Viewer* vtkVM = dynamic_cast( vm ); if( vtkVM ) { - vtkVM->setTrihedronSize( sz, isRelative ); + vtkVM->setStaticTrihedronVisible( isVisible ); vtkVM->Repaint(); } } #endif - } #endif + } -#ifndef DISABLE_VTKVIEWER - if ( sec == QString( "VTKViewer" ) && (param == QString( "speed_value" ) || param == QString( "speed_mode" )) ) + if ( sec == QString( "3DViewer" ) && param == QString( "navigation_mode" ) ) { - int speed = resMgr->integerValue( "VTKViewer", "speed_value", 10 ); - int mode = resMgr->integerValue( "VTKViewer", "speed_mode", 0 ); + int mode = resMgr->integerValue( "3DViewer", "navigation_mode", 0 ); QList lst; -#ifndef DISABLE_SALOMEOBJECT - viewManagers( SVTK_Viewer::Type(), lst ); - QListIterator it( lst ); - while ( it.hasNext() ) +#ifndef DISABLE_OCCVIEWER + viewManagers( OCCViewer_Viewer::Type(), lst ); + QListIterator itOCC( lst ); + while ( itOCC.hasNext() ) { - SUIT_ViewModel* vm = it.next()->getViewModel(); - if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) + SUIT_ViewModel* vm = itOCC.next()->getViewModel(); + if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) continue; - SVTK_Viewer* vtkVM = dynamic_cast( vm ); - if( vtkVM ) vtkVM->setIncrementalSpeed( speed, mode ); + OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm; + occVM->setInteractionStyle( mode ); } #endif - } -#endif - #ifndef DISABLE_VTKVIEWER - if ( sec == QString( "VTKViewer" ) && param == QString( "projection_mode" ) ) - { - int mode = resMgr->integerValue( "VTKViewer", "projection_mode", 0 ); - QList lst; #ifndef DISABLE_SALOMEOBJECT viewManagers( SVTK_Viewer::Type(), lst ); - QListIterator it( lst ); - while ( it.hasNext() ) + QListIterator itVTK( lst ); + while ( itVTK.hasNext() ) { - SUIT_ViewModel* vm = it.next()->getViewModel(); + SUIT_ViewModel* vm = itVTK.next()->getViewModel(); if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) continue; SVTK_Viewer* vtkVM = dynamic_cast( vm ); - if( vtkVM ) vtkVM->setProjectionMode( mode ); + if( vtkVM ) vtkVM->setInteractionStyle( mode ); } #endif - } #endif + } -#ifndef DISABLE_VTKVIEWER - if ( sec == QString( "VTKViewer" ) && param == QString( "navigation_mode" ) ) + if ( sec == QString( "3DViewer" ) && param == QString( "zooming_mode" ) ) { - int mode = resMgr->integerValue( "VTKViewer", "navigation_mode", 0 ); + int mode = resMgr->integerValue( "3DViewer", "zooming_mode", 0 ); QList lst; +#ifndef DISABLE_OCCVIEWER + viewManagers( OCCViewer_Viewer::Type(), lst ); + QListIterator itOCC( lst ); + while ( itOCC.hasNext() ) + { + SUIT_ViewModel* vm = itOCC.next()->getViewModel(); + if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) + continue; + + OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm; + occVM->setZoomingStyle( mode ); + } +#endif +#ifndef DISABLE_VTKVIEWER #ifndef DISABLE_SALOMEOBJECT viewManagers( SVTK_Viewer::Type(), lst ); - QListIterator it( lst ); - while ( it.hasNext() ) + QListIterator itVTK( lst ); + while ( itVTK.hasNext() ) { - SUIT_ViewModel* vm = it.next()->getViewModel(); + SUIT_ViewModel* vm = itVTK.next()->getViewModel(); if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) continue; SVTK_Viewer* vtkVM = dynamic_cast( vm ); - if( vtkVM ) vtkVM->setInteractionStyle( mode ); + if( vtkVM ) vtkVM->setZoomingStyle( mode ); } #endif - } #endif + } #ifndef DISABLE_VTKVIEWER - if ( sec == QString( "VTKViewer" ) && param == QString( "zooming_mode" ) ) + if ( sec == QString( "VTKViewer" ) && (param == QString( "speed_value" ) || param == QString( "speed_mode" )) ) { - int mode = resMgr->integerValue( "VTKViewer", "zooming_mode", 0 ); + int speed = resMgr->integerValue( "VTKViewer", "speed_value", 10 ); + int mode = resMgr->integerValue( "VTKViewer", "speed_mode", 0 ); QList lst; #ifndef DISABLE_SALOMEOBJECT viewManagers( SVTK_Viewer::Type(), lst ); @@ -2679,16 +2630,16 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString continue; SVTK_Viewer* vtkVM = dynamic_cast( vm ); - if( vtkVM ) vtkVM->setZoomingStyle( mode ); + if( vtkVM ) vtkVM->setIncrementalSpeed( speed, mode ); } #endif } #endif #ifndef DISABLE_VTKVIEWER - if ( sec == QString( "VTKViewer" ) && param == QString( "dynamic_preselection" ) ) + if ( sec == QString( "VTKViewer" ) && param == QString( "projection_mode" ) ) { - bool mode = resMgr->booleanValue( "VTKViewer", "dynamic_preselection", true ); + int mode = resMgr->integerValue( "VTKViewer", "projection_mode", 0 ); QList lst; #ifndef DISABLE_SALOMEOBJECT viewManagers( SVTK_Viewer::Type(), lst ); @@ -2700,16 +2651,16 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString continue; SVTK_Viewer* vtkVM = dynamic_cast( vm ); - if( vtkVM ) vtkVM->setDynamicPreSelection( mode ); + if( vtkVM ) vtkVM->setProjectionMode( mode ); } #endif } #endif #ifndef DISABLE_VTKVIEWER - if ( sec == QString( "VTKViewer" ) && param == QString( "show_static_trihedron" ) ) + if ( sec == QString( "VTKViewer" ) && param == QString( "dynamic_preselection" ) ) { - bool isVisible = resMgr->booleanValue( "VTKViewer", "show_static_trihedron", true ); + bool mode = resMgr->booleanValue( "VTKViewer", "dynamic_preselection", true ); QList lst; #ifndef DISABLE_SALOMEOBJECT viewManagers( SVTK_Viewer::Type(), lst ); @@ -2721,11 +2672,7 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString continue; SVTK_Viewer* vtkVM = dynamic_cast( vm ); - if( vtkVM ) - { - vtkVM->setStaticTrihedronVisible( isVisible ); - vtkVM->Repaint(); - } + if( vtkVM ) vtkVM->setDynamicPreSelection( mode ); } #endif } diff --git a/src/LightApp/resources/LightApp_msg_en.ts b/src/LightApp/resources/LightApp_msg_en.ts index 065b1bfe3..1bb64f5db 100644 --- a/src/LightApp/resources/LightApp_msg_en.ts +++ b/src/LightApp/resources/LightApp_msg_en.ts @@ -618,6 +618,10 @@ The changes will be applied on the next application session. PREF_GROUP_COMMON Common + + PREF_GROUP_3DVIEWER + 3D Viewer + PREF_GROUP_OCCVIEWER OCC 3D Viewer diff --git a/src/LightApp/resources/LightApp_msg_fr.ts b/src/LightApp/resources/LightApp_msg_fr.ts index cf5a1fc0a..8ebdcb075 100755 --- a/src/LightApp/resources/LightApp_msg_fr.ts +++ b/src/LightApp/resources/LightApp_msg_fr.ts @@ -618,6 +618,10 @@ Les modifications seront appliquées à la prochaine session. PREF_GROUP_COMMON Commun + + PREF_GROUP_3DVIEWER + Scène 3D + PREF_GROUP_OCCVIEWER Scène OCC 3D diff --git a/src/OCCViewer/OCCViewer_ViewModel.cxx b/src/OCCViewer/OCCViewer_ViewModel.cxx index b102ac738..71f94cbe4 100755 --- a/src/OCCViewer/OCCViewer_ViewModel.cxx +++ b/src/OCCViewer/OCCViewer_ViewModel.cxx @@ -161,7 +161,7 @@ OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron) SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); if(resMgr) - myShowStaticTrihedron = resMgr->booleanValue( "OCCViewer", "show_static_trihedron", true ); + myShowStaticTrihedron = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true ); } /*! @@ -313,7 +313,7 @@ void OCCViewer_Viewer::onMouseRelease(SUIT_ViewWindow* theWindow, QMouseEvent* t if (!theWindow->inherits("OCCViewer_ViewWindow")) return; OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow; - if (!aView || aView->interactionStyle() != SUIT_ViewModel::STANDARD) + if (!aView ) return; myEndPnt.setX(theEvent->x()); myEndPnt.setY(theEvent->y()); @@ -900,7 +900,7 @@ bool OCCViewer_Viewer::computeTrihedronSize( double& theNewSize, double& theSize if ( aMaxSide < Precision::Confusion() ) return false; - float aSizeInPercents = SUIT_Session::session()->resourceMgr()->doubleValue("OCCViewer","trihedron_size", 100.); + float aSizeInPercents = SUIT_Session::session()->resourceMgr()->doubleValue("3DViewer","trihedron_size", 100.); static float EPS = 5.0E-3; theSize = getTrihedron()->Size(); diff --git a/src/OCCViewer/OCCViewer_ViewSketcher.cxx b/src/OCCViewer/OCCViewer_ViewSketcher.cxx index 7f01d1189..085ba42e7 100755 --- a/src/OCCViewer/OCCViewer_ViewSketcher.cxx +++ b/src/OCCViewer/OCCViewer_ViewSketcher.cxx @@ -41,7 +41,8 @@ mypViewWindow( vw ), myType( type ), mypData( 0 ), myResult( Neutral ), -myButtonState( 0 ) +myButtonState( 0 ), +myHasShift( false ) { } @@ -99,6 +100,11 @@ int OCCViewer_ViewSketcher::buttonState() const return myButtonState; } +bool OCCViewer_ViewSketcher::isHasShift() const +{ + return myHasShift; +} + void OCCViewer_ViewSketcher::onActivate() { } @@ -116,6 +122,7 @@ bool OCCViewer_ViewSketcher::eventFilter( QObject* o, QEvent* e ) { OCCViewer_ViewPort3d* avp = mypViewWindow->getViewPort(); + QMouseEvent* me = (QMouseEvent*)e; SketchState state = EnTrain; bool ignore = false; if ( o == avp ) @@ -127,7 +134,6 @@ bool OCCViewer_ViewSketcher::eventFilter( QObject* o, QEvent* e ) case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: { - QMouseEvent* me = (QMouseEvent*)e; myButtonState = me->buttons(); if ( e->type() == QEvent::MouseButtonPress ) @@ -147,6 +153,7 @@ bool OCCViewer_ViewSketcher::eventFilter( QObject* o, QEvent* e ) state = Fin; ignore = true; + myHasShift = ( me->modifiers() & Qt::ShiftModifier ); break; } case QEvent::Hide: diff --git a/src/OCCViewer/OCCViewer_ViewSketcher.h b/src/OCCViewer/OCCViewer_ViewSketcher.h index a90ff502c..a44350df9 100755 --- a/src/OCCViewer/OCCViewer_ViewSketcher.h +++ b/src/OCCViewer/OCCViewer_ViewSketcher.h @@ -57,6 +57,7 @@ public: int type() const; int result() const; int buttonState() const; + bool isHasShift() const; void* data() const; void activate(); @@ -88,6 +89,7 @@ protected: QCursor mySavedCursor; QPoint myStart, myCurr; int myButtonState; + bool myHasShift; }; /*! diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index 2b2d6d866..8b3340dbd 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -230,6 +230,7 @@ OCCViewer_ViewWindow::OCCViewer_ViewWindow( SUIT_Desktop* theDesktop, myRectBand = 0; IsSketcherStyle = false; + myIsKeyFree = false; mypSketcher = 0; myCurSketch = -1; @@ -448,17 +449,24 @@ void OCCViewer_ViewWindow::vpMousePressEvent( QMouseEvent* theEvent ) default: /* Try to activate a transformation */ - switch ( getButtonState(theEvent, anInteractionStyle) ) { + OperationType aState; + if ( interactionStyle() == SUIT_ViewModel::STANDARD ) + aState = getButtonState(theEvent, anInteractionStyle); + else { + aState = OCCViewer_ViewWindow::NOTHING; + myIsKeyFree = true; + } + switch ( aState ) { case ZOOMVIEW: myViewPort->startZoomAtPoint( myStartX, myStartY ); activateZoom(); break; case PANVIEW: - activatePanning(); + activatePanning(); break; case ROTATE: - activateRotation(); - myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); + activateRotation(); + myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); break; default: if ( myRotationPointSelection ) @@ -792,6 +800,25 @@ bool OCCViewer_ViewWindow::setTransformRequested( OperationType op ) */ void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent ) { + if ( myIsKeyFree && interactionStyle() == SUIT_ViewModel::KEY_FREE ) { + myIsKeyFree = false; + switch ( getButtonState( theEvent, interactionStyle() ) ) { + case ZOOMVIEW: + myViewPort->startZoomAtPoint( myStartX, myStartY ); + activateZoom(); + break; + case PANVIEW: + activatePanning(); + break; + case ROTATE: + activateRotation(); + myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); + break; + default: + break; + } + } + myCurrX = theEvent->x(); myCurrY = theEvent->y(); switch (myOperation) { @@ -829,8 +856,10 @@ void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent ) int aState = theEvent->modifiers(); int aButton = theEvent->buttons(); int anInteractionStyle = interactionStyle(); - if ( anInteractionStyle == SUIT_ViewModel::STANDARD && - aButton == Qt::LeftButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) { + if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD && + aButton == Qt::LeftButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) || + ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && + aButton == Qt::LeftButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) { myDrawRect = myEnableDrawMode; if ( myDrawRect ) { drawRect(); @@ -843,8 +872,10 @@ void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent ) } emit mouseMoving( this, theEvent ); } - else if ( anInteractionStyle == SUIT_ViewModel::STANDARD && - aButton == Qt::RightButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) { + else if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD && + aButton == Qt::RightButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) || + ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && + aButton == Qt::RightButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) { OCCViewer_ViewSketcher* sketcher = 0; QList::Iterator it; for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) @@ -2294,7 +2325,7 @@ void OCCViewer_ViewWindow::onSketchingFinished() if ( mypSketcher && mypSketcher->result() == OCCViewer_ViewSketcher::Accept ) { Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - bool append = bool( mypSketcher->buttonState() & Qt::ShiftModifier ); + bool append = bool( mypSketcher->buttonState() && mypSketcher->isHasShift() ); switch( mypSketcher->type() ) { case Rect: diff --git a/src/OCCViewer/OCCViewer_ViewWindow.h b/src/OCCViewer/OCCViewer_ViewWindow.h index 9bae6138c..a445b5a86 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.h +++ b/src/OCCViewer/OCCViewer_ViewWindow.h @@ -315,6 +315,7 @@ protected: bool myEnableDrawMode; bool myPaintersRedrawing; // set to draw with external painters bool IsSketcherStyle; + bool myIsKeyFree; QCursor myCursor; diff --git a/src/SUIT/SUIT_ViewModel.cxx b/src/SUIT/SUIT_ViewModel.cxx index 9d7f44a9b..ebf166665 100755 --- a/src/SUIT/SUIT_ViewModel.cxx +++ b/src/SUIT/SUIT_ViewModel.cxx @@ -52,7 +52,7 @@ SUIT_ViewModel::SUIT_ViewModel() // "key free" interaction style SUIT_ViewModel::myStateMap[KEY_FREE][ZOOM] = Qt::NoModifier; - SUIT_ViewModel::myButtonMap[KEY_FREE][ZOOM] = Qt::LeftButton | Qt::MidButton; + SUIT_ViewModel::myButtonMap[KEY_FREE][ZOOM] = Qt::RightButton; SUIT_ViewModel::myStateMap[KEY_FREE][PAN] = Qt::NoModifier; SUIT_ViewModel::myButtonMap[KEY_FREE][PAN] = Qt::MidButton; diff --git a/src/SVTK/CMakeLists.txt b/src/SVTK/CMakeLists.txt index 6180af5cd..6b8b7d45e 100755 --- a/src/SVTK/CMakeLists.txt +++ b/src/SVTK/CMakeLists.txt @@ -65,7 +65,7 @@ SET(SVTK_SOURCES SVTK_Prs.cxx SVTK_Actor.cxx SALOME_Actor.cxx - SVTK_RectPicker.cxx + SVTK_AreaPicker.cxx SVTK_DeviceActor.cxx SVTK_CubeAxesActor2D.cxx SVTK_NonIsometricDlg.cxx @@ -118,7 +118,7 @@ SET(COMMON_HEADERS_H SVTK_Prs.h SVTK_Actor.h SALOME_Actor.h - SVTK_RectPicker.h + SVTK_AreaPicker.h SVTK_DeviceActor.h SVTK_FontWidget.h SVTK_CubeAxesActor2D.h diff --git a/src/SVTK/Makefile.am b/src/SVTK/Makefile.am index e4c4a9a65..6d176194c 100755 --- a/src/SVTK/Makefile.am +++ b/src/SVTK/Makefile.am @@ -29,7 +29,7 @@ salomeinclude_HEADERS= \ SVTK_Prs.h \ SVTK_Actor.h \ SALOME_Actor.h \ - SVTK_RectPicker.h \ + SVTK_AreaPicker.h \ SVTK_DeviceActor.h \ SVTK_FontWidget.h \ SVTK_CubeAxesActor2D.h \ @@ -62,7 +62,7 @@ dist_libSVTK_la_SOURCES= \ SVTK_Prs.cxx \ SVTK_Actor.cxx \ SALOME_Actor.cxx \ - SVTK_RectPicker.cxx \ + SVTK_AreaPicker.cxx \ SVTK_DeviceActor.cxx \ SVTK_CubeAxesActor2D.cxx \ SVTK_NonIsometricDlg.cxx \ diff --git a/src/SVTK/SALOME_Actor.cxx b/src/SVTK/SALOME_Actor.cxx index bc7b43ad7..5f74dd561 100644 --- a/src/SVTK/SALOME_Actor.cxx +++ b/src/SVTK/SALOME_Actor.cxx @@ -38,7 +38,7 @@ #include "VTKViewer_TransformFilter.h" #include "VTKViewer_GeometryFilter.h" #include "VTKViewer_FramedTextActor.h" -#include "SVTK_RectPicker.h" +#include "SVTK_AreaPicker.h" #include "SVTK_Actor.h" @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,10 @@ #include #include +#include +#include +#include + #if defined __GNUC__ #if __GNUC__ == 2 #define __GNUC_2__ @@ -671,102 +676,30 @@ SALOME_Actor double x = theSelectionEvent->myX; double y = theSelectionEvent->myY; - double z = 0.0; - if( !theSelectionEvent->myIsRectangle ) { - switch(aSelectionMode){ - case NodeSelection: { - SVTK::TPickLimiter aPickLimiter( myPointPicker, this ); - myPointPicker->Pick( x, y, z, aRenderer ); - - int aVtkId = myPointPicker->GetPointId(); - if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId, true ) ) { - int anObjId = GetNodeObjId( aVtkId ); - if( hasIO() && anObjId >= 0 ) { - mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift ); - mySelector->AddIObject( this ); - } - } - break; - } - case CellSelection: - case EdgeSelection: - case FaceSelection: - case VolumeSelection: - case Elem0DSelection: - case BallSelection: - { - SVTK::TPickLimiter aPickLimiter( myCellPicker, this ); - myCellPicker->Pick( x, y, z, aRenderer ); - - int aVtkId = myCellPicker->GetCellId(); - if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) { - int anObjId = GetElemObjId( aVtkId ); - if( anObjId >= 0 ) { - if ( hasIO() && CheckDimensionId(aSelectionMode,this,anObjId) ) { - mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift ); - mySelector->AddIObject( this ); - } - } - } - break; - } - case EdgeOfCellSelection: - { - SVTK::TPickLimiter aPickLimiter( myCellPicker, this ); - myCellPicker->Pick( x, y, z, aRenderer ); - - int aVtkId = myCellPicker->GetCellId(); - if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) { - int anObjId = GetElemObjId( aVtkId ); - if( anObjId >= 0 ) { - int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId); - if( hasIO() && anEdgeId < 0 ) { - mySelector->AddOrRemoveIndex( myIO, anObjId, false ); - mySelector->AddOrRemoveIndex( myIO, anEdgeId, true ); - mySelector->AddIObject( this ); - } - } - } - break; - } - case ActorSelection : - { - if ( hasIO() ) { - if( mySelector->IsSelected( myIO ) && anIsShift ) - mySelector->RemoveIObject( this ); - else { - mySelector->AddIObject( this ); - } - } - break; - } - default: - break; - } - }else{ + if( theSelectionEvent->myIsRectangle || theSelectionEvent->myIsPolygon ) { double xLast = theSelectionEvent->myLastX; double yLast = theSelectionEvent->myLastY; - double zLast = 0.0; double x1 = x < xLast ? x : xLast; double y1 = y < yLast ? y : yLast; - double z1 = z < zLast ? z : zLast; double x2 = x > xLast ? x : xLast; double y2 = y > yLast ? y : yLast; - double z2 = z > zLast ? z : zLast; switch(aSelectionMode){ case NodeSelection: { - SVTK::TPickLimiter aPickLimiter( myPointRectPicker, this ); - myPointRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer ); + SVTK::TPickLimiter aPickLimiter( myPointAreaPicker, this ); + if ( theSelectionEvent->myIsRectangle ) + myPointAreaPicker->Pick( x1, y1, x2, y2, aRenderer, SVTK_AreaPicker::RectangleMode ); + else if( theSelectionEvent->myIsPolygon ) + myPointAreaPicker->Pick( theSelectionEvent->myPolygonPoints, aRenderer, SVTK_AreaPicker::PolygonMode ); - const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myPointRectPicker->GetPointIdsMap(); - SVTK_RectPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this); + const SVTK_AreaPicker::TVectorIdsMap& aVectorIdsMap = myPointAreaPicker->GetPointIdsMap(); + SVTK_AreaPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this); TColStd_MapOfInteger anIndexes; if(aMapIter != aVectorIdsMap.end()){ - const SVTK_RectPicker::TVectorIds& aVectorIds = aMapIter->second; + const SVTK_AreaPicker::TVectorIds& aVectorIds = aMapIter->second; vtkIdType anEnd = aVectorIds.size(); for(vtkIdType anId = 0; anId < anEnd; anId++ ) { int aPointId = aVectorIds[anId]; @@ -800,17 +733,28 @@ SALOME_Actor aRenderer->SetWorldPoint( aBounds[ i ], aBounds[ j ], aBounds[ k ], 1.0 ); aRenderer->WorldToDisplay(); aRenderer->GetDisplayPoint( aPnt ); - - if( aPnt[0] < x1 || aPnt[0] > x2 || aPnt[1] < y1 || aPnt[1] > y2 ) { - anIsPicked = false; - break; + bool anIsPointInSelection; + if( theSelectionEvent->myIsRectangle ) + anIsPointInSelection = aPnt[0] > x1 && aPnt[0] < x2 && aPnt[1] > y1 && aPnt[1] < y2; + else if( theSelectionEvent->myIsPolygon ) + anIsPointInSelection = myPointAreaPicker->isPointInPolygon( QPoint( aPnt[0], aPnt[1] ), + theSelectionEvent->myPolygonPoints ); + + if( !anIsPointInSelection ) { + anIsPicked = false; + break; } } } } - if( anIsPicked ) - mySelector->AddIObject(this); + if ( hasIO() ) { + if( anIsPicked && mySelector->IsSelected( myIO ) && anIsShift ) + mySelector->RemoveIObject( this ); + else if ( anIsPicked ){ + mySelector->AddIObject( this ); + } + } break; } @@ -821,14 +765,17 @@ SALOME_Actor case Elem0DSelection: case BallSelection: { - SVTK::TPickLimiter aPickLimiter( myCellRectPicker, this ); - myCellRectPicker->Pick( x1, y1, z1, x2, y2, z2, aRenderer ); - - const SVTK_RectPicker::TVectorIdsMap& aVectorIdsMap = myCellRectPicker->GetCellIdsMap(); - SVTK_RectPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this); + SVTK::TPickLimiter aPickLimiter( myCellAreaPicker, this ); + if( theSelectionEvent->myIsRectangle ) + myCellAreaPicker->Pick( x1, y1, x2, y2, aRenderer, SVTK_AreaPicker::RectangleMode ); + else if( theSelectionEvent->myIsPolygon ) + myCellAreaPicker->Pick( theSelectionEvent->myPolygonPoints, aRenderer, SVTK_AreaPicker::PolygonMode ); + + const SVTK_AreaPicker::TVectorIdsMap& aVectorIdsMap = myCellAreaPicker->GetCellIdsMap(); + SVTK_AreaPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this); TColStd_MapOfInteger anIndexes; if(aMapIter != aVectorIdsMap.end()){ - const SVTK_RectPicker::TVectorIds& aVectorIds = aMapIter->second; + const SVTK_AreaPicker::TVectorIds& aVectorIds = aMapIter->second; vtkIdType anEnd = aVectorIds.size(); for(vtkIdType anId = 0; anId < anEnd; anId++ ) { int aCellId = aVectorIds[anId]; @@ -857,6 +804,78 @@ SALOME_Actor break; } } + else { + switch(aSelectionMode){ + case NodeSelection: { + SVTK::TPickLimiter aPickLimiter( myPointPicker, this ); + myPointPicker->Pick( x, y, 0.0, aRenderer ); + + int aVtkId = myPointPicker->GetPointId(); + if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId, true ) ) { + int anObjId = GetNodeObjId( aVtkId ); + if( hasIO() && anObjId >= 0 ) { + mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift ); + mySelector->AddIObject( this ); + } + } + break; + } + case CellSelection: + case EdgeSelection: + case FaceSelection: + case VolumeSelection: + case Elem0DSelection: + case BallSelection: + { + SVTK::TPickLimiter aPickLimiter( myCellPicker, this ); + myCellPicker->Pick( x, y, 0.0, aRenderer ); + + int aVtkId = myCellPicker->GetCellId(); + if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) { + int anObjId = GetElemObjId( aVtkId ); + if( anObjId >= 0 ) { + if ( hasIO() && CheckDimensionId(aSelectionMode,this,anObjId) ) { + mySelector->AddOrRemoveIndex( myIO, anObjId, anIsShift ); + mySelector->AddIObject( this ); + } + } + } + break; + } + case EdgeOfCellSelection: + { + SVTK::TPickLimiter aPickLimiter( myCellPicker, this ); + myCellPicker->Pick( x, y, 0.0, aRenderer ); + + int aVtkId = myCellPicker->GetCellId(); + if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) { + int anObjId = GetElemObjId( aVtkId ); + if( anObjId >= 0 ) { + int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId); + if( hasIO() && anEdgeId < 0 ) { + mySelector->AddOrRemoveIndex( myIO, anObjId, false ); + mySelector->AddOrRemoveIndex( myIO, anEdgeId, true ); + mySelector->AddIObject( this ); + } + } + } + break; + } + case ActorSelection : + { + if ( hasIO() ) { + if( mySelector->IsSelected( myIO ) && anIsShift ) + mySelector->RemoveIObject( this ); + else { + mySelector->AddIObject( this ); + } + } + break; + } + default: + break; + } + } mySelectionMode = aSelectionMode; @@ -978,25 +997,25 @@ SALOME_Actor } /*! - To set up a picker for point rectangle selection (initialized by SVTK_Renderer::AddActor) - \param theRectPicker - new picker + To set up a picker for point rectangle or polygonal selection (initialized by SVTK_Renderer::AddActor) + \param theAreaPicker - new picker */ void SALOME_Actor -::SetPointRectPicker(SVTK_RectPicker* theRectPicker) +::SetPointAreaPicker(SVTK_AreaPicker* theAreaPicker) { - myPointRectPicker = theRectPicker; + myPointAreaPicker = theAreaPicker; } /*! - To set up a picker for cell rectangle selection (initialized by SVTK_Renderer::AddActor) - \param theRectPicker - new picker + To set up a picker for cell rectangle of polygonal selection (initialized by SVTK_Renderer::AddActor) + \param theAreaPicker - new picker */ void SALOME_Actor -::SetCellRectPicker(SVTK_RectPicker* theRectPicker) +::SetCellAreaPicker(SVTK_AreaPicker* theAreaPicker) { - myCellRectPicker = theRectPicker; + myCellAreaPicker = theAreaPicker; } /*! diff --git a/src/SVTK/SALOME_Actor.h b/src/SVTK/SALOME_Actor.h index aabf4635c..704210dfc 100644 --- a/src/SVTK/SALOME_Actor.h +++ b/src/SVTK/SALOME_Actor.h @@ -53,7 +53,7 @@ class vtkRenderWindowInteractor; class VTKViewer_FramedTextActor; class SVTK_Actor; -class SVTK_RectPicker; +class SVTK_AreaPicker; class SVTK_InteractorStyle; SVTK_EXPORT extern int SALOME_POINT_SIZE; @@ -251,11 +251,11 @@ class SVTK_EXPORT SALOME_Actor : public VTKViewer_Actor //! To set up a picker for point rectangle selection (initialized by #SVTK_Renderer::AddActor) void - SetPointRectPicker(SVTK_RectPicker* theRectPicker); + SetPointAreaPicker(SVTK_AreaPicker* theAreaPicker); //! To set up a picker for cell rectangle selection (initialized by #SVTK_Renderer::AddActor) void - SetCellRectPicker(SVTK_RectPicker* theRectPicker); + SetCellAreaPicker(SVTK_AreaPicker* theAreaPicker); //---------------------------------------------------------------------------- //! To set up a prehighlight property (initialized by #SVTK_Renderer::AddActor) @@ -285,8 +285,8 @@ class SVTK_EXPORT SALOME_Actor : public VTKViewer_Actor vtkSmartPointer myPointPicker; vtkSmartPointer myCellPicker; - vtkSmartPointer myPointRectPicker; - vtkSmartPointer myCellRectPicker; + vtkSmartPointer myPointAreaPicker; + vtkSmartPointer myCellAreaPicker; vtkSmartPointer myPreHighlightActor; vtkSmartPointer myHighlightActor; diff --git a/src/SVTK/SVTK.cxx b/src/SVTK/SVTK.cxx index a619838fd..4bca43527 100644 --- a/src/SVTK/SVTK.cxx +++ b/src/SVTK/SVTK.cxx @@ -28,7 +28,7 @@ #include "SVTK_Prs.h" #include "SVTK_Actor.h" #include "SALOME_Actor.h" -#include "SVTK_RectPicker.h" +#include "SVTK_AreaPicker.h" #include "SVTK_DeviceActor.h" #include "SVTK_CubeAxesActor2D.h" #include "SVTK_Functor.h" diff --git a/src/SVTK/SVTK_AreaPicker.cxx b/src/SVTK/SVTK_AreaPicker.cxx new file mode 100644 index 000000000..974b2a012 --- /dev/null +++ b/src/SVTK/SVTK_AreaPicker.cxx @@ -0,0 +1,438 @@ +// 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 +// + +// SALOME VTKViewer : build VTK viewer into Salome desktop +// File : SVTK_AreaPicker.cxx +// Author : +// Module : SALOME +// +#include "SVTK_AreaPicker.h" + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace +{ + //---------------------------------------------------------------------------- + inline + double GetZ( float* theZPtr, int theSelection[4], int theDX, int theDY ) + { + return theZPtr[theDX - theSelection[0] + + ( theDY - theSelection[1] ) + * ( theSelection[2] - theSelection[0] + 1 )]; + } + + //---------------------------------------------------------------------------- + inline + int Check( float* theZPtr, int theSelection[4], double theTolerance, + double theDZ, int theDX, int theDY ) + { + int aRet = 0; + double aZ = -1.0; + if ( theDX >= theSelection[0] && theDX <= theSelection[2] + && theDY >= theSelection[1] && theDY <= theSelection[3] ) { + // Access the value from the captured zbuffer. Note, we only + // captured a portion of the zbuffer, so we need to offset dx by + // the selection window. + aZ = GetZ( theZPtr, theSelection, theDX, theDY ); + if ( aZ > theTolerance && aZ < 1.0 - theTolerance ) { + aRet = fabs( aZ - theDZ ) <= theTolerance; + } + } + return aRet; + } + + //---------------------------------------------------------------------------- + inline + void GetCenter( const double theBounds[6], double theCenter[3] ) + { + theCenter[0] = ( theBounds[1] + theBounds[0] ) / 2.0; + theCenter[1] = ( theBounds[3] + theBounds[2] ) / 2.0; + theCenter[2] = ( theBounds[5] + theBounds[4] ) / 2.0; + } + + //---------------------------------------------------------------------------- + void CalculatePickPosition( vtkRenderer *theRenderer, double theSelectionX, + double theSelectionY, double theSelectionZ, double thePickPosition[3] ) + { + // Convert the selection point into world coordinates. + // + theRenderer->SetDisplayPoint( theSelectionX, theSelectionY, theSelectionZ ); + theRenderer->DisplayToWorld(); + double* aWorldCoords = theRenderer->GetWorldPoint(); + if ( aWorldCoords[3] != 0.0 ) { + for ( int i = 0; i < 3; i++ ) { + thePickPosition[i] = aWorldCoords[i] / aWorldCoords[3]; + } + } + } +} + +vtkStandardNewMacro( SVTK_AreaPicker ) +; + +SVTK_AreaPicker::SVTK_AreaPicker() +{ + this->Tolerance = 0.005; + this->PickPoints = 1; +} + +SVTK_AreaPicker::~SVTK_AreaPicker() +{ +} + +int SVTK_AreaPicker::Pick( double, double, double, vtkRenderer* ) +{ + return 0; +} + +int SVTK_AreaPicker::Pick( double theSelectionX, double theSelectionY, + double theSelectionX2, double theSelectionY2, vtkRenderer *theRenderer, + SelectionMode theMode ) +{ + QVector< QPoint > aPoints; + aPoints.append( QPoint( theSelectionX, theSelectionY ) ); + aPoints.append( QPoint( theSelectionX2, theSelectionY2 ) ); + return Pick( aPoints, theRenderer, theMode ); +} + +int SVTK_AreaPicker::Pick( QVector< QPoint >& thePoints, + vtkRenderer *theRenderer, SelectionMode theMode ) +{ + // Initialize picking process + this->Initialize(); + myCellIdsMap.clear(); + myPointIdsMap.clear(); + this->Renderer = theRenderer; + + if ( theMode == RectangleMode ) { + mySelection = {thePoints[0].x(), thePoints[0].y(), thePoints[1].x(), thePoints[1].y()}; + } + else if( theMode == PolygonMode ) { + int minX, minY, maxX, maxY; + minX = maxX = thePoints[0].x(); + minY = maxY = thePoints[0].y(); + for ( int i=0; i < thePoints.size(); i++ ) { + if ( thePoints[i].x() < minX ) + minX = thePoints[i].x(); + if ( thePoints[i].x() > maxX ) + maxX = thePoints[i].x(); + if ( thePoints[i].y() < minY ) + minY = thePoints[i].y(); + if ( thePoints[i].y() > maxY ) + maxY = thePoints[i].y(); + } + mySelection = {minX, minY, maxX, maxY}; + } + + // Invoke start pick method if defined + this->InvokeEvent( vtkCommand::StartPickEvent, NULL ); + + vtkPropCollection *aProps; + if ( this->PickFromList ) aProps = this->GetPickList(); + else + aProps = theRenderer->GetViewProps(); + + aProps->InitTraversal(); + while( vtkProp* aProp = aProps->GetNextProp() ) { + aProp->InitPathTraversal(); + while( vtkAssemblyPath* aPath = aProp->GetNextPath() ) { + vtkMapper *aMapper = NULL; + bool anIsPickable = false; + vtkActor* anActor = NULL; + vtkProp *aPropCandidate = aPath->GetLastNode()->GetViewProp(); + if ( aPropCandidate->GetPickable() && aPropCandidate->GetVisibility() ) { + anIsPickable = true; + anActor = vtkActor::SafeDownCast( aPropCandidate ); + if ( anActor ) { + aMapper = anActor->GetMapper(); + if ( anActor->GetProperty()->GetOpacity() <= 0.0 ) anIsPickable = + false; + } + } + if ( anIsPickable && aMapper && aMapper->GetInput() ) { + if ( this->PickPoints ) { + TVectorIds& aVisibleIds = myPointIdsMap[anActor]; + TVectorIds anInVisibleIds; + SelectVisiblePoints( thePoints, theRenderer, aMapper->GetInput(), + aVisibleIds, anInVisibleIds, this->Tolerance, theMode ); + if ( aVisibleIds.empty() ) { + myPointIdsMap.erase( myPointIdsMap.find( anActor ) ); + } + } + else { + TVectorIds& aVectorIds = myCellIdsMap[anActor]; + SelectVisibleCells( thePoints, theRenderer, aMapper->GetInput(), + aVectorIds, this->Tolerance, theMode ); + if ( aVectorIds.empty() ) { + myCellIdsMap.erase( myCellIdsMap.find( anActor ) ); + } + } + } + } + } + + // Invoke end pick method if defined + this->InvokeEvent( vtkCommand::EndPickEvent, NULL ); + + return myPointIdsMap.empty() || myCellIdsMap.empty(); +} + +//---------------------------------------------------------------------------- +void SVTK_AreaPicker::SelectVisiblePoints( QVector< QPoint >& thePoints, + vtkRenderer *theRenderer, vtkDataSet *theInput, + SVTK_AreaPicker::TVectorIds& theVisibleIds, + SVTK_AreaPicker::TVectorIds& theInVisibleIds, double theTolerance, + SelectionMode theMode ) +{ + theVisibleIds.clear(); + theInVisibleIds.clear(); + + vtkIdType aNumPts = theInput->GetNumberOfPoints(); + if ( aNumPts < 1 ) return; + + theVisibleIds.reserve( aNumPts / 2 + 1 ); + theInVisibleIds.reserve( aNumPts / 2 + 1 ); + + // Grab the composite perspective transform. This matrix is used to convert + // each point to view coordinates. vtkRenderer provides a WorldToView() + // method but it computes the composite perspective transform each time + // WorldToView() is called. This is expensive, so we get the matrix once + // and handle the transformation ourselves. + vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New(); + aMatrix->DeepCopy( + theRenderer->GetActiveCamera()->GetCompositeProjectionTransformMatrix( + theRenderer->GetTiledAspectRatio(), 0, 1 ) ); + + // We grab the z-buffer for the selection region all at once and probe the resulting array. + float *aZPtr = theRenderer->GetRenderWindow()->GetZbufferData( mySelection[0], + mySelection[1], mySelection[2], mySelection[3] ); + + for ( vtkIdType aPntId = 0; aPntId < aNumPts; aPntId++ ) { + // perform conversion + double aX[4] = { 1.0, 1.0, 1.0, 1.0 }; + theInput->GetPoint( aPntId, aX ); + + double aView[4]; + aMatrix->MultiplyPoint( aX, aView ); + if ( aView[3] == 0.0 ) continue; + theRenderer->SetViewPoint( aView[0] / aView[3], aView[1] / aView[3], + aView[2] / aView[3] ); + theRenderer->ViewToDisplay(); + + double aDX[3]; + theRenderer->GetDisplayPoint( aDX ); + + bool isInSelection; + if ( theMode == RectangleMode ) isInSelection = aDX[0] >= mySelection[0] + && aDX[0] <= mySelection[2] && aDX[1] >= mySelection[1] + && aDX[1] <= mySelection[3]; + else + if ( theMode == PolygonMode ) isInSelection = + SVTK_AreaPicker::isPointInPolygon( QPoint( aDX[0], aDX[1] ), + thePoints ); + + // check whether visible and in selection window + if ( isInSelection ) { + int aDX0 = int( aDX[0] ); + int aDX1 = int( aDX[1] ); + + int aRet = Check( aZPtr, mySelection, theTolerance, aDX[2], aDX0, aDX1 ); + if ( aRet > 0 ) goto ADD_VISIBLE; + if ( aRet < 0 ) goto ADD_INVISIBLE; + + static int aMaxRadius = 5; + for ( int aRadius = 1; aRadius < aMaxRadius; aRadius++ ) { + int aStartDX[2] = { aDX0 - aRadius, aDX1 - aRadius }; + for ( int i = 0; i <= aRadius; i++ ) { + int aRet = Check( aZPtr, mySelection, theTolerance, aDX[2], + aStartDX[0]++, aStartDX[1] ); + if ( aRet > 0 ) goto ADD_VISIBLE; + if ( aRet < 0 ) goto ADD_INVISIBLE; + } + for ( int i = 0; i <= aRadius; i++ ) { + int aRet = Check( aZPtr, mySelection, theTolerance, aDX[2], + aStartDX[0], aStartDX[1]++ ); + if ( aRet > 0 ) goto ADD_VISIBLE; + if ( aRet < 0 ) goto ADD_INVISIBLE; + } + for ( int i = 0; i <= aRadius; i++ ) { + int aRet = Check( aZPtr, mySelection, theTolerance, aDX[2], + aStartDX[0]--, aStartDX[1] ); + if ( aRet > 0 ) goto ADD_VISIBLE; + if ( aRet < 0 ) goto ADD_INVISIBLE; + } + for ( int i = 0; i <= aRadius; i++ ) { + int aRet = Check( aZPtr, mySelection, theTolerance, aDX[2], + aStartDX[0], aStartDX[1]-- ); + if ( aRet > 0 ) goto ADD_VISIBLE; + if ( aRet < 0 ) goto ADD_INVISIBLE; + } + } + if ( false ) ADD_VISIBLE:theVisibleIds.push_back( aPntId ); + if ( false ) ADD_INVISIBLE:theInVisibleIds.push_back( aPntId ); + } + } //for all points + + aMatrix->Delete(); + + if ( aZPtr ) delete[] aZPtr; +} + +void SVTK_AreaPicker::SelectVisibleCells( QVector< QPoint >& thePoints, + vtkRenderer *theRenderer, vtkDataSet *theInput, + SVTK_AreaPicker::TVectorIds& theVectorIds, double theTolerance, + SelectionMode theMode ) +{ + theVectorIds.clear(); + + vtkIdType aNumCells = theInput->GetNumberOfCells(); + if ( aNumCells < 1 ) return; + + theVectorIds.reserve( aNumCells / 2 + 1 ); + + SVTK_AreaPicker::TVectorIds aVisiblePntIds; + SVTK_AreaPicker::TVectorIds anInVisiblePntIds; + SelectVisiblePoints( thePoints, theRenderer, theInput, aVisiblePntIds, + anInVisiblePntIds, theTolerance, theMode ); + + typedef std::set< vtkIdType > TIdsSet; + TIdsSet aVisibleIds( aVisiblePntIds.begin(), aVisiblePntIds.end() ); + TIdsSet anInVisibleIds( anInVisiblePntIds.begin(), anInVisiblePntIds.end() ); + + // Grab the composite perspective transform. This matrix is used to convert + // each point to view coordinates. vtkRenderer provides a WorldToView() + // method but it computes the composite perspective transform each time + // WorldToView() is called. This is expensive, so we get the matrix once + // and handle the transformation ourselves. + vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New(); + aMatrix->DeepCopy( + theRenderer->GetActiveCamera()->GetCompositeProjectionTransformMatrix( + theRenderer->GetTiledAspectRatio(), 0, 1 ) ); + + for ( vtkIdType aCellId = 0; aCellId < aNumCells; aCellId++ ) { + vtkCell* aCell = theInput->GetCell( aCellId ); + + double aBounds[6]; + aCell->GetBounds( aBounds ); + + double aCenter[3]; + GetCenter( aBounds, aCenter ); + + double aView[4]; + double aX[4] = { aCenter[0], aCenter[1], aCenter[2], 1.0 }; + aMatrix->MultiplyPoint( aX, aView ); + + if ( aView[3] == 0.0 ) continue; + + theRenderer->SetViewPoint( aView[0] / aView[3], aView[1] / aView[3], + aView[2] / aView[3] ); + theRenderer->ViewToDisplay(); + + double aDX[3]; + theRenderer->GetDisplayPoint( aDX ); + + bool isInSelection; + if ( theMode == RectangleMode ) isInSelection = aDX[0] >= mySelection[0] + && aDX[0] <= mySelection[2] && aDX[1] >= mySelection[1] + && aDX[1] <= mySelection[3]; + else + if ( theMode == PolygonMode ) isInSelection = + SVTK_AreaPicker::isPointInPolygon( QPoint( aDX[0], aDX[1] ), + thePoints ); + // check whether visible and in selection window + if ( isInSelection ) { + vtkIdType aNumPts = aCell->GetNumberOfPoints(); + bool anIsVisible = true; + for ( vtkIdType anId = 0; anId < aNumPts; anId++ ) { + vtkIdType aPntId = aCell->GetPointId( anId ); + anIsVisible = aVisibleIds.find( aPntId ) != aVisibleIds.end(); + if ( !anIsVisible ) break; + } + if ( anIsVisible ) theVectorIds.push_back( aCellId ); + } + } //for all parts +} + +bool SVTK_AreaPicker::isPointInPolygon( const QPoint& thePoint, + const QVector< QPoint >& thePolygon ) +{ + double eps = 1.0; + if ( thePolygon.size() < 3 ) return false; + + QVector< QPoint >::const_iterator end = thePolygon.end(); + QPoint last_pt = thePolygon.back(); + + last_pt.setX( last_pt.x() - thePoint.x() ); + last_pt.setY( last_pt.y() - thePoint.y() ); + + double sum = 0.0; + + for ( QVector< QPoint >::const_iterator iter = thePolygon.begin(); + iter != end; ++iter ) { + QPoint cur_pt = *iter; + cur_pt.setX( cur_pt.x() - thePoint.x() ); + cur_pt.setY( cur_pt.y() - thePoint.y() ); + + double del = last_pt.x() * cur_pt.y() - cur_pt.x() * last_pt.y(); + double xy = cur_pt.x() * last_pt.x() + cur_pt.y() * last_pt.y(); + + sum += + ( atan( + ( last_pt.x() * last_pt.x() + last_pt.y() * last_pt.y() - xy ) + / del ) + + atan( + ( cur_pt.x() * cur_pt.x() + cur_pt.y() * cur_pt.y() - xy ) + / del ) ); + + last_pt = cur_pt; + } + return fabs( sum ) > eps; +} + +const SVTK_AreaPicker::TVectorIdsMap& +SVTK_AreaPicker::GetPointIdsMap() const +{ + return myPointIdsMap; +} + +const SVTK_AreaPicker::TVectorIdsMap& +SVTK_AreaPicker::GetCellIdsMap() const +{ + return myCellIdsMap; +} diff --git a/src/SVTK/SVTK_AreaPicker.h b/src/SVTK/SVTK_AreaPicker.h new file mode 100644 index 000000000..b08bea025 --- /dev/null +++ b/src/SVTK/SVTK_AreaPicker.h @@ -0,0 +1,150 @@ +// 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 +// + +// SALOME VTKViewer : build VTK viewer into Salome desktop +// File : SVTK_AreaPicker.h +// Author : +// Module : SALOME +// +#ifndef __SVTK_AreaPicker_h +#define __SVTK_AreaPicker_h + +#include "SVTK.h" +#include "VTKViewer.h" + +#include +#include + +#include +#include +#include +#include + +class vtkRenderer; + +#ifdef WIN32 +#pragma warning ( disable:4251 ) +#endif + +/*! \class vtkAbstractPropPicker + * \brief For more information see VTK documentation + */ +/*! \class SVTK_AreaPicker + * \brief Rectangular picker class. + */ +class SVTK_EXPORT SVTK_AreaPicker : public vtkAbstractPropPicker +{ + public: + + enum SelectionMode { RectangleMode, PolygonMode }; + + static + SVTK_AreaPicker *New(); + + vtkTypeMacro(SVTK_AreaPicker,vtkAbstractPropPicker); + + /*! + Specify tolerance for performing pick operation. Tolerance is specified + as fraction of rendering window size. (Rendering window size is measured + across diagonal.) + */ + vtkSetMacro(Tolerance,double); + vtkGetMacro(Tolerance,double); + + //! Use these methods to pick points or points and cells + vtkSetMacro(PickPoints,int); + vtkGetMacro(PickPoints,int); + vtkBooleanMacro(PickPoints,int); + + int + Pick( QVector& thePoints, + vtkRenderer *theRenderer, + SelectionMode theMode ); + + int + Pick( double theSelectionX, + double theSelectionY, + double theSelectionX2, + double theSelectionY2, + vtkRenderer *theRenderer, + SelectionMode theMode ); + + static bool + isPointInPolygon( const QPoint& thePoint,const QVector& thePolygon ); + + typedef std::vector TVectorIds; + typedef std::map TVectorIdsMap; + + const TVectorIdsMap& + GetPointIdsMap() const; + + const TVectorIdsMap& + GetCellIdsMap() const; + + protected: + SVTK_AreaPicker(); + ~SVTK_AreaPicker(); + + //! tolerance for computation (% of window) + double Tolerance; + + //! use the following to control picking mode + int PickPoints; + + //! coordinates of bounding box of selection + int mySelection[4]; + + TVectorIdsMap myPointIdsMap; + TVectorIdsMap myCellIdsMap; + + private: + virtual + int + Pick(double, + double, + double, + vtkRenderer*); + + void + SelectVisiblePoints( QVector& thePoints, + vtkRenderer *theRenderer, + vtkDataSet *theInput, + SVTK_AreaPicker::TVectorIds& theVisibleIds, + SVTK_AreaPicker::TVectorIds& theInVisibleIds, + double theTolerance, + SelectionMode theMode ); + void + SelectVisibleCells( QVector& thePoints, + vtkRenderer *theRenderer, + vtkDataSet *theInput, + SVTK_AreaPicker::TVectorIds& theVectorIds, + double theTolerance, + SelectionMode theMode ); +}; + +#ifdef WIN32 +#pragma warning ( default:4251 ) +#endif + +#endif + + diff --git a/src/SVTK/SVTK_InteractorStyle.cxx b/src/SVTK/SVTK_InteractorStyle.cxx index 7e99f5b70..7f7f5e6e7 100644 --- a/src/SVTK/SVTK_InteractorStyle.cxx +++ b/src/SVTK/SVTK_InteractorStyle.cxx @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -90,7 +91,9 @@ SVTK_InteractorStyle::SVTK_InteractorStyle(): myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()), myHighlightSelectionPointActor(SVTK_Actor::New()), myRectBand(0), - myIsAdvancedZoomingEnabled(false) + myPolygonBand(0), + myIsAdvancedZoomingEnabled(false), + myPoligonState( Disable ) { myPointPicker->Delete(); @@ -138,6 +141,7 @@ SVTK_InteractorStyle::SVTK_InteractorStyle(): SVTK_InteractorStyle::~SVTK_InteractorStyle() { endDrawRect(); + endDrawPolygon(); } /*! @@ -451,6 +455,17 @@ void SVTK_InteractorStyle::OnMouseWheelBackward() myOtherPoint = QPoint(x, y); } +/*! + To handle mouse double click event +*/ +void SVTK_InteractorStyle::OnMouseButtonDoubleClick() +{ + if( myPoligonState == InProcess ) { + onFinishOperation(); + myPoligonState = Finished; + } +} + /*! To handle mouse move event */ @@ -458,6 +473,12 @@ void SVTK_InteractorStyle::OnMouseMove(int vtkNotUsed(ctrl), int shift, int x, int y) { + if ( myPoligonState == Start ) { + // if right button was pressed and mouse is moved + // we can to draw a polygon for polygonal selection + myPoligonState = InProcess; + startOperation( VTK_INTERACTOR_STYLE_CAMERA_SELECT ); + } myShiftState = shift; if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) onOperation(QPoint(x, y)); @@ -475,6 +496,9 @@ void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift, if(GetCurrentRenderer() == NULL) return; + if ( myPoligonState != Disable ) + return; + myShiftState = shift; // finishing current viewer operation if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { @@ -565,10 +589,23 @@ void SVTK_InteractorStyle::OnLeftButtonDown(int ctrl, int shift, */ void SVTK_InteractorStyle::OnLeftButtonUp(int vtkNotUsed(ctrl), int shift, - int vtkNotUsed(x), - int vtkNotUsed(y)) + int x, + int y) { myShiftState = shift; + if( myPoligonState == InProcess ) { // add a new point of polygon + myPolygonPoints.append( QPoint( x, y ) ); + this->Interactor->GetEventPosition( mySelectionEvent->myX, mySelectionEvent->myY ); + mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY ) ); + return; + } + else if ( myPoligonState == Closed ) { // close polygon and apply a selection + onFinishOperation(); + myPoligonState = Finished; + return; + } + else if( myPoligonState == Finished || myPoligonState == NotValid ) + return; // finishing current viewer operation if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { onFinishOperation(); @@ -587,6 +624,9 @@ void SVTK_InteractorStyle::OnMiddleButtonDown(int ctrl, if(GetCurrentRenderer() == NULL) return; + if ( myPoligonState != Disable ) + return; + myShiftState = shift; // finishing current viewer operation if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { @@ -612,6 +652,13 @@ void SVTK_InteractorStyle::OnMiddleButtonUp(int vtkNotUsed(ctrl), int vtkNotUsed(x), int vtkNotUsed(y)) { + if( myPoligonState == InProcess ) { // delete a point of polygon + if ( myPolygonPoints.size() > 2 ) { + myPolygonPoints.remove( myPolygonPoints.size() - 1 ); + mySelectionEvent->myPolygonPoints.remove( mySelectionEvent->myPolygonPoints.size() - 1 ); + } + return; + } myShiftState = shift; // finishing current viewer operation if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { @@ -633,6 +680,12 @@ void SVTK_InteractorStyle::OnRightButtonDown(int ctrl, return; myShiftState = shift; + + if ( !ctrl ) { + myPoligonState = Start; + this->Interactor->GetEventPosition(mySelectionEvent->myX, mySelectionEvent->myY); + mySelectionEvent->myPolygonPoints.append( QPoint( mySelectionEvent->myX, mySelectionEvent->myY) ); + } // finishing current viewer operation if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { onFinishOperation(); @@ -656,6 +709,18 @@ void SVTK_InteractorStyle::OnRightButtonUp(int vtkNotUsed(ctrl), int vtkNotUsed(x), int vtkNotUsed(y)) { + if( myPoligonState == Start ) { // if right button was pressed but mouse is not moved + myPoligonState = Disable; + mySelectionEvent->myPolygonPoints.clear(); + } + + if( myPoligonState != Disable ) { + endDrawPolygon(); + myPoligonState = Finished; + startOperation(VTK_INTERACTOR_STYLE_CAMERA_NONE); + return; + } + myShiftState = shift; // finishing current viewer operation if (State != VTK_INTERACTOR_STYLE_CAMERA_NONE) { @@ -1020,7 +1085,10 @@ void SVTK_InteractorStyle::onStartOperation() case VTK_INTERACTOR_STYLE_CAMERA_SELECT: case VTK_INTERACTOR_STYLE_CAMERA_FIT: { - drawRect(); + if ( myPoligonState == InProcess ) + drawPolygon(); + else + drawRect(); break; } case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: @@ -1067,78 +1135,86 @@ void SVTK_InteractorStyle::onFinishOperation() } else { if (myPoint == myOtherPoint) - { - // process point selection - this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY); - Interactor->StartPickCallback(); + { + // process point selection + this->FindPokedRenderer(aSelectionEvent->myX, aSelectionEvent->myY); + Interactor->StartPickCallback(); - SALOME_Actor* aHighlightedActor = NULL; - vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); - - aSelectionEvent->myIsRectangle = false; + SALOME_Actor* aHighlightedActor = NULL; + vtkActorCollection* anActorCollection = GetSelector()->Pick(aSelectionEvent, GetCurrentRenderer()); - if(!myShiftState) - GetSelector()->ClearIObjects(); + aSelectionEvent->myIsRectangle = false; + aSelectionEvent->myIsPolygon = false; + if(!myShiftState) + GetSelector()->ClearIObjects(); - if( anActorCollection ) + if( anActorCollection ) + { + anActorCollection->InitTraversal(); + while( vtkActor* aVTKActor = anActorCollection->GetNextActor() ) { - anActorCollection->InitTraversal(); - while( vtkActor* aVTKActor = anActorCollection->GetNextActor() ) + if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) ) { - if( SALOME_Actor* anActor = SALOME_Actor::SafeDownCast( aVTKActor ) ) + if( anActor->Highlight( this, aSelectionEvent, true ) ) { - if( anActor->Highlight( this, aSelectionEvent, true ) ) - { - aHighlightedActor = anActor; - break; - } + aHighlightedActor = anActor; + break; } } } + } - if( !aHighlightedActor ) - { - if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor) - myLastHighlitedActor->Highlight( this, aSelectionEvent, false ); - } - myLastHighlitedActor = aHighlightedActor; - } - else + if( !aHighlightedActor ) { - //processing rectangle selection - Interactor->StartPickCallback(); - GetSelector()->StartPickCallback(); + if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != aHighlightedActor) + myLastHighlitedActor->Highlight( this, aSelectionEvent, false ); + } + myLastHighlitedActor = aHighlightedActor; + } + else + { + if ( myPoligonState == InProcess || myPoligonState == Closed ) + aSelectionEvent->myIsPolygon = true; + else aSelectionEvent->myIsRectangle = true; - if(!myShiftState) - GetSelector()->ClearIObjects(); + //processing polygonal selection + Interactor->StartPickCallback(); + GetSelector()->StartPickCallback(); + + if(!myShiftState) + GetSelector()->ClearIObjects(); - VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors()); - vtkActorCollection* aListActors = aCopy.GetActors(); - aListActors->InitTraversal(); - while(vtkActor* aActor = aListActors->GetNextActor()) + VTK::ActorCollectionCopy aCopy(GetCurrentRenderer()->GetActors()); + vtkActorCollection* aListActors = aCopy.GetActors(); + aListActors->InitTraversal(); + while(vtkActor* aActor = aListActors->GetNextActor()) + { + if(aActor->GetVisibility()) + { + if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) { - if(aActor->GetVisibility()) - { - if(SALOME_Actor* aSActor = SALOME_Actor::SafeDownCast(aActor)) - { - if(aSActor->hasIO()) - aSActor->Highlight( this, aSelectionEvent, true ); - } - } + if(aSActor->hasIO()) + aSActor->Highlight( this, aSelectionEvent, true ); } + } } + } + aSelectionEvent->myIsRectangle = false; + aSelectionEvent->myIsPolygon = false; + aSelectionEvent->myPolygonPoints.clear(); + endDrawPolygon(); Interactor->EndPickCallback(); GetSelector()->EndPickCallback(); } - } - break; - case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: - case VTK_INTERACTOR_STYLE_CAMERA_PAN: - case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: - case VTK_INTERACTOR_STYLE_CAMERA_SPIN: - break; - case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: + break; + } + case VTK_INTERACTOR_STYLE_CAMERA_ZOOM: + case VTK_INTERACTOR_STYLE_CAMERA_PAN: + case VTK_INTERACTOR_STYLE_CAMERA_ROTATE: + case VTK_INTERACTOR_STYLE_CAMERA_SPIN: + break; + case VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN: { int w, h, x, y; Interactor->GetSize(w, h); @@ -1198,7 +1274,10 @@ void SVTK_InteractorStyle::onOperation(QPoint mousePos) case VTK_INTERACTOR_STYLE_CAMERA_FIT: { myOtherPoint = mousePos; - drawRect(); + if ( myPoligonState == InProcess || myPoligonState == Closed || myPoligonState == NotValid ) + drawPolygon(); + else if ( myPoligonState != Finished ) + drawRect(); break; } } @@ -1493,6 +1572,131 @@ void SVTK_InteractorStyle::drawRect() myRectBand->setVisible( aRect.isValid() ); } +bool isIntersect( const QPoint& theStart1, const QPoint& theEnd1, + const QPoint& theStart2, const QPoint& theEnd2 ) +{ + if ( ( theStart1 == theStart2 && theEnd1 == theEnd2 ) || + ( theStart1 == theEnd2 && theEnd1 == theStart2 ) ) + return true; + + if ( theStart1 == theStart2 || theStart2 == theEnd1 || + theStart1 == theEnd2 || theEnd1 == theEnd2 ) + return false; + + double x11 = theStart1.x() * 1.0; + double x12 = theEnd1.x() * 1.0; + double y11 = theStart1.y() * 1.0; + double y12 = theEnd1.y() * 1.0; + + double x21 = theStart2.x() * 1.0; + double x22 = theEnd2.x() * 1.0; + double y21 = theStart2.y() * 1.0; + double y22 = theEnd2.y() * 1.0; + + double k1 = x12 == x11 ? 0 : ( y12 - y11 ) / ( x12 - x11 ); + double k2 = x22 == x21 ? 0 : ( y22 - y21 ) / ( x22 - x21 ); + + double b1 = y11 - k1 * x11; + double b2 = y21 - k2 * x21; + + if ( k1 == k2 ) + { + if ( b1 != b2 ) + return false; + else + return !( ( qMax( x11, x12 ) <= qMin( x21, x22 ) || + qMin( x11, x12 ) >= qMax( x21, x22 ) ) && + ( qMax( y11, y12 ) <= qMin( y21, y22 ) || + qMin( y11, y12 ) >= qMax( y21, y22 ) ) ); + } + else + { + double x0 = ( b2 - b1 ) / ( k1 - k2 ); + double y0 = ( k1 * b2 - k2 * b1 ) / ( k1 - k2 ); + + if ( qMin( x11, x12 ) < x0 && x0 < qMax( x11, x12 ) && + qMin( y11, y12 ) < y0 && y0 < qMax( y11, y12 ) && + qMin( x21, x22 ) < x0 && x0 < qMax( x21, x22 ) && + qMin( y21, y22 ) < y0 && y0 < qMax( y21, y22 ) ) + return true; + } + return false; +} + +bool isValid( const QPolygon* thePoints, const QPoint& theCurrent ) +{ + if ( !thePoints->count() ) + return true; + + if ( thePoints->count() == 1 && thePoints->point( 0 ) == theCurrent ) + return false; + + const QPoint& aLast = thePoints->point( thePoints->count() - 1 ); + + if ( aLast == theCurrent ) + return true; + + bool res = true; + for ( uint i = 0; i < thePoints->count() - 1 && res; i++ ) + { + const QPoint& aStart = thePoints->point( i ); + const QPoint& anEnd = thePoints->point( i + 1 ); + res = !isIntersect( aStart, anEnd, theCurrent, aLast ); + } + return res; +} + +/*! + Draws polygon +*/ +void SVTK_InteractorStyle::drawPolygon() +{ + QSize aToler( 5, 5 ); + if ( !myPolygonBand ) { + myPolygonBand = new QtxPolyRubberBand( GetRenderWidget() ); + QPalette palette; + palette.setColor( myPolygonBand->foregroundRole(), Qt::white ); + myPolygonBand->setPalette( palette ); + myPolygonPoints.append( QPoint( myPoint.x(), myPoint.y() ) ); + } + myPolygonBand->hide(); + + bool closed = false; + bool valid = GetRenderWidget()->rect().contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) ); + if ( !myPolygonPoints.at(0).isNull() ) + { + QRect aRect( myPolygonPoints.at(0).x() - aToler.width(), myPolygonPoints.at(0).y() - aToler.height(), + 2 * aToler.width(), 2 * aToler.height() ); + closed = aRect.contains( QPoint( myOtherPoint.x(), myOtherPoint.y() ) ); + } + + QPolygon* points = new QPolygon( myPolygonPoints ); + valid = valid && isValid( points, QPoint( myOtherPoint.x(), myOtherPoint.y() ) ); + myPoligonState = valid ? InProcess : NotValid; + delete points; + if ( closed && !valid ) + closed = false; + + if ( closed && myPolygonPoints.size() > 2 ) { + GetRenderWidget()->setCursor( Qt::CrossCursor ); + myPoligonState = Closed; + } + else if ( valid ) + GetRenderWidget()->setCursor( Qt::PointingHandCursor ); + else + GetRenderWidget()->setCursor( Qt::ForbiddenCursor ); + + myPolygonPoints.append( QPoint( myOtherPoint.x(), myOtherPoint.y() ) ); + + QPolygon aPolygon( myPolygonPoints ); + myPolygonBand->initGeometry( aPolygon ); + myPolygonBand->setVisible( true ); + + if ( myPolygonPoints.size() > 1 ) { + myPolygonPoints.remove( myPolygonPoints.size() - 1 ); + } +} + /*! \brief Delete rubber band on the end on the dragging operation. */ @@ -1504,6 +1708,19 @@ void SVTK_InteractorStyle::endDrawRect() myRectBand = 0; } +/*! + \brief Delete rubber band on the end on the dragging operation. +*/ +void SVTK_InteractorStyle::endDrawPolygon() +{ + if ( myPolygonBand ) myPolygonBand->hide(); + + delete myPolygonBand; + myPolygonBand = 0; + + myPolygonPoints.clear(); +} + /*! Main process event method (reimplemented from #vtkInteractorStyle) */ diff --git a/src/SVTK/SVTK_InteractorStyle.h b/src/SVTK/SVTK_InteractorStyle.h index fe174e8d2..4070d5516 100644 --- a/src/SVTK/SVTK_InteractorStyle.h +++ b/src/SVTK/SVTK_InteractorStyle.h @@ -37,6 +37,7 @@ #include #include +#include #include @@ -145,6 +146,8 @@ class QRubberBand; #define VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN 7 #define VTK_INTERACTOR_STYLE_CAMERA_SELECT_ROTATION_POINT 8 +enum PolygonState { Disable, Start, InProcess, Finished, Closed, NotValid }; + //! Introduce SALOME way of user interaction /*! This class defines SALOME way of user interaction for VTK viewer, as well, @@ -205,6 +208,9 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle //! To handle mouse wheel backward event (reimplemented from #vtkInteractorStyle) virtual void OnMouseWheelBackward(); + //! To handle mouse button double click event + virtual void OnMouseButtonDoubleClick(); + //! To handle keyboard event (reimplemented from #vtkInteractorStyle) virtual void OnChar(); @@ -231,7 +237,10 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle SVTK_Selector* GetSelector(); - int CurrentState() const { return State; } + int CurrentState() const { return State; } + PolygonState GetPolygonState() const { return myPoligonState; } + void SetPolygonState( const PolygonState& thePolygonState ) + { myPoligonState = thePolygonState; } void SetAdvancedZoomingEnabled( const bool theState ) { myIsAdvancedZoomingEnabled = theState; } bool IsAdvancedZoomingEnabled() const { return myIsAdvancedZoomingEnabled; } @@ -308,6 +317,8 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle void drawRect(); void endDrawRect(); + void drawPolygon(); + void endDrawPolygon(); protected: QCursor myDefCursor; @@ -354,10 +365,13 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle vtkSmartPointer myHighlightSelectionPointActor; vtkSmartPointer myPointPicker; - double myBBCenter[3]; + double myBBCenter[3]; bool myBBFirstCheck; QRubberBand* myRectBand; //!< selection rectangle rubber band + QtxPolyRubberBand* myPolygonBand; //!< polygonal selection + QVector myPolygonPoints; + PolygonState myPoligonState; bool myIsAdvancedZoomingEnabled; }; diff --git a/src/SVTK/SVTK_KeyFreeInteractorStyle.cxx b/src/SVTK/SVTK_KeyFreeInteractorStyle.cxx index 7564c17c4..32c0b96fe 100644 --- a/src/SVTK/SVTK_KeyFreeInteractorStyle.cxx +++ b/src/SVTK/SVTK_KeyFreeInteractorStyle.cxx @@ -37,8 +37,8 @@ vtkStandardNewMacro(SVTK_KeyFreeInteractorStyle); //---------------------------------------------------------------------------- SVTK_KeyFreeInteractorStyle::SVTK_KeyFreeInteractorStyle(): - myIsMidButtonDown( false ), - myIsLeftButtonDown( false ) + myIsLeftButtonDown( false ), + myIsRightButtonDown( false ) { } @@ -47,11 +47,37 @@ SVTK_KeyFreeInteractorStyle::~SVTK_KeyFreeInteractorStyle() { } +//---------------------------------------------------------------------------- +void SVTK_KeyFreeInteractorStyle::OnMouseMove(int ctrl, + int shift, + int x, int y) +{ + // OnLeftButtonDown + OnMouseMove = Rotate + if ( myIsLeftButtonDown ) { + OnLeftButtonDown( ctrl, shift, x, y ); + myIsLeftButtonDown = false; + } + // OnRightButtonDown + OnMouseMove = Zoom + if ( myIsRightButtonDown ) { + OnRightButtonDown( ctrl, shift, x, y ); + myIsRightButtonDown = false; + } + SVTK_InteractorStyle::OnMouseMove( ctrl, shift, x, y ); +} + //---------------------------------------------------------------------------- void SVTK_KeyFreeInteractorStyle::OnLeftButtonDown(int ctrl, int shift, int x, int y) { - myIsLeftButtonDown = true; + if ( ctrl ) { + SVTK_InteractorStyle::OnLeftButtonDown( !ctrl, shift, x, y ); + return; + } + + if( !myIsLeftButtonDown ) { + myIsLeftButtonDown = true; + return; + } if (this->HasObserver(vtkCommand::LeftButtonPressEvent)) { this->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL); @@ -71,16 +97,9 @@ void SVTK_KeyFreeInteractorStyle::OnLeftButtonDown(int ctrl, int shift, if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) { startOperation(ForcedState); } - else { - if (!(ctrl||shift)){ - if (myIsMidButtonDown){ - startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM); - } - else{ - startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE); - } - } - } + else if ( !shift ) + startOperation(VTK_INTERACTOR_STYLE_CAMERA_ROTATE); + return; } @@ -89,7 +108,10 @@ void SVTK_KeyFreeInteractorStyle::OnMiddleButtonDown(int ctrl, int shift, int x, int y) { - myIsMidButtonDown = true; + if ( ctrl ) { + SVTK_InteractorStyle::OnMiddleButtonDown( !ctrl, shift, x, y ); + return; + } if (this->HasObserver(vtkCommand::MiddleButtonPressEvent)) { this->InvokeEvent(vtkCommand::MiddleButtonPressEvent,NULL); @@ -109,36 +131,73 @@ void SVTK_KeyFreeInteractorStyle::OnMiddleButtonDown(int ctrl, if (ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE) { startOperation(ForcedState); } - else { - if (!(ctrl||shift)){ - if ( myIsLeftButtonDown ){ - startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM); - } - else{ - startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN); - } - } + else if ( !shift ) + startOperation(VTK_INTERACTOR_STYLE_CAMERA_PAN); +} + +//---------------------------------------------------------------------------- +void SVTK_KeyFreeInteractorStyle::OnRightButtonDown( int ctrl, + int shift, + int x, int y ) +{ + if ( ctrl ) { + SVTK_InteractorStyle::OnRightButtonDown( !ctrl, shift, x, y ); + return; } + + if( !myIsRightButtonDown ) { + myIsRightButtonDown = true; + return; + } + + if( this->HasObserver( vtkCommand::RightButtonPressEvent ) ) { + this->InvokeEvent( vtkCommand::RightButtonPressEvent, NULL ); + return; + } + this->FindPokedRenderer( x, y ); + if( this->CurrentRenderer == NULL ) { + return; + } + myShiftState = shift; + // finishing current viewer operation + if ( State != VTK_INTERACTOR_STYLE_CAMERA_NONE ) { + onFinishOperation(); + startOperation( VTK_INTERACTOR_STYLE_CAMERA_NONE ); + } + myOtherPoint = myPoint = QPoint(x, y); + if ( ForcedState != VTK_INTERACTOR_STYLE_CAMERA_NONE ) { + startOperation(ForcedState); + } + else if ( !shift ) + startOperation( VTK_INTERACTOR_STYLE_CAMERA_ZOOM ); } //---------------------------------------------------------------------------- void SVTK_KeyFreeInteractorStyle::OnLeftButtonUp(int ctrl, int shift, int x, int y) { - myIsLeftButtonDown = false; + // OnLeftButtonDown + OnLeftButtonUp = Select + if ( myIsLeftButtonDown ) { + SVTK_InteractorStyle::OnLeftButtonDown( ctrl, shift, x, y ); + myIsLeftButtonDown = false; + } SVTK_InteractorStyle::OnLeftButtonUp( ctrl, shift, x, y ); - - if ( myIsMidButtonDown ) - OnMiddleButtonDown( ctrl, shift, x, y ); } //---------------------------------------------------------------------------- void SVTK_KeyFreeInteractorStyle::OnMiddleButtonUp(int ctrl, int shift, int x, int y) { - myIsMidButtonDown = false; SVTK_InteractorStyle::OnMiddleButtonUp( ctrl, shift, x, y ); +} - if ( myIsLeftButtonDown ) - OnLeftButtonDown( ctrl, shift, x, y ); +//---------------------------------------------------------------------------- +void SVTK_KeyFreeInteractorStyle::OnRightButtonUp(int ctrl, int shift, int x, int y) +{ + // OnRightButtonDown + OnRightButtonUp = Open context menu + if( myIsRightButtonDown ) { + myIsRightButtonDown = false; + SVTK_InteractorStyle::OnRightButtonDown( ctrl, shift, x, y ); + } + SVTK_InteractorStyle::OnRightButtonUp( ctrl, shift, x, y ); } //---------------------------------------------------------------------------- diff --git a/src/SVTK/SVTK_KeyFreeInteractorStyle.h b/src/SVTK/SVTK_KeyFreeInteractorStyle.h index 8d4d053d9..dae65b44b 100644 --- a/src/SVTK/SVTK_KeyFreeInteractorStyle.h +++ b/src/SVTK/SVTK_KeyFreeInteractorStyle.h @@ -44,23 +44,32 @@ class SVTK_EXPORT SVTK_KeyFreeInteractorStyle : public SVTK_InteractorStyle // Generic event bindings must be overridden in subclasses + //! Redefine SVTK_InteractorStyle::OnMouseMove + virtual void OnMouseMove(int ctrl, int shift, int x, int y); + //! Redefine SVTK_InteractorStyle::OnLeftButtonDown virtual void OnLeftButtonDown(int ctrl, int shift, int x, int y); //! Redefine SVTK_InteractorStyle::OnMiddleButtonDown virtual void OnMiddleButtonDown(int ctrl, int shift, int x, int y); + //! Redefine SVTK_InteractorStyle::OnRightButtonDown + virtual void OnRightButtonDown(int ctrl, int shift, int x, int y); + //! Redefine SVTK_InteractorStyle::OnLeftButtonUp virtual void OnLeftButtonUp(int ctrl, int shift, int x, int y); //! Redefine SVTK_InteractorStyle::OnMiddleButtonUp virtual void OnMiddleButtonUp(int ctrl, int shift, int x, int y); + //! Redefine SVTK_InteractorStyle::OnRightButtonUp + virtual void OnRightButtonUp(int ctrl, int shift, int x, int y); + //! Redefine SVTK_InteractorStyle::OnChar virtual void OnChar(); - - bool myIsMidButtonDown; + bool myIsLeftButtonDown; + bool myIsRightButtonDown; }; #endif diff --git a/src/SVTK/SVTK_RectPicker.cxx b/src/SVTK/SVTK_RectPicker.cxx deleted file mode 100644 index f3251da6b..000000000 --- a/src/SVTK/SVTK_RectPicker.cxx +++ /dev/null @@ -1,498 +0,0 @@ -// 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 -// - -// SALOME VTKViewer : build VTK viewer into Salome desktop -// File : SVTK_RectPicker.cxx -// Author : -// Module : SALOME -// -#include "SVTK_RectPicker.h" - -#include - -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace -{ - //---------------------------------------------------------------------------- - inline - double - GetZ(float* theZPtr, - int theSelection[4], - int theDX, - int theDY) - { - return theZPtr[theDX - theSelection[0] + (theDY - theSelection[1])*(theSelection[2] - theSelection[0] + 1)]; - } - - - //---------------------------------------------------------------------------- - inline - int - Check(float* theZPtr, - int theSelection[4], - double theTolerance, - double theDZ, - int theDX, - int theDY) - { - int aRet = 0; - double aZ = -1.0; - if(theDX >= theSelection[0] && theDX <= theSelection[2] && - theDY >= theSelection[1] && theDY <= theSelection[3]) - { - // Access the value from the captured zbuffer. Note, we only - // captured a portion of the zbuffer, so we need to offset dx by - // the selection window. - aZ = GetZ(theZPtr,theSelection,theDX,theDY); - if(aZ > theTolerance && aZ < 1.0 - theTolerance){ - aRet = fabs(aZ - theDZ) <= theTolerance; - } - } - - //cout<<"\tCheck = {"<GetNumberOfPoints(); - if(aNumPts < 1) - return; - - theVisibleIds.reserve(aNumPts/2 + 1); - theInVisibleIds.reserve(aNumPts/2 + 1); - - // Grab the composite perspective transform. This matrix is used to convert - // each point to view coordinates. vtkRenderer provides a WorldToView() - // method but it computes the composite perspective transform each time - // WorldToView() is called. This is expensive, so we get the matrix once - // and handle the transformation ourselves. - vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New(); - aMatrix->DeepCopy( theRenderer->GetActiveCamera()-> - GetCompositeProjectionTransformMatrix( theRenderer->GetTiledAspectRatio(), 0, 1 ) ); - - // We grab the z-buffer for the selection region all at once and probe the resulting array. - float *aZPtr = theRenderer->GetRenderWindow()-> - GetZbufferData(theSelection[0], theSelection[1], theSelection[2], theSelection[3]); - - //cout<<"theSelection = {"<GetPoint(aPntId,aX); - - double aView[4]; - aMatrix->MultiplyPoint(aX,aView); - if(aView[3] == 0.0) - continue; - theRenderer->SetViewPoint(aView[0]/aView[3], - aView[1]/aView[3], - aView[2]/aView[3]); - theRenderer->ViewToDisplay(); - - double aDX[3]; - theRenderer->GetDisplayPoint(aDX); - - // check whether visible and in selection window - if(aDX[0] >= theSelection[0] && aDX[0] <= theSelection[2] && - aDX[1] >= theSelection[1] && aDX[1] <= theSelection[3]) - { - //cout<<"aPntId "< 0) - goto ADD_VISIBLE; - if(aRet < 0) - goto ADD_INVISIBLE; - - static int aMaxRadius = 5; - for(int aRadius = 1; aRadius < aMaxRadius; aRadius++){ - int aStartDX[2] = {aDX0 - aRadius, aDX1 - aRadius}; - for(int i = 0; i <= aRadius; i++){ - int aRet = Check(aZPtr,theSelection,theTolerance,aDX[2],aStartDX[0]++,aStartDX[1]); - if(aRet > 0) - goto ADD_VISIBLE; - if(aRet < 0) - goto ADD_INVISIBLE; - } - for(int i = 0; i <= aRadius; i++){ - int aRet = Check(aZPtr,theSelection,theTolerance,aDX[2],aStartDX[0],aStartDX[1]++); - if(aRet > 0) - goto ADD_VISIBLE; - if(aRet < 0) - goto ADD_INVISIBLE; - } - for(int i = 0; i <= aRadius; i++){ - int aRet = Check(aZPtr,theSelection,theTolerance,aDX[2],aStartDX[0]--,aStartDX[1]); - if(aRet > 0) - goto ADD_VISIBLE; - if(aRet < 0) - goto ADD_INVISIBLE; - } - for(int i = 0; i <= aRadius; i++){ - int aRet = Check(aZPtr,theSelection,theTolerance,aDX[2],aStartDX[0],aStartDX[1]--); - if(aRet > 0) - goto ADD_VISIBLE; - if(aRet < 0) - goto ADD_INVISIBLE; - } - } - if(false) - ADD_VISIBLE : theVisibleIds.push_back(aPntId); - if(false) - ADD_INVISIBLE : theInVisibleIds.push_back(aPntId); - } - }//for all points - - aMatrix->Delete(); - - if(aZPtr) - delete [] aZPtr; - } - - - //---------------------------------------------------------------------------- - inline - void - GetCenter(const double theBounds[6], - double theCenter[3]) - { - theCenter[0] = (theBounds[1] + theBounds[0]) / 2.0; - theCenter[1] = (theBounds[3] + theBounds[2]) / 2.0; - theCenter[2] = (theBounds[5] + theBounds[4]) / 2.0; - } - - void - SelectVisibleCells(int theSelection[4], - vtkRenderer *theRenderer, - vtkDataSet *theInput, - SVTK_RectPicker::TVectorIds& theVectorIds, - double theTolerance) - { - theVectorIds.clear(); - - vtkIdType aNumCells = theInput->GetNumberOfCells(); - if(aNumCells < 1) - return; - - theVectorIds.reserve(aNumCells/2 + 1); - - SVTK_RectPicker::TVectorIds aVisiblePntIds; - SVTK_RectPicker::TVectorIds anInVisiblePntIds; - SelectVisiblePoints(theSelection, - theRenderer, - theInput, - aVisiblePntIds, - anInVisiblePntIds, - theTolerance); - - typedef std::set TIdsSet; - TIdsSet aVisibleIds(aVisiblePntIds.begin(),aVisiblePntIds.end()); - TIdsSet anInVisibleIds(anInVisiblePntIds.begin(),anInVisiblePntIds.end()); - - // Grab the composite perspective transform. This matrix is used to convert - // each point to view coordinates. vtkRenderer provides a WorldToView() - // method but it computes the composite perspective transform each time - // WorldToView() is called. This is expensive, so we get the matrix once - // and handle the transformation ourselves. - vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New(); - aMatrix->DeepCopy(theRenderer->GetActiveCamera()-> - GetCompositeProjectionTransformMatrix( theRenderer->GetTiledAspectRatio(), 0, 1 ) ); - - for(vtkIdType aCellId = 0; aCellId < aNumCells; aCellId++){ - vtkCell* aCell = theInput->GetCell(aCellId); - - double aBounds[6]; - aCell->GetBounds(aBounds); - - double aCenter[3]; - GetCenter(aBounds,aCenter); - - double aView[4]; - double aX[4] = {aCenter[0], aCenter[1], aCenter[2], 1.0}; - aMatrix->MultiplyPoint(aX,aView); - - if(aView[3] == 0.0) - continue; - - theRenderer->SetViewPoint(aView[0]/aView[3], - aView[1]/aView[3], - aView[2]/aView[3]); - theRenderer->ViewToDisplay(); - - double aDX[3]; - theRenderer->GetDisplayPoint(aDX); - - // check whether visible and in selection window - if(aDX[0] >= theSelection[0] && aDX[0] <= theSelection[2] && - aDX[1] >= theSelection[1] && aDX[1] <= theSelection[3]) - { - - //cout<<"aCellId = "<GetNumberOfPoints(); - bool anIsVisible = true; - for(vtkIdType anId = 0; anId < aNumPts; anId++){ - vtkIdType aPntId = aCell->GetPointId(anId); - //cout<SetDisplayPoint(theSelectionX, theSelectionY, theSelectionZ); - theRenderer->DisplayToWorld(); - double* aWorldCoords = theRenderer->GetWorldPoint(); - if ( aWorldCoords[3] != 0.0 ) { - for (int i=0; i < 3; i++) { - thePickPosition[i] = aWorldCoords[i] / aWorldCoords[3]; - } - } - } -} - -vtkStandardNewMacro(SVTK_RectPicker); - -SVTK_RectPicker -::SVTK_RectPicker() -{ - this->Tolerance = 0.005; - this->PickPoints = 1; -} - -SVTK_RectPicker -::~SVTK_RectPicker() -{} - -int -SVTK_RectPicker -::Pick(double, - double, - double, - vtkRenderer*) -{ - return 0; -} - -int -SVTK_RectPicker -::Pick(double theSelection[3], - double theSelection2[3], - vtkRenderer *theRenderer) -{ - return Pick(theSelection[0], theSelection[1], theSelection[2], - theSelection2[0], theSelection2[1], theSelection2[2], - theRenderer); -} - -int -SVTK_RectPicker -::Pick(double theSelectionX, - double theSelectionY, - double theSelectionZ, - double theSelectionX2, - double theSelectionY2, - double theSelectionZ2, - vtkRenderer *theRenderer) -{ - // Initialize picking process - this->Initialize(); - myCellIdsMap.clear(); - myPointIdsMap.clear(); - this->Renderer = theRenderer; - - // Get camera focal point and position. Convert to display (screen) - // coordinates. We need a depth value for z-buffer. - // - vtkCamera* aCamera = theRenderer->GetActiveCamera(); - - double aCameraFP[4]; - aCamera->GetFocalPoint(aCameraFP); - aCameraFP[3] = 1.0; - - theRenderer->SetWorldPoint(aCameraFP); - theRenderer->WorldToDisplay(); - double* aDisplayCoords = theRenderer->GetDisplayPoint(); - double aSelectionZ = aDisplayCoords[2]; - - this->SelectionPoint[0] = theSelectionX; - this->SelectionPoint[1] = theSelectionY; - this->SelectionPoint[2] = theSelectionZ; - - // Convert the selection point into world coordinates. - // - CalculatePickPosition(theRenderer, - theSelectionX, - theSelectionY, - aSelectionZ, - this->PickPosition); - - this->SelectionPoint2[0] = theSelectionX2; - this->SelectionPoint2[1] = theSelectionY2; - this->SelectionPoint2[2] = theSelectionZ2; - - // Convert the selection point into world coordinates. - // - CalculatePickPosition(theRenderer, - theSelectionX2, - theSelectionY2, - aSelectionZ, - this->PickPosition2); - - // Invoke start pick method if defined - this->InvokeEvent(vtkCommand::StartPickEvent,NULL); - - vtkPropCollection *aProps; - if ( this->PickFromList ) - aProps = this->GetPickList(); - else - aProps = theRenderer->GetViewProps(); - - aProps->InitTraversal(); - while ( vtkProp* aProp = aProps->GetNextProp() ) { - aProp->InitPathTraversal(); - while ( vtkAssemblyPath* aPath = aProp->GetNextPath() ) { - vtkMapper *aMapper = NULL; - bool anIsPickable = false; - vtkActor* anActor = NULL; - vtkProp *aPropCandidate = aPath->GetLastNode()->GetViewProp(); - if ( aPropCandidate->GetPickable() && aPropCandidate->GetVisibility() ) { - anIsPickable = true; - anActor = vtkActor::SafeDownCast(aPropCandidate); - if ( anActor ) { - aMapper = anActor->GetMapper(); - if ( anActor->GetProperty()->GetOpacity() <= 0.0 ) - anIsPickable = false; - } - } - if ( anIsPickable && aMapper && aMapper->GetInput()) { - int aSelectionPoint[4] = {int(theSelectionX), - int(theSelectionY), - int(theSelectionX2), - int(theSelectionY2)}; - if ( this->PickPoints ) { - TVectorIds& aVisibleIds = myPointIdsMap[anActor]; - TVectorIds anInVisibleIds; - SelectVisiblePoints(aSelectionPoint, - theRenderer, - aMapper->GetInput(), - aVisibleIds, - anInVisibleIds, - this->Tolerance); - if ( aVisibleIds.empty() ) { - myPointIdsMap.erase(myPointIdsMap.find(anActor)); - } - } else { - TVectorIds& aVectorIds = myCellIdsMap[anActor]; - SelectVisibleCells(aSelectionPoint, - theRenderer, - aMapper->GetInput(), - aVectorIds, - this->Tolerance); - if ( aVectorIds.empty() ) { - myCellIdsMap.erase(myCellIdsMap.find(anActor)); - } - } - } - } - } - - // Invoke end pick method if defined - this->InvokeEvent(vtkCommand::EndPickEvent,NULL); - - return myPointIdsMap.empty() || myCellIdsMap.empty(); -} - - -const SVTK_RectPicker::TVectorIdsMap& -SVTK_RectPicker -::GetPointIdsMap() const -{ - return myPointIdsMap; -} - -const SVTK_RectPicker::TVectorIdsMap& -SVTK_RectPicker -::GetCellIdsMap() const -{ - return myCellIdsMap; -} diff --git a/src/SVTK/SVTK_RectPicker.h b/src/SVTK/SVTK_RectPicker.h deleted file mode 100644 index d49315907..000000000 --- a/src/SVTK/SVTK_RectPicker.h +++ /dev/null @@ -1,130 +0,0 @@ -// 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 -// - -// SALOME VTKViewer : build VTK viewer into Salome desktop -// File : SVTK_RectPicker.h -// Author : -// Module : SALOME -// -#ifndef __SVTK_RectPicker_h -#define __SVTK_RectPicker_h - -#include "SVTK.h" -#include "VTKViewer.h" - -#include -#include - -#include - -class vtkRenderer; - -#ifdef WIN32 -#pragma warning ( disable:4251 ) -#endif - -/*! \class vtkAbstractPropPicker - * \brief For more information see VTK documentation - */ -/*! \class SVTK_RectPicker - * \brief Rectangular picker class. - */ -class SVTK_EXPORT SVTK_RectPicker : public vtkAbstractPropPicker -{ - public: - static - SVTK_RectPicker *New(); - - vtkTypeMacro(SVTK_RectPicker,vtkAbstractPropPicker); - - /*! - Specify tolerance for performing pick operation. Tolerance is specified - as fraction of rendering window size. (Rendering window size is measured - across diagonal.) - */ - vtkSetMacro(Tolerance,double); - vtkGetMacro(Tolerance,double); - - //! Use these methods to pick points or points and cells - vtkSetMacro(PickPoints,int); - vtkGetMacro(PickPoints,int); - vtkBooleanMacro(PickPoints,int); - - virtual - int - Pick(double theSelectionX, - double theSelectionY, - double theSelectionZ, - double theSelectionX2, - double theSelectionY2, - double theSelectionZ2, - vtkRenderer *theRenderer); - - int - Pick(double theSelection[3], - double theSelection2[3], - vtkRenderer *theRenderer); - - typedef std::vector TVectorIds; - typedef std::map TVectorIdsMap; - - const TVectorIdsMap& - GetPointIdsMap() const; - - const TVectorIdsMap& - GetCellIdsMap() const; - - protected: - SVTK_RectPicker(); - ~SVTK_RectPicker(); - - //! tolerance for computation (% of window) - double Tolerance; - - //! use the following to control picking mode - int PickPoints; - - //! second rectangle selection point in window (pixel) coordinates - double SelectionPoint2[3]; - - //! second rectangle selection point in world coordinates - double PickPosition2[3]; - - TVectorIdsMap myPointIdsMap; - TVectorIdsMap myCellIdsMap; - - private: - virtual - int - Pick(double, - double, - double, - vtkRenderer*); -}; - -#ifdef WIN32 -#pragma warning ( default:4251 ) -#endif - -#endif - - diff --git a/src/SVTK/SVTK_RenderWindowInteractor.cxx b/src/SVTK/SVTK_RenderWindowInteractor.cxx index 50a089312..560cef7c3 100644 --- a/src/SVTK/SVTK_RenderWindowInteractor.cxx +++ b/src/SVTK/SVTK_RenderWindowInteractor.cxx @@ -724,17 +724,25 @@ void SVTK_RenderWindowInteractor ::mouseReleaseEvent( QMouseEvent *event ) { + SVTK_InteractorStyle* style = 0; bool aRightBtn = event->button() == Qt::RightButton; bool isOperation = false; + bool isPolygonalSelection = false; if( aRightBtn && GetInteractorStyle()) { - SVTK_InteractorStyle* style = dynamic_cast( GetInteractorStyle() ); + style = dynamic_cast( GetInteractorStyle() ); if ( style ) isOperation = style->CurrentState() != VTK_INTERACTOR_STYLE_CAMERA_NONE; } QVTK_RenderWindowInteractor::mouseReleaseEvent(event); - if ( aRightBtn && !isOperation && !( event->modifiers() & Qt::ControlModifier ) && + if ( style ) { + isPolygonalSelection = style->GetPolygonState() == Finished; + style->SetPolygonState( Disable ); + } + + if ( aRightBtn && !isOperation && !isPolygonalSelection && + !( event->modifiers() & Qt::ControlModifier ) && !( event->modifiers() & Qt::ShiftModifier ) ) { QContextMenuEvent aEvent( QContextMenuEvent::Mouse, event->pos(), event->globalPos() ); @@ -752,6 +760,12 @@ void SVTK_RenderWindowInteractor ::mouseDoubleClickEvent( QMouseEvent* event ) { + if( GetInteractorStyle() && event->button() == Qt::LeftButton ) { + SVTK_InteractorStyle* style = dynamic_cast( GetInteractorStyle() ); + if ( style ) + style->OnMouseButtonDoubleClick(); + } + QVTK_RenderWindowInteractor::mouseDoubleClickEvent(event); if(GENERATE_SUIT_EVENTS) diff --git a/src/SVTK/SVTK_Renderer.cxx b/src/SVTK/SVTK_Renderer.cxx index fa09eb29f..75c9574a3 100644 --- a/src/SVTK/SVTK_Renderer.cxx +++ b/src/SVTK/SVTK_Renderer.cxx @@ -28,7 +28,7 @@ #include "SVTK_Trihedron.h" #include "SVTK_CubeAxesActor2D.h" -#include "SVTK_RectPicker.h" +#include "SVTK_AreaPicker.h" #include "SALOME_Actor.h" #include "VTKViewer_Actor.h" @@ -67,8 +67,8 @@ SVTK_Renderer myEventCallbackCommand(vtkCallbackCommand::New()), myPointPicker(vtkPointPicker::New()), myCellPicker(vtkCellPicker::New()), - myPointRectPicker(SVTK_RectPicker::New()), - myCellRectPicker(SVTK_RectPicker::New()), + myPointAreaPicker(SVTK_AreaPicker::New()), + myCellAreaPicker(SVTK_AreaPicker::New()), myPreHighlightProperty(vtkProperty::New()), myHighlightProperty(vtkProperty::New()), myTransform(VTKViewer_Transform::New()), @@ -83,12 +83,12 @@ SVTK_Renderer myPointPicker->Delete(); myCellPicker->Delete(); - myPointRectPicker->Delete(); - myPointRectPicker->PickFromListOn(); + myPointAreaPicker->Delete(); + myPointAreaPicker->PickFromListOn(); - myCellRectPicker->Delete(); - myCellRectPicker->PickFromListOn(); - myCellRectPicker->PickPointsOff(); + myCellAreaPicker->Delete(); + myCellAreaPicker->PickFromListOn(); + myCellAreaPicker->PickPointsOff(); //SetPreselectionProp(); myPreHighlightProperty->Delete(); @@ -244,8 +244,8 @@ SVTK_Renderer anActor->SetPointPicker(myPointPicker.GetPointer()); anActor->SetCellPicker(myCellPicker.GetPointer()); - anActor->SetPointRectPicker(myPointRectPicker.GetPointer()); - anActor->SetCellRectPicker(myCellRectPicker.GetPointer()); + anActor->SetPointAreaPicker(myPointAreaPicker.GetPointer()); + anActor->SetCellAreaPicker(myCellAreaPicker.GetPointer()); anActor->SetPreHighlightProperty(myPreHighlightProperty.GetPointer()); anActor->SetHighlightProperty(myHighlightProperty.GetPointer()); @@ -275,8 +275,8 @@ SVTK_Renderer anActor->SetPointPicker(NULL); anActor->SetCellPicker(NULL); - anActor->SetPointRectPicker(NULL); - anActor->SetCellRectPicker(NULL); + anActor->SetPointAreaPicker(NULL); + anActor->SetCellAreaPicker(NULL); anActor->SetPreHighlightProperty(NULL); anActor->SetHighlightProperty(NULL); @@ -369,8 +369,8 @@ SVTK_Renderer myPointPicker->SetTolerance( theTolNodes ); myCellPicker->SetTolerance( theTolCell ); - myPointRectPicker->SetTolerance( theTolNodes ); - myCellRectPicker->SetTolerance( theTolCell ); + myPointAreaPicker->SetTolerance( theTolNodes ); + myCellAreaPicker->SetTolerance( theTolCell ); mySelector->SetTolerance( theTolObjects ); } diff --git a/src/SVTK/SVTK_Renderer.h b/src/SVTK/SVTK_Renderer.h index d8e545f84..6c9781286 100644 --- a/src/SVTK/SVTK_Renderer.h +++ b/src/SVTK/SVTK_Renderer.h @@ -42,7 +42,7 @@ class vtkPointPicker; class vtkCellPicker; class vtkProperty; -class SVTK_RectPicker; +class SVTK_AreaPicker; class VTKViewer_Trihedron; class VTKViewer_Transform; @@ -242,8 +242,8 @@ protected: vtkSmartPointer myPointPicker; vtkSmartPointer myCellPicker; - vtkSmartPointer myPointRectPicker; - vtkSmartPointer myCellRectPicker; + vtkSmartPointer myPointAreaPicker; + vtkSmartPointer myCellAreaPicker; vtkSmartPointer myPreHighlightProperty; vtkSmartPointer myHighlightProperty; diff --git a/src/SVTK/SVTK_SelectionEvent.h b/src/SVTK/SVTK_SelectionEvent.h index 8378968df..4104194e2 100644 --- a/src/SVTK/SVTK_SelectionEvent.h +++ b/src/SVTK/SVTK_SelectionEvent.h @@ -28,6 +28,8 @@ #define SVTK_SELECTIONEVENT_H #include "SVTK_Selection.h" +#include +#include //! The structure is used for passing all infromation necessary for claculation of the selection. /*! @@ -44,6 +46,8 @@ struct SVTK_SelectionEvent int myLastX; //!< Last X position of the mouse before starting any complex operation (like rectangle selection) int myLastY; //!< Last Y position of the mouse before starting any complex operation bool myIsRectangle; //!< A flag to define is it necessary provide rectangle selection for current #Selection_Mode + bool myIsPolygon; //!< A flag to define is it necessary provide polygonal selection for current #Selection_Mode + QVector myPolygonPoints; //!< Vector of points for polygonal selection bool myIsCtrl; //!< Is Ctrl key are pressed bool myIsShift; //!< Is Shift key are pressed int myKeyCode; //!< Code of the pressed key diff --git a/src/VTKViewer/VTKViewer_InteractorStyle.cxx b/src/VTKViewer/VTKViewer_InteractorStyle.cxx index c2dc77e28..f1eee7c69 100644 --- a/src/VTKViewer/VTKViewer_InteractorStyle.cxx +++ b/src/VTKViewer/VTKViewer_InteractorStyle.cxx @@ -1038,7 +1038,7 @@ void VTKViewer_InteractorStyle::onFinishOperation() case FaceSelection: case VolumeSelection: { - vtkSmartPointer picker = VTKViewer_CellRectPicker::New(); + vtkSmartPointer picker = VTKViewer_CellRectPicker::New(); picker->SetTolerance(0.001); picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer); @@ -1077,7 +1077,7 @@ void VTKViewer_InteractorStyle::onFinishOperation() break; case ActorSelection: // objects selection { - vtkSmartPointer picker = VTKViewer_RectPicker::New(); + vtkSmartPointer picker = VTKViewer_AreaPicker::New(); picker->SetTolerance(0.001); picker->Pick(x1, y1, 0.0, x2, y2, 0.0, this->CurrentRenderer);