#include "VisuGUI_Plot3DDlg.h"
-#include "QAD_Application.h"
-#include "QAD_Desktop.h"
-#include "QAD_MessageBox.h"
+#include "VisuGUI.h"
+#include "VISU_Plot3DPL.hxx"
+
+#include "SALOME_Actor.h"
+#include "QAD_RightFrame.h"
+#include "VTKViewer_ViewFrame.h"
+#include "VTKViewer_RenderWindow.h"
#include <limits.h>
#include <qvalidator.h>
#include <qtabwidget.h>
+#include <vtkDataSet.h>
+#include <vtkDataSetMapper.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkCamera.h>
+#include <vtkRenderer.h>
+#include <vtkPlaneSource.h>
+#include <vtkPolyData.h>
+#include <vtkMath.h>
using namespace std;
+#define SURFACE_PRS_ID 0
+#define CONTOUR_PRS_ID 1
+
+#define GET_VTK_VIEWFRAME(aStudy) dynamic_cast<VTKViewer_ViewFrame*>(aStudy->getActiveStudyFrame()->getRightFrame()->getViewFrame())
+
+//=======================================================================
+//function : renderViewFrame
+//purpose :
+//=======================================================================
+
+static void renderViewFrame(QAD_Study* theStudy)
+{
+ if (VTKViewer_ViewFrame* vf = GET_VTK_VIEWFRAME( theStudy )) {
+ if (vf->getRenderer()->GetActors()->GetNumberOfItems() > 0) {
+ vf->getRenderer()->ResetCameraClippingRange();
+ vf->Repaint();
+ }
+ }
+}
+
+//=======================================================================
+//class : TPlane
+//purpose : actor of plane preview
+//=======================================================================
+
+class TPlane : public SALOME_Actor
+{
+ vtkDataSetMapper* myMapper;
+ vtkPlaneSource* myPlaneSource;
+
+ public:
+ // constructor
+ TPlane() {
+ Init();
+ }
+ // set plane parameters
+ void Set(float origin[3], float normal[3]) {
+ float point2[3], point1[3];
+ vtkMath::Perpendiculars( normal, point1, point2, 0. );
+ for ( int i = 0; i < 3; ++i ) {
+ point1[ i ] += origin[ i ];
+ point2[ i ] += origin[ i ];
+ }
+ myPlaneSource->SetOrigin( origin );
+ myPlaneSource->SetPoint1( point1 );
+ myPlaneSource->SetPoint2( point2 );
+ myPlaneSource->SetCenter( origin );
+ }
+ vtkTypeMacro(TPlane,SALOME_Actor);
+
+ protected:
+ void Init() {
+ myPlaneSource = vtkPlaneSource::New();
+ myMapper = vtkDataSetMapper::New();
+ myMapper->SetInput( myPlaneSource->GetOutput() );
+ // actor methods
+ VisibilityOff();
+ PickableOff();
+ SetInfinitive(true);
+ SetMapper( myMapper );
+ }
+ ~TPlane() {
+ myMapper->RemoveAllInputs();
+ myMapper->Delete();
+ myPlaneSource->UnRegisterAllOutputs();
+ myPlaneSource->Delete();
+ };
+ // Not implemented.
+ TPlane(const TPlane&);
+ void operator=(const TPlane&);
+};
+
+//=======================================================================
+//function : VisuGUI_Plot3DPane
+//purpose :
+//=======================================================================
VisuGUI_Plot3DPane::VisuGUI_Plot3DPane(QWidget* parent)
- : QVBox(parent)
+ :QVBox(parent), myInitFromPrs( false ), myPreviewActor(NULL),
+ myViewFrame(VisuGUI::GetVtkViewFrame()), myPrs(NULL), myPipeCopy(NULL),
+ myStudyFrame( VisuGUI::GetActiveStudy()->getActiveStudyFrame() )
+{
+ layout()->setAlignment( Qt::AlignTop );
+ setSpacing(6);
+
+ // Orientation
+
+ GBOrientation = new QButtonGroup( tr( "Orientation" ), this, "GBOrientation" );
+ GBOrientation->setTitle( tr( "ORIENTATION" ) );
+ GBOrientation->setColumnLayout(0, Qt::Vertical );
+ GBOrientation->layout()->setSpacing( 0 );
+ GBOrientation->layout()->setMargin( 0 );
+ QGridLayout* BGOrientationLayout = new QGridLayout( GBOrientation->layout() );
+ BGOrientationLayout->setAlignment( Qt::AlignTop );
+ BGOrientationLayout->setSpacing( 6 );
+ BGOrientationLayout->setMargin( 11 );
+
+ QRadioButton *RBxy, *RByz, *RBzx;
+ RBxy = new QRadioButton( tr( "// X-Y" ), GBOrientation, "RBxy" );
+ RByz = new QRadioButton( tr( "// Y-Z" ), GBOrientation, "RByz" );
+ RBzx = new QRadioButton( tr( "// Z-X" ), GBOrientation, "RBzx" );
+ BGOrientationLayout->addWidget( RBxy, 0, 0 );
+ BGOrientationLayout->addWidget( RByz, 0, 1 );
+ BGOrientationLayout->addWidget( RBzx, 0, 2 );
+
+ // Rotation
+
+ QGroupBox* GBrot = new QGroupBox( tr( "ROTATIONS" ), this, "GBrot" );
+ GBrot->setColumnLayout(0, Qt::Vertical );
+ GBrot->layout()->setSpacing( 0 );
+ GBrot->layout()->setMargin( 0 );
+ QGridLayout* GBrotLayout = new QGridLayout( GBrot->layout() );
+ GBrotLayout->setAlignment( Qt::AlignTop );
+ GBrotLayout->setSpacing( 6 );
+ GBrotLayout->setMargin( 11 );
+ // label 1
+ LabelRot1 = new QLabel( tr( "ROTATION_X" ), GBrot, "LabelRot1" );
+ GBrotLayout->addWidget( LabelRot1, 0, 0 );
+ // spin 1
+ Rot1 = new QAD_SpinBoxDbl( GBrot, -180, 180, 5 );
+ Rot1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+ GBrotLayout->addWidget( Rot1, 0, 1 );
+ // label 2
+ LabelRot2 = new QLabel( tr( "ROTATION_Y" ), GBrot, "LabelRot2" );
+ GBrotLayout->addWidget( LabelRot2, 1, 0 );
+ // spin 2
+ Rot2 = new QAD_SpinBoxDbl( GBrot, -180, 180, 5 );
+ Rot2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+ GBrotLayout->addWidget( Rot2, 1, 1 );
+
+ // Position
+
+ QGroupBox* GBpos = new QGroupBox( tr( "POSITION" ), this, "GBpos" );
+ GBpos->setColumnLayout(0, Qt::Horizontal );
+ GBpos->layout()->setSpacing( 0 );
+ GBpos->layout()->setMargin( 0 );
+ QGridLayout* GBposLayout = new QGridLayout( GBpos->layout() );
+ GBposLayout->setAlignment( Qt::AlignTop );
+ GBposLayout->setSpacing( 6 );
+ GBposLayout->setMargin( 11 );
+ // value label
+ QLabel * valueLabel = new QLabel( tr( "POSITION_VALUE" ), GBpos, "LabelRot1" );
+ GBposLayout->addWidget( valueLabel, 0, 0 );
+ // value spin
+ PositionSpn = new QAD_SpinBoxDbl( GBpos, 0, 1, 0.1 );
+ GBposLayout->addWidget( PositionSpn, 0, 1 );
+ // Relative CheckBox
+ RelativeChkB = new QCheckBox(tr("RELATIVE"), GBpos, "RelativeChkB");
+ RelativeChkB->setChecked( true );
+ GBposLayout->addWidget( RelativeChkB, 0, 2 );
+
+ // Scale, Presentation type, Nb Contours, Preview
+
+ QFrame* bottomFrame = new QFrame( this );
+ QGridLayout* bottomLayout = new QGridLayout( bottomFrame );
+ bottomLayout->setAlignment( Qt::AlignTop );
+ bottomLayout->setSpacing( 11 );
+ bottomLayout->setMargin( 0 );
+ // scale
+ QLabel* scaleLabel = new QLabel( tr( "SCALE" ), bottomFrame );
+ ScaleSpn = new QAD_SpinBoxDbl( bottomFrame, -1.e6, 1.e6, 0.1 );
+ // Presentation type
+ GBPrsType = new QHButtonGroup( tr("PRESENTATION_TYPE"), bottomFrame );
+ new QRadioButton( tr( "SURFACE" ), GBPrsType);
+ new QRadioButton( tr( "CONTOUR" ), GBPrsType);
+ // nb Contours
+ QLabel* nbContLabel = new QLabel( tr( "NUMBER_CONTOURS" ), bottomFrame );
+ NbContoursSpn = new QSpinBox( 1, 999, 1, bottomFrame, "NbContoursSpn" );
+ // Preview
+ PreviewChkB = new QCheckBox(tr("PREVIEW"), bottomFrame);
+ PreviewChkB->setChecked(false);
+
+ bottomLayout->addWidget( scaleLabel, 0, 0 );
+ bottomLayout->addWidget( ScaleSpn, 0, 1 );
+ bottomLayout->addMultiCellWidget( GBPrsType, 1, 1, 0, 1 );
+ bottomLayout->addWidget( nbContLabel, 2, 0 );
+ bottomLayout->addWidget( NbContoursSpn, 2, 1 );
+ bottomLayout->addWidget( PreviewChkB, 3, 0 );
+
+
+ // signals and slots connections
+
+ connect( GBOrientation, SIGNAL( clicked( int )), this, SLOT( orientationChanged( int )));
+ connect( Rot1, SIGNAL( valueChanged( double )), this, SLOT( updatePreview() ));
+ connect( Rot2, SIGNAL( valueChanged( double )), this, SLOT( updatePreview() ));
+ connect( PositionSpn, SIGNAL( valueChanged( double )), this, SLOT( onPositionSpn() ));
+ connect( RelativeChkB, SIGNAL( toggled( bool)), this, SLOT( onRelativePos( bool )));
+ connect( GBPrsType, SIGNAL( clicked( int )), this, SLOT( onPrsType( int )));
+ connect( PreviewChkB, SIGNAL( toggled( bool)), this, SLOT( updatePreview() ));
+}
+
+//=======================================================================
+//function : destructor
+//purpose :
+//=======================================================================
+
+VisuGUI_Plot3DPane::~VisuGUI_Plot3DPane()
+{
+ if ( myPreviewActor ) {
+ if (myViewFrame && VisuGUI::GetVtkViewFrame())
+ myViewFrame->RemoveActor( myPreviewActor );
+ myPreviewActor->Delete();
+ }
+ renderViewFrame( myStudyFrame->getStudy() );
+}
+
+//=======================================================================
+//function : storePrsParams
+//purpose : create a copy of Prs parameters and then store current
+// control values into the Prs
+//=======================================================================
+
+void VisuGUI_Plot3DPane::storePrsParams()
+{
+ if ( !myPipeCopy )
+ myPipeCopy = VISU_Plot3DPL::New();
+ if ( myPrs ) {
+ myPipeCopy->ShallowCopy( myPrs->GetPL() );
+ storeToPrsObject( myPrs );
+ }
+}
+
+//=======================================================================
+//function : restorePrsParams
+//purpose : restore Prs parameters from the copy
+//=======================================================================
+
+void VisuGUI_Plot3DPane::restorePrsParams()
+{
+ if ( !myPipeCopy )
+ myPipeCopy = VISU_Plot3DPL::New();
+ if ( myPrs )
+ myPrs->GetPL()->ShallowCopy( myPipeCopy );
+}
+
+//=======================================================================
+//function : onPositionSpn
+//purpose : update absolute position range
+//=======================================================================
+
+void VisuGUI_Plot3DPane::onPositionSpn()
+{
+ if ( myPrs && !RelativeChkB->isChecked() ) {
+ float minPos, maxPos;
+ storePrsParams();
+ myPrs->GetPlot3DPL()->GetMinMaxPosition( minPos, maxPos );
+ restorePrsParams();
+ if ( minPos > PositionSpn->value() )
+ minPos = PositionSpn->value();
+ if ( maxPos < PositionSpn->value() )
+ maxPos = PositionSpn->value();
+ PositionSpn->setRange( minPos, maxPos );
+ }
+ updatePreview();
+}
+
+//=======================================================================
+//function : orientationChanged
+//purpose : update rotation labels and preview
+//=======================================================================
+
+void VisuGUI_Plot3DPane::orientationChanged( int Id )
+{
+ if ( Id == 0 ) { // RBxy->isChecked()
+ LabelRot1->setText( tr( "ROTATION_X" ) );
+ LabelRot2->setText( tr( "ROTATION_Y" ) );
+ } else if ( Id == 1 ) { // RByz->isChecked()
+ LabelRot1->setText( tr( "ROTATION_Y" ) );
+ LabelRot2->setText( tr( "ROTATION_Z" ) );
+ } else {
+ LabelRot1->setText( tr( "ROTATION_Z" ) );
+ LabelRot2->setText( tr( "ROTATION_X" ) );
+ }
+ updatePreview();
+}
+
+//=======================================================================
+//function : onRelativePos
+//purpose : update position value and range
+//=======================================================================
+
+void VisuGUI_Plot3DPane::onRelativePos( bool isRelativePos )
+{
+ float minPos = 0., maxPos = 1., pos = PositionSpn->value();
+ if ( myPrs ) {
+ storePrsParams();
+ myPrs->GetPlot3DPL()->GetMinMaxPosition( minPos, maxPos );
+ restorePrsParams();
+ if ( isRelativePos ) // absolute -> relative
+ pos = ( pos - minPos ) / ( maxPos - minPos );
+ else // relative -> absolute
+ pos = minPos * ( 1. - pos ) + maxPos * pos;
+ }
+ PositionSpn->setMinValue( isRelativePos ? 0. : minPos );
+ PositionSpn->setMaxValue( isRelativePos ? 1. : maxPos );
+ PositionSpn->setValue( pos );
+}
+
+//=======================================================================
+//function : onPrsType
+//purpose :
+//=======================================================================
+
+void VisuGUI_Plot3DPane::onPrsType( int id )
{
+ NbContoursSpn->setEnabled( id == CONTOUR_PRS_ID );
}
+//=======================================================================
+//function : updatePreview
+//purpose :
+//=======================================================================
+
+void VisuGUI_Plot3DPane::updatePreview()
+{
+ if ( myInitFromPrs )
+ return;
+ if ( PreviewChkB->isChecked() ) // show preview plane
+ {
+ TPlane* planePreview = (TPlane*) myPreviewActor;
+ if ( !planePreview ) {
+ myPreviewActor = planePreview = new TPlane;
+ if ( myViewFrame ) {
+ myViewFrame->AddActor( planePreview );
+ if ( !VisuGUI::GetActor( myPrs ))
+ myViewFrame->onViewFitAll();
+ }
+ }
+ if ( myPrs ) // set plane parameters corresponding to control values
+ {
+ storePrsParams();
+ float normal[3], origin[3];
+ myPrs->GetPlot3DPL()->GetBasePlane( origin, normal, true );
+ planePreview->Set( origin, normal );
+ planePreview->SetVisibility( true );
+ restorePrsParams();
+ }
+ }
+ else if ( myPreviewActor ) // erase preview
+ {
+ myPreviewActor->SetVisibility( false );
+ }
+ renderViewFrame( myStudyFrame->getStudy() );
+}
+
+//=======================================================================
+//function : initFromPrsObject
+//purpose :
+//=======================================================================
+
void VisuGUI_Plot3DPane::initFromPrsObject(VISU::Plot3D_i* thePrs)
{
+ myInitFromPrs = true;
+ myPrs = thePrs;
+
+ // orientation
+ int id;
+ switch ( thePrs->GetOrientationType() ) {
+ case VISU::Plot3D::XY: id = 0; break;
+ case VISU::Plot3D::YZ: id = 1; break;
+ default: id = 2;
+ }
+ GBOrientation->setButton( id );
+ orientationChanged( id );
+
+ // rotation
+ Rot1->setValue( thePrs->GetRotateX() * 180./PI );
+ Rot2->setValue( thePrs->GetRotateY() * 180./PI );
+
+ // position
+ RelativeChkB->setChecked( thePrs->IsPositionRelative() );
+ onRelativePos( thePrs->IsPositionRelative() ); // update range
+ PositionSpn->setValue( thePrs->GetPlanePosition() );
+
+ // scale
+ ScaleSpn->setValue( thePrs->GetScaleFactor() );
+
+ // prs type
+ id = thePrs->GetIsContourPrs() ? CONTOUR_PRS_ID : SURFACE_PRS_ID;
+ GBPrsType->setButton( id );
+ onPrsType( id );
+
+ // nb contours
+ NbContoursSpn->setValue( thePrs->GetNbOfContours() );
+
+ // disable cutting plane controls if the mesh is planar
+
+ vtkDataSet* unstrGrid = thePrs->GetPL()->GetInput();
+ float aBounds[6];
+ unstrGrid->GetBounds( aBounds ); // xmin,xmax, ymin,ymax, zmin,zmax
+ if (fabs( aBounds[0] - aBounds[1] ) <= FLT_MIN ||
+ fabs( aBounds[2] - aBounds[3] ) <= FLT_MIN ||
+ fabs( aBounds[4] - aBounds[5] ) <= FLT_MIN )
+ {
+ GBOrientation->setEnabled( false );
+ Rot1 ->setEnabled( false );
+ Rot2 ->setEnabled( false );
+ PositionSpn ->setEnabled( false );
+ RelativeChkB ->setEnabled( false );
+ PreviewChkB ->setEnabled( false );
+ }
+
+ myInitFromPrs = false;
+ updatePreview();
}
+//=======================================================================
+//function : storeToPrsObject
+//purpose :
+//=======================================================================
+
int VisuGUI_Plot3DPane::storeToPrsObject(VISU::Plot3D_i* thePrs)
{
+ if ( myInitFromPrs )
+ return 0;
+ // orientation
+ int id = GBOrientation->id ( GBOrientation->selected() );
+ VISU::Plot3D::Orientation ori;
+ switch ( id ) {
+ case 0 : ori = VISU::Plot3D::XY ; break;
+ case 1 : ori = VISU::Plot3D::YZ ; break;
+ default: ori = VISU::Plot3D::ZX ;
+ }
+ // rotation
+ thePrs->SetOrientation( ori, Rot1->value()*PI/180., Rot2->value()*PI/180. );
+
+ // position
+ thePrs->SetPlanePosition( PositionSpn->value(), RelativeChkB->isChecked() );
+
+ // scale
+ thePrs->SetScaleFactor( ScaleSpn->value() );
+
+ // prs type
+ id = GBPrsType->id ( GBPrsType->selected() );
+ thePrs->SetContourPrs( id == CONTOUR_PRS_ID );
+
+ // nb contours
+ thePrs->SetNbOfContours( NbContoursSpn->value() );
+
return 1;
}
+//=======================================================================
+//function : check
+//purpose :
+//=======================================================================
+
bool VisuGUI_Plot3DPane::check()
{
+ if ( myPreviewActor ) // erase preview
+ myPreviewActor->SetVisibility( false );
+
return true;
}
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
-/*!
- Constructor
-*/
VisuGUI_Plot3DDlg::VisuGUI_Plot3DDlg()
- : QDialog( QAD_Application::getDesktop(), "VisuGUI_Plot3DDlg", true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
+ : QDialog( QAD_Application::getDesktop(), "VisuGUI_Plot3DDlg", false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
{
- setCaption( tr( "Iso Surfaces Definition" ) );
+ setCaption( tr( "TITLE" ) );
setSizeGripEnabled( TRUE );
QVBoxLayout* TopLayout = new QVBoxLayout(this);
TopLayout->setMargin(11);
QTabWidget* aTabBox = new QTabWidget(this);
- myIsoPane = new VisuGUI_Plot3DPane(this);
+ myIsoPane = new VisuGUI_Plot3DPane(this);
myIsoPane->setMargin( 5 );
- aTabBox->addTab(myIsoPane, "Iso Surface");
+ aTabBox->addTab(myIsoPane, tr( "PLOT3D_TAB_TITLE" ));
myScalarPane = new VisuGUI_ScalarBarPane(this, false);
- myIsoPane->setScalarBarPane(myScalarPane);
+ //myIsoPane->setScalarBarPane(myScalarPane);
myScalarPane->setMargin( 5 );
- aTabBox->addTab(myScalarPane, "Scalar Bar");
+ aTabBox->addTab(myScalarPane, tr( "SCALAR_BAR_TAB_TITLE" ));
TopLayout->addWidget(aTabBox);
TopLayout->addWidget(GroupButtons);
+ QAD_StudyFrame* studyFrame = VisuGUI::GetActiveStudy()->getActiveStudyFrame();
+
// signals and slots connections
connect( buttonOk, SIGNAL( clicked() ), this, SLOT( accept() ) );
connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
+ connect( studyFrame, SIGNAL(sfStudyFrameActivated(QAD_StudyFrame*)),
+ this, SLOT(onFrameActivated(QAD_StudyFrame*)));
+}
+
+//=======================================================================
+//function : accept
+//purpose :
+//=======================================================================
+
+void VisuGUI_Plot3DDlg::accept()
+{
+ if (myIsoPane->check() && myScalarPane->check()) {
+ if ( !isModal() ) {
+ VISU::Plot3D_i* prs = myIsoPane->GetPrs();
+ QAD_Study* study = myIsoPane->GetStudyFrame()->getStudy();
+ bool isCreation = !VisuGUI::GetActor( prs );
+ if (storeToPrsObject( prs )) {
+ if ( isCreation ) { // creation
+ if ( study->getActiveStudyFrame()->getTypeView() == VIEW_VTK) {
+ try {
+ VisuGUI::CreateActor( prs );
+ }
+ catch (...) {
+ reject();
+ return;
+ }
+ GET_VTK_VIEWFRAME( study )->onViewFitAll();
+ }
+ } else { // edition
+ VisuGUI::RecreateActor(prs);
+ renderViewFrame( study );
+ }
+ } else {
+ if (isCreation) {
+ prs->RemoveFromStudy();
+ study->updateObjBrowser();
+ }
+ }
+ }
+ QDialog::accept();
+ }
}
-void VisuGUI_Plot3DDlg::accept() {
- if (myIsoPane->check() && myScalarPane->check()) QDialog::accept();
+//=======================================================================
+//function : reject
+//purpose :
+//=======================================================================
+
+void VisuGUI_Plot3DDlg::reject()
+{
+ myIsoPane->check(); // hide preview
+
+ if (!isModal() && myIsoPane->GetPrs() &&
+ !VisuGUI::GetActor( myIsoPane->GetPrs() )) {
+ myIsoPane->GetPrs()->RemoveFromStudy();
+ myIsoPane->GetStudyFrame()->getStudy()->updateObjBrowser();
+ }
+ QDialog::reject();
}
+//=======================================================================
+//function : onFrameActivated
+//purpose :
+//=======================================================================
+
+void VisuGUI_Plot3DDlg::onFrameActivated( QAD_StudyFrame* theFrame) {
+ if (theFrame != myIsoPane->GetStudyFrame() )
+ reject();
+}