From 97fef2383f06436d0d7cafb3f1885921cfedb8dd Mon Sep 17 00:00:00 2001 From: mkr Date: Tue, 21 Nov 2006 14:01:27 +0000 Subject: [PATCH] Fix for IPAL10048 : Changing rotation point in GUI visualization. --- src/OCCViewer/Makefile.in | 6 +- src/OCCViewer/OCCViewer_ClippingDlg.cxx | 17 + src/OCCViewer/OCCViewer_ClippingDlg.h | 3 + .../OCCViewer_SetRotationPointDlg.cxx | 266 +++++++++++++++ src/OCCViewer/OCCViewer_SetRotationPointDlg.h | 82 +++++ src/OCCViewer/OCCViewer_ViewModel.cxx | 5 + src/OCCViewer/OCCViewer_ViewPort3d.cxx | 108 ++++-- src/OCCViewer/OCCViewer_ViewPort3d.h | 4 +- src/OCCViewer/OCCViewer_ViewWindow.cxx | 320 ++++++++++++++++-- src/OCCViewer/OCCViewer_ViewWindow.h | 37 +- src/OCCViewer/resources/OCCViewer_images.po | 3 + src/OCCViewer/resources/OCCViewer_msg_en.po | 36 ++ .../resources/view_rotation_point.png | Bin 0 -> 988 bytes src/SOCC/SOCC_ViewWindow.cxx | 16 +- src/SVTK/Makefile.in | 2 + src/SVTK/SVTK_Event.h | 8 + src/SVTK/SVTK_InteractorStyle.cxx | 245 +++++++++++++- src/SVTK/SVTK_InteractorStyle.h | 20 +- src/SVTK/SVTK_MainWindow.cxx | 63 ++++ src/SVTK/SVTK_MainWindow.h | 11 +- src/SVTK/SVTK_SetRotationPointDlg.cxx | 316 +++++++++++++++++ src/SVTK/SVTK_SetRotationPointDlg.h | 108 ++++++ src/SVTK/resources/SVTK_msg_en.po | 39 +++ 23 files changed, 1640 insertions(+), 75 deletions(-) create mode 100644 src/OCCViewer/OCCViewer_SetRotationPointDlg.cxx create mode 100644 src/OCCViewer/OCCViewer_SetRotationPointDlg.h create mode 100755 src/OCCViewer/resources/view_rotation_point.png create mode 100755 src/SVTK/SVTK_SetRotationPointDlg.cxx create mode 100755 src/SVTK/SVTK_SetRotationPointDlg.h diff --git a/src/OCCViewer/Makefile.in b/src/OCCViewer/Makefile.in index 842759ae3..c8e9a28d1 100755 --- a/src/OCCViewer/Makefile.in +++ b/src/OCCViewer/Makefile.in @@ -54,7 +54,8 @@ LIB_SRC= OCCViewer_AISSelector.cxx \ OCCViewer_ViewWindow.cxx \ OCCViewer_VService.cxx \ OCCViewer_CreateRestoreViewDlg.cxx \ - OCCViewer_ClippingDlg.cxx + OCCViewer_ClippingDlg.cxx \ + OCCViewer_SetRotationPointDlg.cxx LIB_MOC = OCCViewer_AISSelector.h \ OCCViewer_ViewModel.h \ @@ -63,7 +64,8 @@ LIB_MOC = OCCViewer_AISSelector.h \ OCCViewer_ViewWindow.h \ OCCViewer_ViewManager.h \ OCCViewer_CreateRestoreViewDlg.h \ - OCCViewer_ClippingDlg.h + OCCViewer_ClippingDlg.h \ + OCCViewer_SetRotationPointDlg.h RESOURCES_FILES = \ view_back.png \ diff --git a/src/OCCViewer/OCCViewer_ClippingDlg.cxx b/src/OCCViewer/OCCViewer_ClippingDlg.cxx index bedb9eacb..106e28b8f 100644 --- a/src/OCCViewer/OCCViewer_ClippingDlg.cxx +++ b/src/OCCViewer/OCCViewer_ClippingDlg.cxx @@ -220,6 +220,9 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, QWidge connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ); myBusy = false; + + connect(view, SIGNAL(Show( QShowEvent * )), this, SLOT(onViewShow())); + connect(view, SIGNAL(Hide( QHideEvent * )), this, SLOT(onViewHide())); } /*! @@ -559,3 +562,17 @@ void OCCViewer_ClippingDlg::ReserveClippingPlane() myClippingPlane = aView3d->ActivePlane(); } } + +void OCCViewer_ClippingDlg::onViewShow() +{ + if(myAction->isOn()) + show(); + else + hide(); +} + +void OCCViewer_ClippingDlg::onViewHide() +{ + hide(); +} + diff --git a/src/OCCViewer/OCCViewer_ClippingDlg.h b/src/OCCViewer/OCCViewer_ClippingDlg.h index 27efa2e90..bed795811 100644 --- a/src/OCCViewer/OCCViewer_ClippingDlg.h +++ b/src/OCCViewer/OCCViewer_ClippingDlg.h @@ -105,6 +105,9 @@ private slots: void onModeChanged( int mode ); void onValueChanged(); void onPreview( bool on ); + + void onViewShow(); + void onViewHide(); }; #endif // OCCVIEWER_CLIPPINGDLG_H diff --git a/src/OCCViewer/OCCViewer_SetRotationPointDlg.cxx b/src/OCCViewer/OCCViewer_SetRotationPointDlg.cxx new file mode 100644 index 000000000..1ce5ab4a4 --- /dev/null +++ b/src/OCCViewer/OCCViewer_SetRotationPointDlg.cxx @@ -0,0 +1,266 @@ +// Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "OCCViewer_SetRotationPointDlg.h" + +#include + +#include "OCCViewer_ViewWindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + Constructor + \param view - view window + \param parent - parent widget + \param name - dialog name + \param modal - is this dialog modal + \param fl - flags +*/ +OCCViewer_SetRotationPointDlg::OCCViewer_SetRotationPointDlg( OCCViewer_ViewWindow* view, QWidget* parent, const char* name, bool modal, WFlags fl ) +: QDialog( parent, "OCCViewer_SetRotationPointDlg", modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ), + myView( view ) +{ + setCaption(tr("CAPTION")); + setSizeGripEnabled(TRUE); + + // Create layout for this dialog + QGridLayout* layoutDlg = new QGridLayout (this); + layoutDlg->setSpacing(6); + layoutDlg->setMargin(11); + + // Create check box "Use Bounding Box Center" + QHBox* aCheckBox = new QHBox(this); + + myIsBBCenter = new QCheckBox(tr("USE_BBCENTER"), aCheckBox); + myIsBBCenter->setChecked(true); + connect(myIsBBCenter, SIGNAL(stateChanged(int)), SLOT(onBBCenterChecked())); + + // Create croup button with radio buttons + myGroupSelButton = new QButtonGroup(2,Qt::Vertical,"",this); + myGroupSelButton->setMargin(11); + + // Create "Set to Origin" button + myToOrigin = new QPushButton(myGroupSelButton); + myToOrigin->setText(tr("LBL_TOORIGIN")); + connect(myToOrigin, SIGNAL(clicked()), this, SLOT(onToOrigin())); + + // Create "Select Point from View" button + mySelectPoint = new QPushButton(myGroupSelButton); + mySelectPoint->setText(tr("LBL_SELECTPOINT")); + mySelectPoint->setToggleButton(true); + connect(mySelectPoint, SIGNAL(clicked()), this, SLOT(onSelectPoint())); + + // Create croup box with grid layout + myGroupBoxCoord = new QGroupBox(this, "GroupBox"); + QHBoxLayout* aHBoxLayout = new QHBoxLayout(myGroupBoxCoord); + aHBoxLayout->setMargin(11); + aHBoxLayout->setSpacing(6); + + // "X" coordinate + QLabel* TextLabelX = new QLabel (tr("LBL_X"), myGroupBoxCoord, "TextLabelX"); + TextLabelX->setFixedWidth(15); + myX = new QLineEdit(myGroupBoxCoord); + myX->setValidator(new QDoubleValidator(myX)); + myX->setText(QString::number(0.0)); + connect(myX, SIGNAL(textChanged(const QString&)), this, SLOT(onCoordChanged())); + + // "Y" coordinate + QLabel* TextLabelY = new QLabel (tr("LBL_Y"), myGroupBoxCoord, "TextLabelY"); + TextLabelY->setFixedWidth(15); + myY = new QLineEdit(myGroupBoxCoord); + myY->setValidator(new QDoubleValidator(myY)); + myY->setText(QString::number(0.0)); + connect(myY, SIGNAL(textChanged(const QString&)), this, SLOT(onCoordChanged())); + + // "Z" coordinate + QLabel* TextLabelZ = new QLabel (tr("LBL_Z"), myGroupBoxCoord, "TextLabelZ"); + TextLabelZ->setFixedWidth(15); + myZ = new QLineEdit(myGroupBoxCoord); + myZ->setValidator(new QDoubleValidator(myZ)); + myZ->setText(QString::number(0.0)); + connect(myZ, SIGNAL(textChanged(const QString&)), this, SLOT(onCoordChanged())); + + // Layout widgets in the horizontal group box + aHBoxLayout->addWidget(TextLabelX); + aHBoxLayout->addWidget(myX); + aHBoxLayout->addWidget(TextLabelY); + aHBoxLayout->addWidget(myY); + aHBoxLayout->addWidget(TextLabelZ); + aHBoxLayout->addWidget(myZ); + + // "Close" button + QGroupBox* aGroupBox = new QGroupBox(this); + QHBoxLayout* aHBoxLayout2 = new QHBoxLayout(aGroupBox); + aHBoxLayout2->setMargin(11); + aHBoxLayout2->setSpacing(6); + + QPushButton* m_bClose = new QPushButton(tr("&Close"), aGroupBox, "m_bClose"); + m_bClose->setAutoDefault(TRUE); + m_bClose->setFixedSize(m_bClose->sizeHint()); + connect(m_bClose, SIGNAL(clicked()), this, SLOT(onClickClose())); + + // Layout buttons + aHBoxLayout2->addWidget(m_bClose); + + // Layout top level widgets + layoutDlg->addWidget(aCheckBox,0,0); + layoutDlg->addWidget(myGroupSelButton,1,0); + layoutDlg->addWidget(myGroupBoxCoord,2,0); + layoutDlg->addWidget(aGroupBox,3,0); + + setEnabled(myGroupSelButton,!myIsBBCenter->isChecked()); + setEnabled(myGroupBoxCoord,!myIsBBCenter->isChecked()); + + this->resize(400, this->sizeHint().height()); + + connect(view, SIGNAL(Show( QShowEvent * )), this, SLOT(onViewShow())); + connect(view, SIGNAL(Hide( QHideEvent * )), this, SLOT(onViewHide())); +} + +/* + * Destroys the object and frees any allocated resources + */ +OCCViewer_SetRotationPointDlg +::~OCCViewer_SetRotationPointDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + +/*! + Return true if it is the first show for this dialog +*/ +bool +OCCViewer_SetRotationPointDlg +::IsFirstShown() +{ + return myIsBBCenter->isChecked() && myX->text().toDouble() == 0. + && myY->text().toDouble() == 0. && myZ->text().toDouble() == 0.; +} + +void +OCCViewer_SetRotationPointDlg +::setEnabled(QGroupBox* theGrp, const bool theState) +{ + QObjectList aChildren(*theGrp->children()); + QObject* anObj; + for(anObj = aChildren.first(); anObj !=0; anObj = aChildren.next()) + { + if (anObj !=0 && anObj->inherits("QLineEdit")) + ((QLineEdit*)anObj)->setReadOnly(!theState); + if (anObj !=0 && anObj->inherits("QPushButton")) + ((QLineEdit*)anObj)->setEnabled(theState); + } + +} + +void +OCCViewer_SetRotationPointDlg +::onBBCenterChecked() +{ + setEnabled(myGroupSelButton,!myIsBBCenter->isChecked()); + setEnabled(myGroupBoxCoord,!myIsBBCenter->isChecked()); + + if ( myIsBBCenter->isChecked() ) + myView->activateSetRotationGravity(); + else + myView->activateSetRotationSelected(myX->text().toDouble(), + myY->text().toDouble(), + myZ->text().toDouble()); +} + +void +OCCViewer_SetRotationPointDlg +::onToOrigin() +{ + setCoords(); + myView->activateSetRotationSelected(myX->text().toDouble(), + myY->text().toDouble(), + myZ->text().toDouble()); +} + +void +OCCViewer_SetRotationPointDlg +::onSelectPoint() +{ + if ( mySelectPoint->state() == QButton::On ) + myView->activateStartPointSelection(); + else + mySelectPoint->toggle(); +} + +void +OCCViewer_SetRotationPointDlg +::onCoordChanged() +{ + if ( !myIsBBCenter->isChecked() ) + myView->activateSetRotationSelected(myX->text().toDouble(), + myY->text().toDouble(), + myZ->text().toDouble()); +} + +void +OCCViewer_SetRotationPointDlg +::setCoords(double theX, double theY, double theZ) +{ + myX->setText(QString::number(theX)); + myY->setText(QString::number(theY)); + myZ->setText(QString::number(theZ)); +} + +void +OCCViewer_SetRotationPointDlg +::toggleChange() +{ + if ( !myIsBBCenter->isChecked() ) + mySelectPoint->toggle(); +} + +void +OCCViewer_SetRotationPointDlg +::onClickClose() +{ + myAction->setOn( false ); + reject(); +} + +void +OCCViewer_SetRotationPointDlg +::onViewShow() +{ + if(myAction->isOn()) + show(); + else + hide(); +} + +void +OCCViewer_SetRotationPointDlg +::onViewHide() +{ + hide(); +} diff --git a/src/OCCViewer/OCCViewer_SetRotationPointDlg.h b/src/OCCViewer/OCCViewer_SetRotationPointDlg.h new file mode 100644 index 000000000..af8430468 --- /dev/null +++ b/src/OCCViewer/OCCViewer_SetRotationPointDlg.h @@ -0,0 +1,82 @@ +// Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef OCCVIEWER_SETROTATIONPOINTDLG_H +#define OCCVIEWER_SETROTATIONPOINTDLG_H + +#include "OCCViewer.h" + +#include + +class QtxAction; + +class QLineEdit; +class QPushButton; +class QGroupBox; +class QButtonGroup; +class QCheckBox; + +class OCCViewer_ViewWindow; + +class OCCViewer_SetRotationPointDlg : public QDialog +{ + Q_OBJECT + +public: + OCCViewer_SetRotationPointDlg(OCCViewer_ViewWindow* , QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0); + ~OCCViewer_SetRotationPointDlg(); + + void SetAction( QtxAction* theAction ) { myAction = theAction; } + bool IsFirstShown(); + + void setCoords(double theX=0., double theY=0., double theZ=0.); + void toggleChange(); + +protected: + OCCViewer_ViewWindow* myView; + QtxAction* myAction; + + QCheckBox* myIsBBCenter; + + QButtonGroup* myGroupSelButton; + QPushButton* myToOrigin; + QPushButton* mySelectPoint; + + QGroupBox* myGroupBoxCoord; + QLineEdit* myX; + QLineEdit* myY; + QLineEdit* myZ; + + void setEnabled(QGroupBox* theGrp, const bool theState); + +protected slots: + void onBBCenterChecked(); + + void onToOrigin(); + void onSelectPoint(); + + void onCoordChanged(); + + void onClickClose(); + + void onViewShow(); + void onViewHide(); +}; + +#endif // OCCVIEWER_SETROTATIONPOINTDLG_H diff --git a/src/OCCViewer/OCCViewer_ViewModel.cxx b/src/OCCViewer/OCCViewer_ViewModel.cxx index 2cba6871c..41cafa2c9 100755 --- a/src/OCCViewer/OCCViewer_ViewModel.cxx +++ b/src/OCCViewer/OCCViewer_ViewModel.cxx @@ -335,8 +335,13 @@ void OCCViewer_Viewer::onShowToolbar() { */ void OCCViewer_Viewer::update() { + printf("=========== OCCViewer_Viewer::update()\n"); if (!myV3dViewer.IsNull()) myV3dViewer->Update(); + + OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView()); + if ( aView ) + aView->updateGravityCoords(); } /*! diff --git a/src/OCCViewer/OCCViewer_ViewPort3d.cxx b/src/OCCViewer/OCCViewer_ViewPort3d.cxx index 50930efbc..1a83b55ea 100755 --- a/src/OCCViewer/OCCViewer_ViewPort3d.cxx +++ b/src/OCCViewer/OCCViewer_ViewPort3d.cxx @@ -20,6 +20,7 @@ #include "OCCViewer_ViewPort3d.h" #include "OCCViewer_VService.h" +#include "OCCViewer_ViewWindow.h" #include #include @@ -35,6 +36,12 @@ #include #endif +static double rx = 0.; +static double ry = 0.; +static int sx = 0; +static int sy = 0; +static Standard_Boolean zRotation = Standard_False; + /*! Constructor */ @@ -314,25 +321,86 @@ void OCCViewer_ViewPort3d::pan( int dx, int dy ) /*! Inits 'rotation' transformation. [ protected ] */ -void OCCViewer_ViewPort3d::startRotation( int x, int y ) +void OCCViewer_ViewPort3d::startRotation( int x, int y, + int theRotationPointType, + const gp_Pnt& theSelectedPoint ) { - if ( !activeView().IsNull() ) - { - myDegenerated = activeView()->DegenerateModeIsOn(); - activeView()->SetDegenerateModeOn(); - if (myAnimate) activeView()->SetAnimationModeOn(); - activeView()->StartRotation( x, y, 0.45 ); + if ( !activeView().IsNull() ) + { + myDegenerated = activeView()->DegenerateModeIsOn(); + activeView()->SetDegenerateModeOn(); + if (myAnimate) activeView()->SetAnimationModeOn(); + + //double gx, gy, gz; + //double gx = activeView()->gx; + //activeView()->Gravity(gx,gy,gz); + + switch ( theRotationPointType ) { + case OCCViewer_ViewWindow::GRAVITY: + activeView()->StartRotation( x, y, 0.45 ); + break; + case OCCViewer_ViewWindow::SELECTED: + sx = x; sy = y; + + double X,Y; + activeView()->Size(X,Y); + rx = Standard_Real(activeView()->Convert(X)); + ry = Standard_Real(activeView()->Convert(Y)); + + activeView()->Rotate( 0., 0., 0., + theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(), + Standard_True ); + + Quantity_Ratio zRotationThreshold; + zRotation = Standard_False; + zRotationThreshold = 0.45; + if( zRotationThreshold > 0. ) { + Standard_Real dx = Abs(sx - rx/2.); + Standard_Real dy = Abs(sy - ry/2.); + Standard_Real dd = zRotationThreshold * (rx + ry)/2.; + if( dx > dd || dy > dd ) zRotation = Standard_True; } + break; + default: + break; + } + } } /*! Rotates the viewport. [ protected ] */ -void OCCViewer_ViewPort3d::rotate( int x, int y ) +void OCCViewer_ViewPort3d::rotate( int x, int y, + int theRotationPointType, + const gp_Pnt& theSelectedPoint ) { - if ( !activeView().IsNull() ) - activeView()->Rotation( x, y ); -// setZSize( getZSize() ); + if ( !activeView().IsNull() ) { + switch ( theRotationPointType ) { + case OCCViewer_ViewWindow::GRAVITY: + activeView()->Rotation( x, y ); + break; + case OCCViewer_ViewWindow::SELECTED: + double dx, dy, dz; + if( zRotation ) { + dz = atan2(Standard_Real(x)-rx/2., ry/2.-Standard_Real(y)) - + atan2(sx-rx/2.,ry/2.-sy); + dx = dy = 0.; + } + else { + dx = (Standard_Real(x) - sx) * Standard_PI/rx; + dy = (sy - Standard_Real(y)) * Standard_PI/ry; + dz = 0.; + } + + activeView()->Rotate( dx, dy, dz, + theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(), + Standard_False ); + break; + default: + break; + } + } + // setZSize( getZSize() ); } /*! @@ -340,15 +408,15 @@ void OCCViewer_ViewPort3d::rotate( int x, int y ) */ void OCCViewer_ViewPort3d::endRotation() { - if ( !activeView().IsNull() ) - { - if (myAnimate) activeView()->SetAnimationModeOff(); - if ( !myDegenerated ) - activeView()->SetDegenerateModeOff(); - activeView()->ZFitAll(1.); - activeView()->SetZSize(0.); - activeView()->Update(); - } + if ( !activeView().IsNull() ) + { + if (myAnimate) activeView()->SetAnimationModeOff(); + if ( !myDegenerated ) + activeView()->SetDegenerateModeOff(); + activeView()->ZFitAll(1.); + activeView()->SetZSize(0.); + activeView()->Update(); + } } /*! diff --git a/src/OCCViewer/OCCViewer_ViewPort3d.h b/src/OCCViewer/OCCViewer_ViewPort3d.h index 204b8eb99..c1cd248b0 100755 --- a/src/OCCViewer/OCCViewer_ViewPort3d.h +++ b/src/OCCViewer/OCCViewer_ViewPort3d.h @@ -64,8 +64,8 @@ public: virtual void zoom( int, int, int, int ); virtual void fitAll( bool keepScale = false, bool withZ = true, bool upd = true ); - void startRotation( int, int ); - void rotate( int, int ); + void startRotation( int, int, int, const gp_Pnt& ); + void rotate( int, int, int, const gp_Pnt& ); void endRotation(); protected: diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index cef3b10d8..d921e3053 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -24,6 +24,7 @@ #include "OCCViewer_ViewPort3d.h" #include "OCCViewer_CreateRestoreViewDlg.h" #include "OCCViewer_ClippingDlg.h" +#include "OCCViewer_SetRotationPointDlg.h" #include "SUIT_Desktop.h" #include "SUIT_Session.h" @@ -46,6 +47,19 @@ #include #include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + + const char* imageZoomCursor[] = { "32 32 3 1", ". c None", @@ -174,6 +188,7 @@ OCCViewer_ViewWindow::OCCViewer_ViewWindow(SUIT_Desktop* theDesktop, OCCViewer_V myEnableDrawMode = false; updateEnabledDrawMode(); myClippingDlg = 0; + mySetRotationPointDlg = 0; } /*! @@ -184,9 +199,14 @@ void OCCViewer_ViewWindow::initLayout() myViewPort = new OCCViewer_ViewPort3d( this, myModel->getViewer3d(), V3d_ORTHOGRAPHIC ); myViewPort->setBackgroundColor(black); myViewPort->installEventFilter(this); - setCentralWidget(myViewPort); + setCentralWidget(myViewPort); myOperation = NOTHING; + myCurrPointType = GRAVITY; + myPrevPointType = GRAVITY; + mySelectedPoint = gp_Pnt(0.,0.,0.); + myRotationPointSelection = false; + setTransformRequested ( NOTHING ); setTransformInProcess ( false ); @@ -305,7 +325,7 @@ void OCCViewer_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent) case ROTATE: if ( theEvent->button() == Qt::LeftButton ) { - myViewPort->startRotation(myStartX, myStartY); + myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); emit vpTransformationStarted ( ROTATE ); } break; @@ -321,10 +341,40 @@ void OCCViewer_ViewWindow::vpMousePressEvent(QMouseEvent* theEvent) break; case ROTATE: activateRotation(); - myViewPort->startRotation(myStartX, myStartY); + myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); break; default: - emit mousePressed(this, theEvent); + if ( myRotationPointSelection ) + { + if ( theEvent->button() == Qt::LeftButton ) + { + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + ic->Select(); + for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() ) + { + TopoDS_Shape aShape = ic->SelectedShape(); + if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX ) + { + gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) ); + if ( mySetRotationPointDlg ) mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z()); + } + else + { + myCurrPointType = myPrevPointType; + break; + } + } + if ( ic->NbSelected() == 0 ) myCurrPointType = myPrevPointType; + if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange(); + ic->CloseAllContexts(); + myOperation = NOTHING; + setCursor( myCursor ); + myCursorIsHand = false; + myRotationPointSelection = false; + } + } + else + emit mousePressed(this, theEvent); break; } /* notify that we start a transformation */ @@ -384,6 +434,147 @@ void OCCViewer_ViewWindow::activateRotation() } } +/*! + Compute the gravity center +*/ +bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, double& theZ ) +{ + Handle(Visual3d_View) aView = myViewPort->getView()->View(); + + Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W ; + Standard_Real Umin,Vmin,Umax,Vmax ; + Standard_Integer Nstruct,Npoint ; + Graphic3d_MapOfStructure MySetOfStructures; + + aView->DisplayedStructures (MySetOfStructures); + Nstruct = MySetOfStructures.Extent() ; + + Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ; + aView->ViewMapping().WindowLimit(Umin,Vmin,Umax,Vmax) ; + Npoint = 0 ; theX = theY = theZ = 0. ; + for( ; MyIterator.More(); MyIterator.Next()) { + if (!(MyIterator.Key())->IsEmpty()) { + (MyIterator.Key())->MinMaxValues(Xmin,Ymin,Zmin, + Xmax,Ymax,Zmax) ; + + Standard_Real LIM = ShortRealLast() -1.; + if (! (fabs(Xmin) > LIM || fabs(Ymin) > LIM || fabs(Zmin) > LIM + || fabs(Xmax) > LIM || fabs(Ymax) > LIM || fabs(Zmax) > LIM )) { + + aView->Projects(Xmin,Ymin,Zmin,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmin ; + } + aView->Projects(Xmax,Ymin,Zmin,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmin ; + } + aView->Projects(Xmin,Ymax,Zmin,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmin ; + } + aView->Projects(Xmax,Ymax,Zmin,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmin ; + } + aView->Projects(Xmin,Ymin,Zmax,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmax ; + } + aView->Projects(Xmax,Ymin,Zmax,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmax ; + } + aView->Projects(Xmin,Ymax,Zmax,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmax ; + } + aView->Projects(Xmax,Ymax,Zmax,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmax ; + } + } + } + } + if( Npoint > 0 ) { + theX /= Npoint ; theY /= Npoint ; theZ /= Npoint ; + } + return true; +} + +/*! + Set the gravity center as a rotation point +*/ +void OCCViewer_ViewWindow::activateSetRotationGravity() +{ + myPrevPointType = myCurrPointType; + myCurrPointType = GRAVITY; + + Standard_Real Xcenter, Ycenter, Zcenter; + if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) ) + mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter ); +} + +/*! + Update gravity center in the SetRotationPointDlg +*/ +void OCCViewer_ViewWindow::updateGravityCoords() +{ + if ( mySetRotationPointDlg && mySetRotationPointDlg->isShown() && myCurrPointType == GRAVITY ) + { + Standard_Real Xcenter, Ycenter, Zcenter; + if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) ) + mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter ); + } +} + +/*! + Set the point selected by user as a rotation point +*/ +void OCCViewer_ViewWindow::activateSetRotationSelected(double theX, double theY, double theZ) +{ + myPrevPointType = myCurrPointType; + myCurrPointType = SELECTED; + mySelectedPoint.SetCoord(theX,theY,theZ); +} + +/*! + Start the point selection process +*/ +void OCCViewer_ViewWindow::activateStartPointSelection() +{ + myPrevPointType = myCurrPointType; + myCurrPointType = SELECTED; + + // activate selection ------> + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + + ic->OpenLocalContext(); + + AIS_ListOfInteractive aList; + ic->DisplayedObjects( aList ); + for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) + { + Handle(AIS_InteractiveObject) anObj = it.Value(); + if ( !anObj.IsNull() && anObj->HasPresentation() && + anObj->IsKind( STANDARD_TYPE(AIS_Shape) ) ) + { + ic->Load(anObj,-1); + ic->Activate(anObj,AIS_Shape::SelectionMode(TopAbs_VERTEX)); + } + } + // activate selection <------ + + if ( !myCursorIsHand ) + { + QCursor handCursor (Qt::PointingHandCursor); + myCursorIsHand = true; + myCursor = cursor(); + setCursor( handCursor ); + } + myRotationPointSelection = true; +} + /*! Starts global panning operation, sets corresponding cursor */ @@ -424,7 +615,7 @@ void OCCViewer_ViewWindow::activateWindowFit() void OCCViewer_ViewWindow::setTransformRequested ( OperationType op ) { myOperation = op; - myViewPort->setMouseTracking( myOperation == NOTHING ); + myViewPort->setMouseTracking( myOperation == NOTHING ); } @@ -437,7 +628,7 @@ void OCCViewer_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent) myCurrY = theEvent->y(); switch (myOperation) { case ROTATE: - myViewPort->rotate(myCurrX, myCurrY); + myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint); break; case ZOOMVIEW: @@ -461,24 +652,29 @@ void OCCViewer_ViewWindow::vpMouseMoveEvent(QMouseEvent* theEvent) break; default: - int aState = theEvent->state(); - //int aButton = theEvent->button(); - if ( aState == Qt::LeftButton || - aState == ( Qt::LeftButton | Qt::ShiftButton) ) { - myDrawRect = myEnableDrawMode; - if ( myDrawRect ) { - drawRect(); - if ( !myCursorIsHand ) { // we are going to sketch a rectangle - QCursor handCursor (Qt::PointingHandCursor); - myCursorIsHand = true; - myCursor = cursor(); - setCursor( handCursor ); - } - } - } - else { + if ( myRotationPointSelection ) emit mouseMoving( this, theEvent ); - } + else + { + int aState = theEvent->state(); + //int aButton = theEvent->button(); + if ( aState == Qt::LeftButton || + aState == ( Qt::LeftButton | Qt::ShiftButton) ) { + myDrawRect = myEnableDrawMode; + if ( myDrawRect ) { + drawRect(); + if ( !myCursorIsHand ) { // we are going to sketch a rectangle + QCursor handCursor (Qt::PointingHandCursor); + myCursorIsHand = true; + myCursor = cursor(); + setCursor( handCursor ); + } + } + } + else { + emit mouseMoving( this, theEvent ); + } + } } } @@ -552,9 +748,17 @@ void OCCViewer_ViewWindow::resetState() myRect.setLeft(2); myRect.setRight(0); - if ( transformRequested() || myCursorIsHand ) - setCursor( myCursor ); - myCursorIsHand = false; + if ( myRotationPointSelection ) + { + QCursor handCursor (Qt::PointingHandCursor); + setCursor( handCursor ); + } + else + { + if ( transformRequested() || myCursorIsHand ) + setCursor( myCursor ); + myCursorIsHand = false; + } if ( transformRequested() ) emit vpTransformationFinished (myOperation); @@ -630,7 +834,15 @@ void OCCViewer_ViewWindow::createActions() tr( "MNU_GLOBALPAN_VIEW" ), 0, this); aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW")); connect(aAction, SIGNAL(activated()), this, SLOT(activateGlobalPanning())); - myActionsMap[ GlobalPanId ] = aAction; + myActionsMap[ GlobalPanId ] = aAction; + + // Rotation Point + mySetRotationPointAction = new QtxAction(tr("MNU_CHANGINGROTATIONPOINT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATION_POINT" ) ), + tr( "MNU_CHANGINGROTATIONPOINT_VIEW" ), 0, this); + mySetRotationPointAction->setStatusTip(tr("DSC_CHANGINGROTATIONPOINT_VIEW")); + mySetRotationPointAction->setToggleAction( true ); + connect(mySetRotationPointAction, SIGNAL(toggled( bool )), this, SLOT(onSetRotationPoint( bool ))); + myActionsMap[ ChangeRotationPointId ] = mySetRotationPointAction; // Rotation aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATE" ) ), @@ -695,7 +907,7 @@ void OCCViewer_ViewWindow::createActions() myClippingAction->setStatusTip(tr("DSC_CLIPPING")); myClippingAction->setToggleAction( true ); connect(myClippingAction, SIGNAL(toggled( bool )), this, SLOT(onClipping( bool ))); - myActionsMap[ ClippingId ] = myClippingAction; + myActionsMap[ ClippingId ] = myClippingAction; aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ), tr( "MNU_SHOOT_VIEW" ), 0, this); @@ -736,6 +948,8 @@ void OCCViewer_ViewWindow::createToolBar() aPanningBtn->AddAction(myActionsMap[PanId]); aPanningBtn->AddAction(myActionsMap[GlobalPanId]); + myActionsMap[ChangeRotationPointId]->addTo(myToolBar); + myActionsMap[RotationId]->addTo(myToolBar); SUIT_ToolButton* aViewsBtn = new SUIT_ToolButton(myToolBar, "projection"); @@ -855,6 +1069,39 @@ void OCCViewer_ViewWindow::onFitAll() myViewPort->fitAll(); } +/*! + SLOT: called if change rotation point operation is activated +*/ +void OCCViewer_ViewWindow::onSetRotationPoint( bool on ) +{ + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + + if ( on ) + { + if ( !mySetRotationPointDlg ) + { + mySetRotationPointDlg = new OCCViewer_SetRotationPointDlg( this, myDesktop ); + mySetRotationPointDlg->SetAction( mySetRotationPointAction ); + } + + if ( !mySetRotationPointDlg->isShown() ) + { + if ( mySetRotationPointDlg->IsFirstShown() ) + { + Standard_Real Xcenter, Ycenter, Zcenter; + if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) ) + mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter ); + } + mySetRotationPointDlg->show(); + } + } + else + { + if ( mySetRotationPointDlg->isShown() ) + mySetRotationPointDlg->hide(); + } +} + /*! Creates one more window with same content */ @@ -1088,3 +1335,20 @@ void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters ) performRestoring( params ); } } + +/*! + Custom show event handler +*/ +void OCCViewer_ViewWindow::showEvent( QShowEvent * theEvent ) +{ + emit Show( theEvent ); +} + +/*! + Custom hide event handler +*/ +void OCCViewer_ViewWindow::hideEvent( QHideEvent * theEvent ) +{ + emit Hide( theEvent ); +} + diff --git a/src/OCCViewer/OCCViewer_ViewWindow.h b/src/OCCViewer/OCCViewer_ViewWindow.h index d9dafcffe..f73368da5 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.h +++ b/src/OCCViewer/OCCViewer_ViewWindow.h @@ -32,6 +32,7 @@ class SUIT_Desktop; class OCCViewer_ViewPort3d; class OCCViewer_ClippingDlg; +class OCCViewer_SetRotationPointDlg; #ifdef WIN32 #pragma warning( disable:4251 ) @@ -42,9 +43,12 @@ class OCCVIEWER_EXPORT OCCViewer_ViewWindow : public SUIT_ViewWindow Q_OBJECT public: - enum OperationType{ NOTHING, PANVIEW, ZOOMVIEW, ROTATE, PANGLOBAL, WINDOWFIT, FITALLVIEW, RESETVIEW, + enum OperationType{ NOTHING, PANVIEW, ZOOMVIEW, ROTATE, + PANGLOBAL, WINDOWFIT, FITALLVIEW, RESETVIEW, FRONTVIEW, BACKVIEW, TOPVIEW, BOTTOMVIEW, LEFTVIEW, RIGHTVIEW }; + enum RotationPointType{ GRAVITY, SELECTED }; + OCCViewer_ViewWindow(SUIT_Desktop* theDesktop, OCCViewer_Viewer* theModel); virtual ~OCCViewer_ViewWindow() {}; @@ -67,8 +71,8 @@ public: virtual QString getVisualParameters(); virtual void setVisualParameters( const QString& parameters ); - -public slots: + + public slots: void onFrontView(); void onViewFitAll(); void onBackView(); @@ -83,20 +87,33 @@ public slots: void activateRotation(); void activatePanning(); void activateGlobalPanning(); + void onSetRotationPoint( bool on ); void onCloneView(); void onClipping( bool on ); void onMemorizeView(); void onRestoreView(); void onTrihedronShow(); void setRestoreFlag(); - + + void activateSetRotationGravity(); + void activateSetRotationSelected( double theX, double theY, double theZ ); + void activateStartPointSelection(); + void updateGravityCoords(); + + virtual void showEvent( QShowEvent * ); + virtual void hideEvent( QHideEvent * ); + signals: void vpTransformationStarted(OCCViewer_ViewWindow::OperationType type); void vpTransformationFinished(OCCViewer_ViewWindow::OperationType type); void cloneView(); + void Show( QShowEvent * ); + void Hide( QHideEvent * ); + protected: - enum { DumpId, FitAllId, FitRectId, ZoomId, PanId, GlobalPanId, RotationId, + enum { DumpId, FitAllId, FitRectId, ZoomId, PanId, GlobalPanId, + ChangeRotationPointId, RotationId, FrontId, BackId, TopId, BottomId, LeftId, RightId, ResetId, CloneId, ClippingId, MemId, RestoreId, TrihedronShowId }; @@ -126,10 +143,17 @@ protected: viewAspect getViewParams() const; + bool computeGravityCenter( double& theX, double& theY, double& theZ ); + OperationType myOperation; OCCViewer_Viewer* myModel; OCCViewer_ViewPort3d* myViewPort; + RotationPointType myCurrPointType; + RotationPointType myPrevPointType; + gp_Pnt mySelectedPoint; + bool myRotationPointSelection; + int myRestoreFlag; int myStartX; @@ -154,6 +178,9 @@ protected: private: OCCViewer_ClippingDlg* myClippingDlg; QtxAction* myClippingAction; + + OCCViewer_SetRotationPointDlg* mySetRotationPointDlg; + QtxAction* mySetRotationPointAction; }; diff --git a/src/OCCViewer/resources/OCCViewer_images.po b/src/OCCViewer/resources/OCCViewer_images.po index b75530310..4ab78a38d 100755 --- a/src/OCCViewer/resources/OCCViewer_images.po +++ b/src/OCCViewer/resources/OCCViewer_images.po @@ -62,6 +62,9 @@ msgstr "view_reset.png" msgid "ICON_OCCVIEWER_VIEW_RIGHT" msgstr "view_right.png" +msgid "ICON_OCCVIEWER_VIEW_ROTATION_POINT" +msgstr "view_rotation_point.png" + msgid "ICON_OCCVIEWER_VIEW_ROTATE" msgstr "view_rotate.png" diff --git a/src/OCCViewer/resources/OCCViewer_msg_en.po b/src/OCCViewer/resources/OCCViewer_msg_en.po index 08af365ae..5623b366e 100755 --- a/src/OCCViewer/resources/OCCViewer_msg_en.po +++ b/src/OCCViewer/resources/OCCViewer_msg_en.po @@ -107,9 +107,45 @@ msgstr "Selection of a new center of the view" msgid "MNU_GLOBALPAN_VIEW" msgstr "Global Panning" +msgid "DSC_CHANGINGROTATIONPOINT_VIEW" +msgstr "Change the point, around which the rotation is performed" + msgid "DSC_ROTATE_VIEW" msgstr "Rotation of the point of view around the scene center" +msgid "OCCViewer_SetRotationPointDlg::CAPTION" +msgstr "Set Rotation Point" + +msgid "OCCViewer_SetRotationPointDlg::USE_BBCENTER" +msgstr "Use Bounding Box Center" + +msgid "OCCViewer_SetRotationPointDlg::LBL_TOORIGIN" +msgstr "Set to Origin" + +msgid "OCCViewer_SetRotationPointDlg::LBL_SELECTPOINT" +msgstr "Select Point from View" + +msgid "OCCViewer_SetRotationPointDlg::LBL_X" +msgstr "X :" + +msgid "OCCViewer_SetRotationPointDlg::LBL_Y" +msgstr "Y :" + +msgid "OCCViewer_SetRotationPointDlg::LBL_Z" +msgstr "Z :" + +msgid "MNU_CHANGINGROTATIONPOINT_VIEW" +msgstr "Change Rotation Point" + +msgid "MNU_ROTATIONPOINTGRAVITY_VIEW" +msgstr "Rotation Point : the gravity center" + +msgid "MNU_ROTATIONPOINT000_VIEW" +msgstr "Rotation Point : (0,0,0)" + +msgid "MNU_ROTATIONPOINTSELECTED_VIEW" +msgstr "Rotation Point : the point selected by the user" + msgid "MNU_ROTATE_VIEW" msgstr "Rotation" diff --git a/src/OCCViewer/resources/view_rotation_point.png b/src/OCCViewer/resources/view_rotation_point.png new file mode 100755 index 0000000000000000000000000000000000000000..59f59311bc5105d7ba1246598d169259af3bf8c7 GIT binary patch literal 988 zcmbVKZAep57=F(--Q6wI&SXetxo|ZRBqeFhA35F3k<+2(Y*-m&SgGiowxAzl4az@d z31U$pG(tk82#lm)B#D%TP=@%YT^g2w5qS4uAKc!1r=wr}=x{#X^Soc@dEe7-uQ`;) zZesx;&01xy!!uJ{j2!n#$I3xGR9#g^djK}6#YN!O?JNK}*sB{Xs1yY7dc8wKLxLc9 z&J6&hBM3m&(r4&uH6euZS@E4m;yOJVP+spCWH1hnEU3bXmN;GI2JmkFrgRFzFS^Q$ zUeSxq+IB~tSMnNhZFh>s3gXH%(dgI;+eRaSicwiYu%xciNEi{kf-GMO50qb^{4>k` z+~pDjrr;dUX+(o6#1X8#yGxRTpYF|JUW^=BE24Y|$f<<8+6go|!x=1n8iI~iB|Jsrn}fiwdk zol(xF@9Ou2#jC%}!_e6K;S@c{=tg`3gd#{Ip*H@-fD-aZjqCiKVf9T=z8ov%k_MzKZmW|1GBItRTxL^w>liGxU5ZNybM(LQ0bevSBqo z8V8rQNV30z4aK5y4^RMP0bo#1%q5D0?Lfimx6v4uLV*SnUol~FEHZ;;yrj76YU=T$ z3h;AcOFaVJRfitAll(); break; case SUIT_Accel::RotateLeft : - myViewPort->startRotation( cx, cy ); - myViewPort->rotate( cx - inc, cy ); + myViewPort->startRotation( cx, cy, myCurrPointType, mySelectedPoint ); + myViewPort->rotate( cx - inc, cy, myCurrPointType, mySelectedPoint ); myViewPort->endRotation(); break; case SUIT_Accel::RotateRight : - myViewPort->startRotation( cx, cy ); - myViewPort->rotate( cx + inc, cy ); + myViewPort->startRotation( cx, cy, myCurrPointType, mySelectedPoint ); + myViewPort->rotate( cx + inc, cy, myCurrPointType, mySelectedPoint ); myViewPort->endRotation(); break; case SUIT_Accel::RotateUp : - myViewPort->startRotation( cx, cy ); - myViewPort->rotate( cx, cy - inc ); + myViewPort->startRotation( cx, cy, myCurrPointType, mySelectedPoint ); + myViewPort->rotate( cx, cy - inc, myCurrPointType, mySelectedPoint ); myViewPort->endRotation(); break; case SUIT_Accel::RotateDown : - myViewPort->startRotation( cx, cy ); - myViewPort->rotate( cx, cy + inc ); + myViewPort->startRotation( cx, cy, myCurrPointType, mySelectedPoint ); + myViewPort->rotate( cx, cy + inc, myCurrPointType, mySelectedPoint ); myViewPort->endRotation(); break; } diff --git a/src/SVTK/Makefile.in b/src/SVTK/Makefile.in index f45b583aa..4188e1cb8 100755 --- a/src/SVTK/Makefile.in +++ b/src/SVTK/Makefile.in @@ -74,6 +74,7 @@ LIB_SRC= \ SVTK_NonIsometricDlg.cxx \ SVTK_UpdateRateDlg.cxx \ SVTK_CubeAxesDlg.cxx \ + SVTK_SetRotationPointDlg.cxx \ SVTK_DialogBase.cxx \ SVTK_FontWidget.cxx \ SVTK_Trihedron.cxx \ @@ -95,6 +96,7 @@ LIB_MOC = \ SVTK_NonIsometricDlg.h \ SVTK_UpdateRateDlg.h \ SVTK_CubeAxesDlg.h \ + SVTK_SetRotationPointDlg.h \ SVTK_FontWidget.h \ SVTK_DialogBase.h \ SVTK_ViewModelBase.h \ diff --git a/src/SVTK/SVTK_Event.h b/src/SVTK/SVTK_Event.h index fa415ab83..00a9e2c0f 100644 --- a/src/SVTK/SVTK_Event.h +++ b/src/SVTK/SVTK_Event.h @@ -61,6 +61,14 @@ namespace SVTK StartGlobalPan, StartFitArea, + SetRotateGravity, + StartPointSelection, + SetRotateSelected, + + BBCenterChanged, + RotationPointChanged, + ChangeRotationPoint, + LastEvent }; } diff --git a/src/SVTK/SVTK_InteractorStyle.cxx b/src/SVTK/SVTK_InteractorStyle.cxx index 4f8dfaa60..9959ea2ff 100644 --- a/src/SVTK/SVTK_InteractorStyle.cxx +++ b/src/SVTK/SVTK_InteractorStyle.cxx @@ -36,6 +36,7 @@ #include "SVTK_Event.h" #include "SVTK_Selector.h" #include "SVTK_Functor.h" +#include "SVTK_Actor.h" #include "VTKViewer_Algorithm.h" #include "SVTK_Functor.h" @@ -48,10 +49,14 @@ #include #include #include +#include #include #include #include #include +#include +#include +#include #include #include @@ -62,6 +67,8 @@ //VRV: porting on Qt 3.0.5 #include +#include + using namespace std; namespace @@ -100,6 +107,7 @@ namespace vtkStandardNewMacro(SVTK_InteractorStyle); + /*! Constructor */ @@ -107,12 +115,17 @@ SVTK_InteractorStyle ::SVTK_InteractorStyle(): mySelectionEvent(new SVTK_SelectionEvent()), myPicker(vtkPicker::New()), + myPointPicker(vtkPointPicker::New()), myLastHighlitedActor(NULL), myLastPreHighlitedActor(NULL), myControllerIncrement(SVTK_ControllerIncrement::New()), - myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()) + myControllerOnKeyDown(SVTK_ControllerOnKeyDown::New()), + myHighlightRotationPointActor(SVTK_Actor::New()) { myPicker->Delete(); + myPointPicker->Delete(); + + myPointPicker->SetTolerance(0.025); this->MotionFactor = 10.0; this->State = VTK_INTERACTOR_STYLE_CAMERA_NONE; @@ -131,6 +144,20 @@ SVTK_InteractorStyle // myControllerIncrement->Delete(); myControllerOnKeyDown->Delete(); + + myCurrRotationPointType = SVTK::SetRotateGravity; + myPrevRotationPointType = myCurrRotationPointType; + + myHighlightRotationPointActor->Delete(); + myHighlightRotationPointActor->Initialize(); + myHighlightRotationPointActor->PickableOff(); + myHighlightRotationPointActor->SetVisibility( false ); + + myHighlightRotationPointActor->GetProperty()->SetPointSize(SALOME_POINT_SIZE+2); + myHighlightRotationPointActor->GetProperty()->SetLineWidth(SALOME_LINE_WIDTH+2); + myHighlightRotationPointActor->GetProperty()->SetRepresentationToPoints(); + + myBBFirstCheck = true; } /*! @@ -205,7 +232,7 @@ void SVTK_InteractorStyle ::RotateXY(int dx, int dy) { - if(GetCurrentRenderer() == NULL) + /* if(GetCurrentRenderer() == NULL) return; int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize(); @@ -222,6 +249,58 @@ SVTK_InteractorStyle GetCurrentRenderer()->ResetCameraClippingRange(); + this->Render();*/ + + if(GetCurrentRenderer() == NULL) + return; + + vtkCamera *cam = GetCurrentRenderer()->GetActiveCamera(); + + double viewFP[3], viewPos[3]; + cam->GetFocalPoint(viewFP); + cam->GetPosition(viewPos); + + if ( myCurrRotationPointType == SVTK::SetRotateGravity ) + { + vtkFloatingPointType aCenter[3]; + if ( ComputeBBCenter(GetCurrentRenderer(),aCenter) ) + { + myRotationPointX = aCenter[0]; + myRotationPointY = aCenter[1]; + myRotationPointZ = aCenter[2]; + } + } + + // Calculate corresponding transformation + vtkPerspectiveTransform* aTransform = vtkPerspectiveTransform::New(); + aTransform->Identity(); + aTransform->Translate(+myRotationPointX, +myRotationPointY, +myRotationPointZ); + + // Azimuth transformation + int *size = GetCurrentRenderer()->GetRenderWindow()->GetSize(); + double aDeltaAzimuth = -20.0 / size[0]; + + double rxf = double(dx) * aDeltaAzimuth * this->MotionFactor; + aTransform->RotateWXYZ(rxf, cam->GetViewUp()); + + // Elevation transformation + double aDeltaElevation = -20.0 / size[1]; + + double ryf = double(dy) * aDeltaElevation * this->MotionFactor; + vtkMatrix4x4* aMatrix = cam->GetViewTransformMatrix(); + const double anAxis[3] = {aMatrix->GetElement(0,0), aMatrix->GetElement(0,1), aMatrix->GetElement(0,2)}; + aTransform->RotateWXYZ(ryf, anAxis); + + aTransform->Translate(-myRotationPointX, -myRotationPointY, -myRotationPointZ); + + // To apply the transformation + cam->SetPosition(aTransform->TransformPoint(viewPos)); + cam->SetFocalPoint(aTransform->TransformPoint(viewFP)); + + cam->OrthogonalizeViewUp(); + + GetCurrentRenderer()->ResetCameraClippingRange(); + this->Render(); } @@ -431,9 +510,54 @@ SVTK_InteractorStyle } else { if (ctrl) startOperation(VTK_INTERACTOR_STYLE_CAMERA_ZOOM); + else if ( myCurrRotationPointType == SVTK::StartPointSelection ) + { + SVTK_SelectionEvent* aSelectionEvent = GetSelectionEventFlipY(); + myPicker->Pick(aSelectionEvent->myX, + aSelectionEvent->myY, + 0.0, + GetCurrentRenderer()); + if ( SALOME_Actor* anActor = GetFirstSALOMEActor(myPicker.GetPointer()) ) + { + myPointPicker->Pick( aSelectionEvent->myX, + aSelectionEvent->myY, + 0.0, + GetCurrentRenderer() ); + int aVtkId = myPointPicker->GetPointId(); + if ( aVtkId >= 0 ) + { + int anObjId = anActor->GetNodeObjId( aVtkId ); + vtkFloatingPointType* aCoords = anActor->GetNodeCoord(anObjId); + + myCurrRotationPointType = SVTK::SetRotateSelected; + + // invoke event for update coordinates in SVTK_SetRotationPointDlg + InvokeEvent(SVTK::RotationPointChanged,(void*)aCoords); + + myHighlightRotationPointActor->SetVisibility( false ); + if(GetCurrentRenderer() != NULL) + GetCurrentRenderer()->RemoveActor( myHighlightRotationPointActor.GetPointer() ); + } + else + { + // invoke event with no data (for SVTK_SetRotationPointDlg) + InvokeEvent(SVTK::RotationPointChanged,0); + myCurrRotationPointType = myPrevRotationPointType; + } + } + else + { + // invoke event with no data (for SVTK_SetRotationPointDlg) + InvokeEvent(SVTK::RotationPointChanged,0); + myCurrRotationPointType = myPrevRotationPointType; + } + + GetRenderWidget()->setCursor(myDefCursor); + } else startOperation(VTK_INTERACTOR_STYLE_CAMERA_SELECT); } + return; } @@ -696,6 +820,26 @@ SVTK_InteractorStyle ForcedState = VTK_INTERACTOR_STYLE_CAMERA_ROTATE; } +/*! + Set rotation point selected by user +*/ +void +SVTK_InteractorStyle +::startPointSelection() +{ + myCurrRotationPointType = SVTK::StartPointSelection; + + if(GetCurrentRenderer() != NULL) { + GetCurrentRenderer()->AddActor( myHighlightRotationPointActor.GetPointer() ); + vtkFloatingPointType aColor[3]; + GetCurrentRenderer()->GetBackground( aColor ); + myHighlightRotationPointActor->GetProperty()->SetColor(1. - aColor[0], + 1. - aColor[1], + 1. - aColor[2]); + } + + setCursor(VTK_INTERACTOR_STYLE_CAMERA_NONE); +} /*! Starts Spin operation (e.g. through menu command) @@ -863,7 +1007,10 @@ SVTK_InteractorStyle break; case VTK_INTERACTOR_STYLE_CAMERA_NONE: default: - GetRenderWidget()->setCursor(myDefCursor); + if ( myCurrRotationPointType == SVTK::StartPointSelection ) + GetRenderWidget()->setCursor(myHandCursor); + else + GetRenderWidget()->setCursor(myDefCursor); myCursorState = false; break; } @@ -961,8 +1108,9 @@ SVTK_InteractorStyle if(anActor){ anActor->Highlight( this, aSelectionEvent, true ); }else{ - if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != anActor) + if(myLastHighlitedActor.GetPointer() && myLastHighlitedActor.GetPointer() != anActor) { myLastHighlitedActor->Highlight( this, aSelectionEvent, false ); + } } myLastHighlitedActor = anActor; } @@ -1089,13 +1237,43 @@ SVTK_InteractorStyle GetCurrentRenderer()); SALOME_Actor *anActor = GetFirstSALOMEActor(myPicker.GetPointer()); - if (anActor){ - anIsChanged |= anActor->PreHighlight( this, aSelectionEvent, true ); + + if ( myCurrRotationPointType == SVTK::StartPointSelection ) + { + myHighlightRotationPointActor->SetVisibility( false ); + + SALOME_Actor *anCurrActor; + if ( anActor ) anCurrActor = anActor; + else if ( myLastPreHighlitedActor.GetPointer() + && + myLastPreHighlitedActor.GetPointer() != anActor ) + anCurrActor = myLastPreHighlitedActor.GetPointer(); + if ( anCurrActor ) + { + myPointPicker->Pick( aSelectionEvent->myX, aSelectionEvent->myY, 0.0, GetCurrentRenderer() ); + int aVtkId = myPointPicker->GetPointId(); + if ( aVtkId >= 0 ) { + int anObjId = anActor->GetNodeObjId( aVtkId ); + + TColStd_IndexedMapOfInteger aMapIndex; + aMapIndex.Add( anObjId ); + myHighlightRotationPointActor->MapPoints( anActor, aMapIndex ); + + myHighlightRotationPointActor->SetVisibility( true ); + anIsChanged = true; + } + } } + else { + if (anActor){ + anIsChanged |= anActor->PreHighlight( this, aSelectionEvent, true ); + } - if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != anActor) - anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false ); + if(myLastPreHighlitedActor.GetPointer() && myLastPreHighlitedActor.GetPointer() != anActor) + anIsChanged |= myLastPreHighlitedActor->PreHighlight( this, aSelectionEvent, false ); + } + myLastPreHighlitedActor = anActor; if(anIsChanged) @@ -1225,6 +1403,11 @@ SVTK_InteractorStyle theInteractor->AddObserver( SVTK::StartRotate, EventCallbackCommand, Priority ); theInteractor->AddObserver( SVTK::StartGlobalPan, EventCallbackCommand, Priority ); theInteractor->AddObserver( SVTK::StartFitArea, EventCallbackCommand, Priority ); + + theInteractor->AddObserver( SVTK::SetRotateGravity, EventCallbackCommand, Priority ); + theInteractor->AddObserver( SVTK::StartPointSelection, EventCallbackCommand, Priority ); + + theInteractor->AddObserver( SVTK::ChangeRotationPoint, EventCallbackCommand, Priority ); } } @@ -1237,6 +1420,30 @@ SVTK_InteractorStyle { //vtkInteractorStyle::OnTimer(); this->Interactor->Render(); + // check if bounding box was changed + if ( GetCurrentRenderer() ) + { + vtkFloatingPointType aCurrBBCenter[3]; + if ( ComputeBBCenter(GetCurrentRenderer(),aCurrBBCenter) ) + { + if ( !myBBFirstCheck ) + { + if ( fabs(aCurrBBCenter[0]-myBBCenter[0]) > 1e-38 || + fabs(aCurrBBCenter[1]-myBBCenter[1]) > 1e-38 || + fabs(aCurrBBCenter[2]-myBBCenter[2]) > 1e-38 ) { + // bounding box was changed => send SVTK::RotationPointChanged event + // invoke event for update coordinates in SVTK_SetRotationPointDlg + InvokeEvent(SVTK::BBCenterChanged,(void*)aCurrBBCenter); + for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i]; + } + } + else + { + for ( int i =0; i < 3; i++) myBBCenter[i] = aCurrBBCenter[i]; + myBBFirstCheck = false; + } + } + } } /*! @@ -1299,6 +1506,8 @@ SVTK_InteractorStyle vtkObject* anObject = reinterpret_cast( clientData ); SVTK_InteractorStyle* self = dynamic_cast( anObject ); int aSpeedIncrement=self->ControllerIncrement()->Current(); + vtkFloatingPointType aCenter[3]; + vtkFloatingPointType* aSelectedPoint; if ( self ) { switch ( event ) { case SVTK::SpaceMouseMoveEvent : @@ -1372,6 +1581,26 @@ SVTK_InteractorStyle case SVTK::StartFitArea: self->startFitArea(); return; + + case SVTK::SetRotateGravity: + self->myPrevRotationPointType = self->myCurrRotationPointType; + self->myCurrRotationPointType = SVTK::SetRotateGravity; + if ( ComputeBBCenter(self->GetCurrentRenderer(),aCenter) ) + // invoke event for update coordinates in SVTK_SetRotationPointDlg + self->InvokeEvent(SVTK::BBCenterChanged,(void*)aCenter); + return; + case SVTK::StartPointSelection: + self->startPointSelection(); + return; + + case SVTK::ChangeRotationPoint: + self->myPrevRotationPointType = self->myCurrRotationPointType; + self->myCurrRotationPointType = SVTK::SetRotateSelected; + aSelectedPoint = (vtkFloatingPointType*)callData; + self->myRotationPointX = aSelectedPoint[0]; + self->myRotationPointY = aSelectedPoint[1]; + self->myRotationPointZ = aSelectedPoint[2]; + return; } } } diff --git a/src/SVTK/SVTK_InteractorStyle.h b/src/SVTK/SVTK_InteractorStyle.h index 064b6a2de..e03f1ca73 100644 --- a/src/SVTK/SVTK_InteractorStyle.h +++ b/src/SVTK/SVTK_InteractorStyle.h @@ -100,11 +100,13 @@ class SVTK_ControllerOnKeyDown : public vtkObject{ class vtkCell; class vtkPicker; +class vtkPointPicker; class SALOME_Actor; class SVTK_Selector; class SVTK_GenericRenderWindowInteractor; +class SVTK_Actor; #define VTK_INTERACTOR_STYLE_CAMERA_NONE 0 #define VTK_INTERACTOR_STYLE_CAMERA_ROTATE 1 @@ -114,6 +116,7 @@ class SVTK_GenericRenderWindowInteractor; #define VTK_INTERACTOR_STYLE_CAMERA_FIT 5 #define VTK_INTERACTOR_STYLE_CAMERA_SELECT 6 #define VTK_INTERACTOR_STYLE_CAMERA_GLOBAL_PAN 7 +#define VTK_INTERACTOR_STYLE_CAMERA_SELECT_ROTATION_POINT 8 //! Introduce SALOME way of user interaction /*! @@ -220,7 +223,7 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle SVTK_Selector* GetSelector(); - protected: + protected: SVTK_InteractorStyle(); ~SVTK_InteractorStyle(); @@ -273,6 +276,8 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle void startFitArea(); void startSpin(); + void startPointSelection(); + protected: void loadCursors(); void startOperation(int operation); @@ -320,6 +325,19 @@ class SVTK_EXPORT SVTK_InteractorStyle: public vtkInteractorStyle PSelectionEvent mySelectionEvent; vtkSmartPointer myPicker; + + unsigned long myCurrRotationPointType; + unsigned long myPrevRotationPointType; + + double myRotationPointX; + double myRotationPointY; + double myRotationPointZ; + + vtkSmartPointer myHighlightRotationPointActor; + vtkSmartPointer myPointPicker; + + vtkFloatingPointType myBBCenter[3]; + bool myBBFirstCheck; }; #endif diff --git a/src/SVTK/SVTK_MainWindow.cxx b/src/SVTK/SVTK_MainWindow.cxx index 8493b1721..045a05453 100644 --- a/src/SVTK/SVTK_MainWindow.cxx +++ b/src/SVTK/SVTK_MainWindow.cxx @@ -42,11 +42,13 @@ #include "SVTK_NonIsometricDlg.h" #include "SVTK_UpdateRateDlg.h" #include "SVTK_CubeAxesDlg.h" +#include "SVTK_SetRotationPointDlg.h" #include "SVTK_MainWindow.h" #include "SVTK_Event.h" #include "SVTK_Renderer.h" #include "SVTK_RenderWindowInteractor.h" +#include "SVTK_InteractorStyle.h" #include "SVTK_Selector.h" @@ -91,6 +93,7 @@ SVTK_MainWindow myUpdateRateDlg = new SVTK_UpdateRateDlg(myActionsMap[UpdateRate],this,"SVTK_UpdateRateDlg"); myNonIsometricDlg = new SVTK_NonIsometricDlg(myActionsMap[NonIsometric],this,"SVTK_NonIsometricDlg"); myCubeAxesDlg = new SVTK_CubeAxesDlg(myActionsMap[GraduatedAxes],this,"SVTK_CubeAxesDlg"); + mySetRotationPointDlg = new SVTK_SetRotationPointDlg(myActionsMap[ChangeRotationPointId],this,"SVTK_SetRotationPointDlg"); } /*! @@ -143,6 +146,9 @@ SVTK_MainWindow GetRenderer()->OnAdjustTrihedron(); GetInteractor()->update(); + + if ( (SVTK_InteractorStyle*)GetInteractorStyle() ) + ((SVTK_InteractorStyle*)GetInteractorStyle())->OnTimer(); } /*! @@ -463,6 +469,15 @@ SVTK_MainWindow connect(anAction, SIGNAL(activated()), this, SLOT(activateGlobalPanning())); myActionsMap[ GlobalPanId ] = anAction; + // Change rotation point + anAction = new QtxAction(tr("MNU_CHANGINGROTATIONPOINT_VIEW"), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_ROTATION_POINT" ) ), + tr( "MNU_CHANGINGROTATIONPOINT_VIEW" ), 0, this); + anAction->setStatusTip(tr("DSC_CHANGINGROTATIONPOINT_VIEW")); + anAction->setToggleAction(true); + connect(anAction, SIGNAL(toggled(bool)), this, SLOT(onChangeRotationPoint(bool))); + myActionsMap[ ChangeRotationPointId ] = anAction; + // Rotation anAction = new QtxAction(tr("MNU_ROTATE_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_ROTATE" ) ), @@ -581,6 +596,8 @@ SVTK_MainWindow aPanningBtn->AddAction(myActionsMap[PanId]); aPanningBtn->AddAction(myActionsMap[GlobalPanId]); + myActionsMap[ChangeRotationPointId]->addTo(myToolBar); + myActionsMap[RotationId]->addTo(myToolBar); SUIT_ToolButton* aViewsBtn = new SUIT_ToolButton(myToolBar); @@ -648,6 +665,52 @@ SVTK_MainWindow myEventDispatcher->InvokeEvent(SVTK::StartRotate,0); } +/*! + Change rotation point +*/ +void +SVTK_MainWindow +::onChangeRotationPoint(bool theIsActivate) +{ + if(theIsActivate){ + mySetRotationPointDlg->addObserver(); + if ( mySetRotationPointDlg->IsFirstShown() ) + activateSetRotationGravity(); + mySetRotationPointDlg->show(); + }else + mySetRotationPointDlg->hide(); +} + +/*! + Set the gravity center as a rotation point +*/ +void +SVTK_MainWindow +::activateSetRotationGravity() +{ + myEventDispatcher->InvokeEvent(SVTK::SetRotateGravity,0); +} + +/*! + Set the selected point as a rotation point +*/ +void +SVTK_MainWindow +::activateSetRotationSelected(void* theData) +{ + myEventDispatcher->InvokeEvent(SVTK::ChangeRotationPoint,theData); +} + +/*! + Set the point selected by user as a rotation point +*/ +void +SVTK_MainWindow +::activateStartPointSelection() +{ + myEventDispatcher->InvokeEvent(SVTK::StartPointSelection,0); +} + /*! Starts global panning transformation */ diff --git a/src/SVTK/SVTK_MainWindow.h b/src/SVTK/SVTK_MainWindow.h index 6533ff8cb..1be95b652 100644 --- a/src/SVTK/SVTK_MainWindow.h +++ b/src/SVTK/SVTK_MainWindow.h @@ -46,6 +46,7 @@ class SVTK_NonIsometricDlg; class SVTK_UpdateRateDlg; class SVTK_CubeAxesActor2D; class SVTK_CubeAxesDlg; +class SVTK_SetRotationPointDlg; class VTKViewer_Trihedron; class VTKViewer_Transform; @@ -207,6 +208,12 @@ public: void activatePanning(); void activateGlobalPanning(); + void onChangeRotationPoint(bool theIsActivate); + + void activateSetRotationGravity(); + void activateSetRotationSelected(void* theData); + void activateStartPointSelection(); + void onFrontView(); void onBackView(); void onTopView(); @@ -240,7 +247,8 @@ public: void SetEventDispatcher(vtkObject* theDispatcher); - enum { DumpId, FitAllId, FitRectId, ZoomId, PanId, GlobalPanId, RotationId, + enum { DumpId, FitAllId, FitRectId, ZoomId, PanId, GlobalPanId, + ChangeRotationPointId, RotationId, FrontId, BackId, TopId, BottomId, LeftId, RightId, ResetId, ViewTrihedronId, NonIsometric, GraduatedAxes, UpdateRate}; typedef QMap TActionsMap; @@ -250,6 +258,7 @@ public: SVTK_NonIsometricDlg* myNonIsometricDlg; SVTK_UpdateRateDlg* myUpdateRateDlg; SVTK_CubeAxesDlg* myCubeAxesDlg; + SVTK_SetRotationPointDlg* mySetRotationPointDlg; vtkSmartPointer myEventDispatcher; TActionsMap myActionsMap; diff --git a/src/SVTK/SVTK_SetRotationPointDlg.cxx b/src/SVTK/SVTK_SetRotationPointDlg.cxx new file mode 100755 index 000000000..248e3ecd0 --- /dev/null +++ b/src/SVTK/SVTK_SetRotationPointDlg.cxx @@ -0,0 +1,316 @@ +// SALOME VTKViewer : build VTK viewer into Salome desktop +// +// Copyright (C) 2003 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 +// +// +// +// File : +// Author : +// Module : SALOME +// $Header$ + +#include "SVTK_SetRotationPointDlg.h" +#include "SVTK_MainWindow.h" +#include "SVTK_RenderWindowInteractor.h" +#include "SVTK_Event.h" +#include "SVTK_InteractorStyle.h" + +#include "VTKViewer_Utilities.h" + +#include "QtxAction.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace std; + +/*! + Constructor +*/ +SVTK_SetRotationPointDlg +::SVTK_SetRotationPointDlg(QtxAction* theAction, + SVTK_MainWindow* theParent, + const char* theName): + SVTK_DialogBase(theAction, + theParent, + theName), + myMainWindow(theParent), + myPriority(0.0), + myEventCallbackCommand(vtkCallbackCommand::New()), + myRWInteractor(theParent->GetInteractor()) +{ + setCaption(tr("DLG_TITLE")); + setSizeGripEnabled(TRUE); + + // Create layout for this dialog + QGridLayout* layoutDlg = new QGridLayout (this); + layoutDlg->setSpacing(6); + layoutDlg->setMargin(11); + + // Create check box "Use Bounding Box Center" + QHBox* aCheckBox = new QHBox(this); + + myIsBBCenter = new QCheckBox(tr("USE_BBCENTER"), aCheckBox); + myIsBBCenter->setChecked(true); + connect(myIsBBCenter, SIGNAL(stateChanged(int)), SLOT(onBBCenterChecked())); + + // Create croup button with radio buttons + myGroupSelButton = new QButtonGroup(2,Qt::Vertical,"",this); + myGroupSelButton->setMargin(11); + + // Create "Set to Origin" button + myToOrigin = new QPushButton(myGroupSelButton); + myToOrigin->setText(tr("LBL_TOORIGIN")); + connect(myToOrigin, SIGNAL(clicked()), this, SLOT(onToOrigin())); + + // Create "Select Point from View" button + mySelectPoint = new QPushButton(myGroupSelButton); + mySelectPoint->setText(tr("LBL_SELECTPOINT")); + mySelectPoint->setToggleButton(true); + connect(mySelectPoint, SIGNAL(clicked()), this, SLOT(onSelectPoint())); + + // Create croup box with grid layout + myGroupBoxCoord = new QGroupBox(this, "GroupBox"); + QHBoxLayout* aHBoxLayout = new QHBoxLayout(myGroupBoxCoord); + aHBoxLayout->setMargin(11); + aHBoxLayout->setSpacing(6); + + // "X" coordinate + QLabel* TextLabelX = new QLabel (tr("LBL_X"), myGroupBoxCoord, "TextLabelX"); + TextLabelX->setFixedWidth(15); + myX = new QLineEdit(myGroupBoxCoord); + myX->setValidator(new QDoubleValidator(myX)); + myX->setText(QString::number(0.0)); + connect(myX, SIGNAL(textChanged(const QString&)), this, SLOT(onCoordChanged())); + + // "Y" coordinate + QLabel* TextLabelY = new QLabel (tr("LBL_Y"), myGroupBoxCoord, "TextLabelY"); + TextLabelY->setFixedWidth(15); + myY = new QLineEdit(myGroupBoxCoord); + myY->setValidator(new QDoubleValidator(myY)); + myY->setText(QString::number(0.0)); + connect(myY, SIGNAL(textChanged(const QString&)), this, SLOT(onCoordChanged())); + + // "Z" coordinate + QLabel* TextLabelZ = new QLabel (tr("LBL_Z"), myGroupBoxCoord, "TextLabelZ"); + TextLabelZ->setFixedWidth(15); + myZ = new QLineEdit(myGroupBoxCoord); + myZ->setValidator(new QDoubleValidator(myZ)); + myZ->setText(QString::number(0.0)); + connect(myZ, SIGNAL(textChanged(const QString&)), this, SLOT(onCoordChanged())); + + // Layout widgets in the horizontal group box + aHBoxLayout->addWidget(TextLabelX); + aHBoxLayout->addWidget(myX); + aHBoxLayout->addWidget(TextLabelY); + aHBoxLayout->addWidget(myY); + aHBoxLayout->addWidget(TextLabelZ); + aHBoxLayout->addWidget(myZ); + + // "Close" button + QGroupBox* aGroupBox = new QGroupBox(this); + QHBoxLayout* aHBoxLayout2 = new QHBoxLayout(aGroupBox); + aHBoxLayout2->setMargin(11); + aHBoxLayout2->setSpacing(6); + + QPushButton* m_bClose = new QPushButton(tr("&Close"), aGroupBox, "m_bClose"); + m_bClose->setAutoDefault(TRUE); + m_bClose->setFixedSize(m_bClose->sizeHint()); + connect(m_bClose, SIGNAL(clicked()), this, SLOT(onClickClose())); + + // Layout buttons + aHBoxLayout2->addWidget(m_bClose); + + // Layout top level widgets + layoutDlg->addWidget(aCheckBox,0,0); + layoutDlg->addWidget(myGroupSelButton,1,0); + layoutDlg->addWidget(myGroupBoxCoord,2,0); + layoutDlg->addWidget(aGroupBox,3,0); + + setEnabled(myGroupSelButton,!myIsBBCenter->isChecked()); + setEnabled(myGroupBoxCoord,!myIsBBCenter->isChecked()); + + this->resize(400, this->sizeHint().height()); + + myEventCallbackCommand->Delete(); + myEventCallbackCommand->SetClientData(this); + myEventCallbackCommand->SetCallback(SVTK_SetRotationPointDlg::ProcessEvents); + myIsObserverAdded = false; +} + +/* + * Destroys the object and frees any allocated resources + */ +SVTK_SetRotationPointDlg +::~SVTK_SetRotationPointDlg() +{ + // no need to delete child widgets, Qt does it all for us +} + +void +SVTK_SetRotationPointDlg +::addObserver() +{ + if ( !myIsObserverAdded ) { + vtkInteractorStyle* aIStyle = myRWInteractor->GetInteractorStyle(); + aIStyle->AddObserver(SVTK::BBCenterChanged, myEventCallbackCommand.GetPointer(), myPriority); + aIStyle->AddObserver(SVTK::RotationPointChanged, myEventCallbackCommand.GetPointer(), myPriority); + myIsObserverAdded = true; + } +} + +/*! + Return true if it is the first show for this dialog +*/ +bool +SVTK_SetRotationPointDlg +::IsFirstShown() +{ + return myIsBBCenter->isChecked() && myX->text().toDouble() == 0. + && myY->text().toDouble() == 0. && myZ->text().toDouble() == 0.; +} + +/*! + Processes events +*/ +void +SVTK_SetRotationPointDlg +::ProcessEvents(vtkObject* vtkNotUsed(theObject), + unsigned long theEvent, + void* theClientData, + void* theCallData) +{ + SVTK_SetRotationPointDlg* self = reinterpret_cast(theClientData); + vtkFloatingPointType* aCoord = (vtkFloatingPointType*)theCallData; + + switch ( theEvent ) { + case SVTK::BBCenterChanged: + if ( self->myIsBBCenter->isChecked() + || + IsBBEmpty(self->myMainWindow->getRenderer()) ) + { + if ( aCoord ) + { + self->myX->setText( QString::number(aCoord[0]) ); + self->myY->setText( QString::number(aCoord[1]) ); + self->myZ->setText( QString::number(aCoord[2]) ); + } + } + break; + case SVTK::RotationPointChanged: + if ( aCoord ) + { + self->myX->setText( QString::number(aCoord[0]) ); + self->myY->setText( QString::number(aCoord[1]) ); + self->myZ->setText( QString::number(aCoord[2]) ); + } + if ( !self->myIsBBCenter->isChecked() ) + self->mySelectPoint->toggle(); + } +} + +void +SVTK_SetRotationPointDlg +::setEnabled(QGroupBox* theGrp, const bool theState) +{ + QObjectList aChildren(*theGrp->children()); + QObject* anObj; + for(anObj = aChildren.first(); anObj !=0; anObj = aChildren.next()) + { + if (anObj !=0 && anObj->inherits("QLineEdit")) + ((QLineEdit*)anObj)->setReadOnly(!theState); + if (anObj !=0 && anObj->inherits("QPushButton")) + ((QLineEdit*)anObj)->setEnabled(theState); + } + +} + +void +SVTK_SetRotationPointDlg +::onBBCenterChecked() +{ + setEnabled(myGroupSelButton,!myIsBBCenter->isChecked()); + setEnabled(myGroupBoxCoord,!myIsBBCenter->isChecked()); + + if ( myIsBBCenter->isChecked() ) + { // activate mode : the rotation point is the center of the bounding box + // send the data to the SVTK_InteractorStyle: set the type of the rotation point + // calculate coordinates of the rotation point + myMainWindow->activateSetRotationGravity(); + } + else + { + QString aX = myX->text(); + myX->setText(QString::number(aX.toDouble()+1.)); + myX->setText(aX); + } +} + +void +SVTK_SetRotationPointDlg +::onToOrigin() +{ + myX->setText(QString::number(0.0)); + myY->setText(QString::number(0.0)); + myZ->setText(QString::number(0.0)); +} + +void +SVTK_SetRotationPointDlg +::onSelectPoint() +{ + if ( mySelectPoint->state() == QButton::On ) + myMainWindow->activateStartPointSelection(); + else + mySelectPoint->toggle(); +} + +void +SVTK_SetRotationPointDlg +::onCoordChanged() +{ + if ( !myIsBBCenter->isChecked() ) { + vtkFloatingPointType aCenter[3] = {myX->text().toDouble(), + myY->text().toDouble(), + myZ->text().toDouble()}; + myMainWindow->activateSetRotationSelected((void*)aCenter); + } + else + myMainWindow->activateSetRotationGravity(); +} + +void +SVTK_SetRotationPointDlg +::onClickClose() +{ + reject(); +} + + diff --git a/src/SVTK/SVTK_SetRotationPointDlg.h b/src/SVTK/SVTK_SetRotationPointDlg.h new file mode 100755 index 000000000..37eed0645 --- /dev/null +++ b/src/SVTK/SVTK_SetRotationPointDlg.h @@ -0,0 +1,108 @@ +// SALOME VTKViewer : build VTK viewer into Salome desktop +// +// Copyright (C) 2003 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 +// +// +// +// File : +// Author : +// Module : SALOME +// $Header$ + +#ifndef SVTK_SETROTATIONPOINTDLG_H +#define SVTK_SETROTATIONPOINTDLG_H + +#include "SVTK_DialogBase.h" + +#include + +class SVTK_MainWindow; +class SVTK_RenderWindowInteractor; + +class QtxAction; + +class QLineEdit; +class QPushButton; +class QGroupBox; +class QButtonGroup; +class QCheckBox; + +class vtkCallbackCommand; +class vtkObject; + +class SVTK_SetRotationPointDlg : public SVTK_DialogBase +{ + Q_OBJECT; + +public: + SVTK_SetRotationPointDlg(QtxAction* theAction, + SVTK_MainWindow* theParent, + const char* theName); + + ~SVTK_SetRotationPointDlg(); + + void addObserver(); + bool IsFirstShown(); + +protected: + SVTK_MainWindow *myMainWindow; + SVTK_RenderWindowInteractor* myRWInteractor; + bool myIsObserverAdded; + + QCheckBox* myIsBBCenter; + + QButtonGroup* myGroupSelButton; + QPushButton* myToOrigin; + QPushButton* mySelectPoint; + + QGroupBox* myGroupBoxCoord; + QLineEdit* myX; + QLineEdit* myY; + QLineEdit* myZ; + + void setEnabled(QGroupBox* theGrp, const bool theState); + + //---------------------------------------------------------------------------- + // Priority at which events are processed + vtkFloatingPointType myPriority; + + // Used to process events + vtkSmartPointer myEventCallbackCommand; + + // Description: + // Main process event method + static void ProcessEvents(vtkObject* object, + unsigned long event, + void* clientdata, + void* calldata); + +protected slots: + void onBBCenterChecked(); + + void onToOrigin(); + void onSelectPoint(); + + void onCoordChanged(); + + void onClickClose(); + +}; + +#endif // SVTK_SETROTATIONPOINTDLG_H diff --git a/src/SVTK/resources/SVTK_msg_en.po b/src/SVTK/resources/SVTK_msg_en.po index 1e28bfdbd..609f62c2b 100755 --- a/src/SVTK/resources/SVTK_msg_en.po +++ b/src/SVTK/resources/SVTK_msg_en.po @@ -113,6 +113,12 @@ msgstr "Rotation of the point of view around the scene center" msgid "MNU_ROTATE_VIEW" msgstr "Rotation" +msgid "DSC_CHANGINGROTATIONPOINT_VIEW" +msgstr "Change the point, around which the rotation is performed" + +msgid "MNU_CHANGINGROTATIONPOINT_VIEW" +msgstr "Change Rotation Point" + msgid "DSC_DUMP_VIEW" msgstr "Saves the active view in the image file" @@ -182,6 +188,39 @@ msgstr "Scaling" msgid "SVTK_MainWindow::DSC_SVTK_SCALING" msgstr "Scaling" +msgid "SVTK_SetRotationPointDlg::DLG_TITLE" +msgstr "Set Rotation Point" + +msgid "SVTK_SetRotationPointDlg::USE_BBCENTER" +msgstr "Use Bounding Box Center" + +msgid "SVTK_SetRotationPointDlg::LBL_TOORIGIN" +msgstr "Set to Origin" + +msgid "SVTK_SetRotationPointDlg::LBL_SELECTPOINT" +msgstr "Select Point from View" + +msgid "SVTK_SetRotationPointDlg::LBL_CENTER_OF_BOUNDING_BOX" +msgstr "Center of bounding box" + +msgid "SVTK_SetRotationPointDlg::LBL_ORIGIN" +msgstr "Origin of the coordinate system" + +msgid "SVTK_SetRotationPointDlg::LBL_SELECTED_POINT" +msgstr "Selected point" + +msgid "SVTK_SetRotationPointDlg::LBL_X" +msgstr "X :" + +msgid "SVTK_SetRotationPointDlg::LBL_Y" +msgstr "Y :" + +msgid "SVTK_SetRotationPointDlg::LBL_Z" +msgstr "Z :" + +msgid "SVTK_SetRotationPointDlg::RBUTTONGROUP_TITLE" +msgstr "The rotation point type" + msgid "SVTK_FontWidget::ARIAL" msgstr "Arial" -- 2.39.2