#include "VisuGUI.h"
#include "VISU_Prs3d_i.hh"
+#include <VISU_Result_i.hh>
#include "QAD_Config.h"
#include "QAD_RightFrame.h"
#include <qlayout.h>
#include <qgroupbox.h>
#include <qvalidator.h>
+#include <qtabwidget.h>
+#include <qhbuttongroup.h>
+#include <qradiobutton.h>
+#include <qspinbox.h>
// VTK Includes
#include <vtkMath.h>
#include <vtkPolyData.h>
#include <vtkUnstructuredGrid.h>
+// OCC
+#include <gp_Dir.hxx>
+
using namespace std;
namespace VISU {
}
}
- void RangeStepAndValidator (QAD_SpinBoxDbl* theSpinBox, double min, double max,
+void RangeStepAndValidator (QAD_SpinBoxDbl* theSpinBox, double min, double max,
double step, unsigned short decimals)
{
theSpinBox->setRange(min, max);
}
};
+//=======================================================================
+//class : OrientedPlane
+//purpose :
+//=======================================================================
+
class OrientedPlane: public vtkPlane
{
QAD_Study* myStudy;
~OrientedPlane()
{
- //if (myStudy && VISU::FindVtkViewFrame(myStudy,myStudyFrame)) {
- if (myStudy && VisuGUI::GetVtkViewFrame()) {
+ //if (myStudy && VISU::FindVtkViewFrame(myStudy,myStudyFrame))
+ if (myStudy && VisuGUI::GetVtkViewFrame())
myViewFrame->RemoveActor(myActor);
- }
+
myActor->Delete();
myMapper->RemoveAllInputs();
VisuGUI_ClippingDlgLayout->setMargin( 11 );
// Controls for selecting, creating, deleting planes
+
QGroupBox* GroupPlanes = new QGroupBox( this, "GroupPlanes" );
GroupPlanes->setTitle( tr("Clipping planes") );
GroupPlanes->setColumnLayout(0, Qt::Vertical);
GroupPlanesLayout->addWidget( buttonDelete, 0, 3 );
// Controls for defining plane parameters
- QGroupBox* GroupParameters = new QGroupBox( this, "GroupParameters" );
+
+ // Tab pane
+ QGroupBox* GroupParameters = new QGroupBox(this, "GroupParameters" );
GroupParameters->setTitle( tr("VISU_PARAMETERS") );
GroupParameters->setColumnLayout(0, Qt::Vertical);
GroupParameters->layout()->setSpacing( 0 );
GroupParametersLayout->setAlignment( Qt::AlignTop );
GroupParametersLayout->setSpacing( 6 );
GroupParametersLayout->setMargin( 11 );
-
- TextLabelOrientation = new QLabel( GroupParameters, "TextLabelOrientation" );
- TextLabelOrientation->setText( tr("TXT_ORIENTATION") );
- GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );
-
- ComboBoxOrientation = new QComboBox(GroupParameters, "ComboBoxOrientation");
- GroupParametersLayout->addWidget( ComboBoxOrientation, 0, 1 );
-
- TextLabelDistance = new QLabel( GroupParameters, "TextLabelDistance" );
- TextLabelDistance->setText( tr("VISU_DISTANCE") );
- GroupParametersLayout->addWidget( TextLabelDistance, 1, 0 );
- SpinBoxDistance = new QAD_SpinBoxDbl( GroupParameters, "SpinBoxDistance" );
- GroupParametersLayout->addWidget( SpinBoxDistance, 1, 1 );
+ TabPane = new QTabWidget( GroupParameters );
+ TabPane->addTab( createParamsTab(), "Non structured" );
+ TabPane->addTab( createIJKParamsTab(), "IJK (Structured)" );
+ GroupParametersLayout->addWidget( TabPane, 0, 0 );
- TextLabelRot1 = new QLabel( GroupParameters, "TextLabelRot1" );
- TextLabelRot1->setText( tr("Rotation around X (Y to Z):") );
- GroupParametersLayout->addWidget( TextLabelRot1, 2, 0 );
-
- SpinBoxRot1 = new QAD_SpinBoxDbl( GroupParameters, "SpinBoxRot1" );
- GroupParametersLayout->addWidget( SpinBoxRot1, 2, 1 );
-
- TextLabelRot2 = new QLabel( GroupParameters, "TextLabelRot2" );
- TextLabelRot2->setText( tr("Rotation around Y (X to Z):") );
- GroupParametersLayout->addWidget( TextLabelRot2, 3, 0 );
-
- SpinBoxRot2 = new QAD_SpinBoxDbl( GroupParameters, "SpinBoxRot2" );
- GroupParametersLayout->addWidget( SpinBoxRot2, 3, 1 );
+ // "Show preview" and "Auto Apply" check boxes
- PreviewCheckBox = new QCheckBox(tr("Show preview"), GroupParameters);
+ PreviewCheckBox = new QCheckBox(tr("Show preview"), this);
PreviewCheckBox->setChecked(true);
- GroupParametersLayout->addWidget( PreviewCheckBox, 4, 0 );
- AutoApplyCheckBox = new QCheckBox(tr("Auto Apply"), GroupParameters);
+ AutoApplyCheckBox = new QCheckBox(tr("Auto Apply"), this);
AutoApplyCheckBox->setChecked(false);
- GroupParametersLayout->addWidget( AutoApplyCheckBox, 4, 1 );
-
+
// Controls for "Ok", "Apply" and "Close" button
+
QGroupBox* GroupButtons = new QGroupBox( this, "GroupButtons" );
GroupButtons->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)0, 0, 0, GroupButtons->sizePolicy().hasHeightForWidth() ) );
GroupButtons->setGeometry( QRect( 10, 10, 281, 48 ) );
buttonOk->setDefault( TRUE );
GroupButtonsLayout->addWidget( buttonOk, 0, 0 );
- VisuGUI_ClippingDlgLayout->addWidget( GroupPlanes, 0, 0 );
- VisuGUI_ClippingDlgLayout->addWidget( GroupParameters, 1, 0 );
- VisuGUI_ClippingDlgLayout->addWidget( GroupButtons, 2, 0 );
+ VisuGUI_ClippingDlgLayout->addMultiCellWidget( GroupPlanes, 0, 0, 0, 1 );
+ VisuGUI_ClippingDlgLayout->addMultiCellWidget( GroupParameters, 1, 1, 0, 1 );
+ VisuGUI_ClippingDlgLayout->addWidget( PreviewCheckBox, 2, 0 );
+ VisuGUI_ClippingDlgLayout->addWidget( AutoApplyCheckBox, 2, 1 );
+ VisuGUI_ClippingDlgLayout->addMultiCellWidget( GroupButtons, 3, 3, 0, 1 );
// mySelection = SALOME_Selection::Selection( VisuGUI::GetVisuGUI()->GetActiveStudy()->getSelection());
connect( ComboBoxPlanes, SIGNAL( activated( int )), this, SLOT( onSelectPlane( int ) ) );
connect( buttonNew, SIGNAL( clicked() ), this, SLOT( ClickOnNew() ) );
connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );
- connect( ComboBoxOrientation, SIGNAL( activated( int )), this, SLOT( onSelectOrientation( int ) ) );
- connect( SpinBoxDistance, SIGNAL( valueChanged( double )), this, SLOT( SetCurrentPlaneParam() ) );
+ connect( ComboBoxOrientation, SIGNAL( activated( int )), this, SLOT( onSelectOrientation(int)));
+ connect( SpinBoxDistance, SIGNAL( valueChanged( double )), this, SLOT( SetCurrentPlaneParam()));
connect( SpinBoxRot1, SIGNAL( valueChanged( double )), this, SLOT( SetCurrentPlaneParam() ) );
connect( SpinBoxRot2, SIGNAL( valueChanged( double )), this, SLOT( SetCurrentPlaneParam() ) );
+ connect( ButtonGroupIJKAxis, SIGNAL( clicked( int )), this, SLOT( onIJKAxisChanged( int ) ) );
+ connect( SpinBoxIJKIndex, SIGNAL( valueChanged( int )), this, SLOT( SetCurrentPlaneIJKParam()));
+ connect( CheckBoxIJKPlaneReverse, SIGNAL(toggled(bool)), this, SLOT( SetCurrentPlaneIJKParam()));
+ connect( TabPane, SIGNAL( currentChanged ( QWidget* )), this, SLOT( onTabChanged( QWidget* )));
+
connect( PreviewCheckBox, SIGNAL( toggled( bool )), this, SLOT( OnPreviewToggle( bool ) ) );
connect( AutoApplyCheckBox, SIGNAL( toggled( bool )), this, SLOT( ClickOnApply() ) );
connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
VISU::RenderViewFrame(VisuGUI::GetActiveStudy());
}
+//=======================================================================
+//function : createParamsTab
+//purpose :
+//=======================================================================
+
+QWidget* VisuGUI_ClippingDlg::createParamsTab()
+{
+ QFrame* GroupParameters = new QFrame( this );
+ QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters );
+ GroupParametersLayout->setAlignment( Qt::AlignTop );
+ GroupParametersLayout->setSpacing( 6 );
+ GroupParametersLayout->setMargin( 11 );
+
+ TextLabelOrientation = new QLabel( GroupParameters, "TextLabelOrientation" );
+ TextLabelOrientation->setText( tr("TXT_ORIENTATION") );
+ GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );
+
+ ComboBoxOrientation = new QComboBox(GroupParameters, "ComboBoxOrientation");
+ GroupParametersLayout->addWidget( ComboBoxOrientation, 0, 1 );
+
+ TextLabelDistance = new QLabel( GroupParameters, "TextLabelDistance" );
+ TextLabelDistance->setText( tr("VISU_DISTANCE") );
+ GroupParametersLayout->addWidget( TextLabelDistance, 1, 0 );
+
+ SpinBoxDistance = new QAD_SpinBoxDbl( GroupParameters, "SpinBoxDistance" );
+ GroupParametersLayout->addWidget( SpinBoxDistance, 1, 1 );
+
+ TextLabelRot1 = new QLabel( GroupParameters, "TextLabelRot1" );
+ TextLabelRot1->setText( tr("Rotation around X (Y to Z):") );
+ GroupParametersLayout->addWidget( TextLabelRot1, 2, 0 );
+
+ SpinBoxRot1 = new QAD_SpinBoxDbl( GroupParameters, "SpinBoxRot1" );
+ GroupParametersLayout->addWidget( SpinBoxRot1, 2, 1 );
+
+ TextLabelRot2 = new QLabel( GroupParameters, "TextLabelRot2" );
+ TextLabelRot2->setText( tr("Rotation around Y (X to Z):") );
+ GroupParametersLayout->addWidget( TextLabelRot2, 3, 0 );
+
+ SpinBoxRot2 = new QAD_SpinBoxDbl( GroupParameters, "SpinBoxRot2" );
+ GroupParametersLayout->addWidget( SpinBoxRot2, 3, 1 );
+
+ return GroupParameters;
+}
+
+//=======================================================================
+//function : createIJKParamsTab
+//purpose :
+//=======================================================================
+
+QWidget* VisuGUI_ClippingDlg::createIJKParamsTab()
+{
+ // tab layout
+ WidgetIJKTab = new QFrame( this );
+ QGridLayout* IJKParametersLayout = new QGridLayout( WidgetIJKTab );
+ IJKParametersLayout->setAlignment( Qt::AlignTop );
+ IJKParametersLayout->setSpacing( 6 );
+ IJKParametersLayout->setMargin( 11 );
+
+ // Axis group
+ ButtonGroupIJKAxis = new QHButtonGroup( QObject::tr( "Axis" ), WidgetIJKTab);
+ new QRadioButton( QObject::tr( "I" ), ButtonGroupIJKAxis); // 0
+ new QRadioButton( QObject::tr( "J" ), ButtonGroupIJKAxis); // 1
+ new QRadioButton( QObject::tr( "K" ), ButtonGroupIJKAxis); // 2
+ ButtonGroupIJKAxis->setButton(0);
+
+ // Index
+ TextLabelIJKIndex = new QLabel( WidgetIJKTab, "TextLabelIJKIndex" );
+ TextLabelIJKIndex->setText( tr( "Index (from 0 to 0)" ));
+ SpinBoxIJKIndex = new QSpinBox( WidgetIJKTab, "SpinBoxIJKIndex");
+
+ // Orientation
+ CheckBoxIJKPlaneReverse = new QCheckBox( tr("Reverse normal"), WidgetIJKTab);
+ CheckBoxIJKPlaneReverse->setChecked(false);
+
+ IJKParametersLayout->addMultiCellWidget( ButtonGroupIJKAxis, 0, 0, 0, 1 );
+ IJKParametersLayout->addWidget( TextLabelIJKIndex, 1, 0 );
+ IJKParametersLayout->addWidget( SpinBoxIJKIndex, 1, 1 );
+ IJKParametersLayout->addWidget( CheckBoxIJKPlaneReverse, 2, 0 );
+
+ return WidgetIJKTab;
+}
+
//=======================================================================
// function : ClickOnApply()
// purpose :
TSetVisiblity(PreviewCheckBox->isChecked()));
}
}
+ // enable/disable IJK tab
+ TabPane->setTabEnabled( WidgetIJKTab, isStructured() );
Sinchronize();
//VISU::RenderViewFrame(VISU::GetCurrentVtkView());
VISU::RenderViewFrame(VisuGUI::GetActiveStudy());
{
if (!myPrs3d || myPlanes.empty())
return;
-
+
OrientedPlane* aPlane = myPlanes[theIndex].GetPointer();
// Orientation
myIsSelectPlane = true;
setDistance(aPlane->GetDistance());
setRotation(aRot[0], aRot[1]);
+ int item = 0;
switch (anOrientation) {
- case VISU::XY:
- ComboBoxOrientation->setCurrentItem(0);
- onSelectOrientation(0);
- break;
- case VISU::YZ:
- ComboBoxOrientation->setCurrentItem(1);
- onSelectOrientation(1);
- break;
- case VISU::ZX:
- ComboBoxOrientation->setCurrentItem(2);
- onSelectOrientation(2);
- break;
+ case VISU::XY: item = 0; break;
+ case VISU::YZ: item = 1; break;
+ case VISU::ZX: item = 2; break;
}
+ ComboBoxOrientation->setCurrentItem( item );
+
+ bool isIJK = ( TabPane->currentPage() == WidgetIJKTab );
+ if ( isIJK )
+ setIJKByNonStructured();
+ else
+ onSelectOrientation( item );
+
myIsSelectPlane = false;
}
//=======================================================================
// function : Sinchronize()
-// purpose :
+// purpose : update control values according to plane selection
//=======================================================================
void VisuGUI_ClippingDlg::Sinchronize()
{
SpinBoxDistance->setValue(0.5);
}
- buttonDelete->setEnabled(anIsControlsEnable);
- buttonApply->setEnabled(anIsControlsEnable);
- PreviewCheckBox->setEnabled(anIsControlsEnable);
- AutoApplyCheckBox->setEnabled(anIsControlsEnable);
- ComboBoxOrientation->setEnabled(anIsControlsEnable);
- SpinBoxDistance->setEnabled(anIsControlsEnable);
- SpinBoxRot1->setEnabled(anIsControlsEnable);
- SpinBoxRot2->setEnabled(anIsControlsEnable);
+ buttonDelete ->setEnabled(anIsControlsEnable);
+ buttonApply ->setEnabled(anIsControlsEnable);
+ PreviewCheckBox ->setEnabled(anIsControlsEnable);
+ AutoApplyCheckBox ->setEnabled(anIsControlsEnable);
+
+ ComboBoxOrientation ->setEnabled(anIsControlsEnable);
+ SpinBoxDistance ->setEnabled(anIsControlsEnable);
+ SpinBoxRot1 ->setEnabled(anIsControlsEnable);
+ SpinBoxRot2 ->setEnabled(anIsControlsEnable);
+
+ ButtonGroupIJKAxis ->setEnabled(anIsControlsEnable);
+ SpinBoxIJKIndex ->setEnabled(anIsControlsEnable);
+ CheckBoxIJKPlaneReverse->setEnabled(anIsControlsEnable);
}
//=======================================================================
VISU::RenderViewFrame(VisuGUI::GetActiveStudy());
}
+//=======================================================================
+//function : onTabChanged
+//purpose :
+//=======================================================================
+
+void VisuGUI_ClippingDlg::onTabChanged( QWidget* newTab)
+{
+ if ( newTab == WidgetIJKTab ) // IJK
+ setIJKByNonStructured();
+}
+
+//=======================================================================
+//function : SetCurrentPlaneIJKParam
+//purpose : set non structured parameters by IJK parameters
+//=======================================================================
+
+void VisuGUI_ClippingDlg::SetCurrentPlaneIJKParam()
+{
+ if (myPlanes.empty() || myIsSelectPlane || !WidgetIJKTab->isEnabled())
+ return;
+
+ VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
+ if ( !result )
+ return;
+
+ // get axis data
+ int i, axId = ButtonGroupIJKAxis->id ( ButtonGroupIJKAxis->selected() );
+ VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axId;
+ gp_Dir dir;
+ const vector<float> * values =
+ result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
+ if ( !values )
+ return;
+
+ // find distance;
+ int index = SpinBoxIJKIndex->value();
+ float distance = 0;
+ if ( index < values->size() )
+ distance = (*values)[ index ];
+
+ // find id of axis closest to dir
+ // 0 || X-Y - axis Z
+ // 1 || Y-Z - azis X
+ // 2 || Z-X - axiz Y
+ double cos[3] = { gp::DZ() * dir, gp::DX() * dir, gp::DY() * dir };
+ double maxCos = 0;
+ for ( i = 0; i < 3; ++i ) {
+ if ( Abs( cos[ i ]) > Abs ( maxCos )) {
+ maxCos = cos[ i ];
+ axId = i;
+ }
+ }
+ // find rotation angles
+ float angle[2];
+ int rotId[2] = {
+ ( axId == 0 ) ? 2 : axId - 1,
+ ( axId == 2 ) ? 0 : axId + 1
+ };
+ static double aCoeff = 180.0/vtkMath::Pi();
+ for ( i = 0; i < 2; ++i ) {
+ float cosin = cos[ rotId[ i ]];
+ if ( maxCos < 0 )
+ cosin = -cosin;
+ angle[ i ] = asin( cosin ) * aCoeff;
+ if ( maxCos < 0 )
+ angle[ i ] += 180. * ( angle[ i ] < 0 ? 1. : -1. );
+ }
+ if ( CheckBoxIJKPlaneReverse->isChecked() ) {
+ angle[ 0 ] += 180. * ( angle[ 0 ] < 0 ? 1. : -1. );
+ distance = 1. - distance;
+ }
+ if ( maxCos < 0 )
+ distance = 1. - distance;
+
+ // set paramerets
+ myIsSelectPlane = true;
+ ComboBoxOrientation->setCurrentItem( axId );
+ setRotation( -angle[0], -angle[1] );
+ setDistance( distance );
+ myIsSelectPlane = false;
+
+ SetCurrentPlaneParam();
+}
+
+//=======================================================================
+//function : setIJKByNonStructured
+//purpose : convert current non structured parameters to structured ones
+//=======================================================================
+
+void VisuGUI_ClippingDlg::setIJKByNonStructured()
+{
+ if (!myPrs3d || myPlanes.empty() || !myPrs3d->GetResult())
+ return;
+
+ // get plane normal
+ int planeIndex = ComboBoxPlanes->currentItem();
+ OrientedPlane* plane = myPlanes[ planeIndex ].GetPointer();
+ vtkPlaneSource* planeSource = plane->myPlaneSource;
+ float * planeNormal = planeSource->GetNormal();
+ gp_Dir normal( planeNormal[0], planeNormal[1], planeNormal[2] );
+
+ // find index of an axis most co-directed with plane normal
+ int i, axId = 0;
+ double maxDot = 0;
+ const vector<float> *curValues, *values = 0;
+ VISU::Result_i* result = myPrs3d->GetResult();
+ for ( i = 0; i < 3; ++i ) {
+ VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) i;
+ gp_Dir dir;
+ curValues = result->GetAxisInfo(myPrs3d->GetMeshName(), axis, dir);
+ if ( curValues ) {
+ double dot = normal * dir;
+ if ( Abs( dot ) > Abs( maxDot )) {
+ maxDot = dot;
+ axId = i;
+ values = curValues;
+ }
+ }
+ }
+ // find index value
+// double v = SpinBoxDistance->value();
+// if ( reverse )
+// v = 1. - v;
+// for ( i = 0; i < values->size(); ++i )
+// if ( (*values)[ i ] > v )
+// break;
+// if ( i == values->size() ) --i;
+// cout << "maxDot: " << maxDot
+// << " axis: " << axId
+// << " index: " << i
+// << " planeNormal: " << planeNormal[0]<<" "<<planeNormal[1]<<" "<<planeNormal[2]
+// << endl;
+// if ( i != 0 && (*values)[ i ] - v > v - (*values)[ i - 1] ) {
+// --i;
+// cout << " Decrease index to " << i << endl;
+// }
+
+ // set control values
+ myIsSelectPlane = true;
+ CheckBoxIJKPlaneReverse->setChecked( false );
+ SpinBoxIJKIndex->setValue( 0 );
+ ButtonGroupIJKAxis->setButton( axId );
+ onIJKAxisChanged( axId );
+ myIsSelectPlane = false;
+
+ SetCurrentPlaneIJKParam();
+}
+
+//=======================================================================
+//function : isStructured
+//purpose : return true if mesh is structured
+//=======================================================================
+
+bool VisuGUI_ClippingDlg::isStructured() const
+{
+ VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
+ if ( result ) {
+ gp_Dir dir;
+ return result->GetAxisInfo(myPrs3d->GetMeshName(),
+ VISU::Result_i::AXIS_X,
+ dir);
+ }
+ return false;
+}
+
+//=======================================================================
+//function : onIJKAxisChanged
+//purpose : update Index range and call SetCurrentPlaneParam()
+//=======================================================================
+
+void VisuGUI_ClippingDlg::onIJKAxisChanged( int axisId )
+{
+ // set index range
+ int maxIndex = 0;
+ VISU::Result_i* result = myPrs3d ? myPrs3d->GetResult() : 0;
+ if ( result ) {
+ VISU::Result_i::TAxis axis = (VISU::Result_i::TAxis) axisId;
+ gp_Dir dir;
+ const vector<float> * indices = result->GetAxisInfo(myPrs3d->GetMeshName(),
+ axis, dir);
+ if ( indices )
+ maxIndex = indices->size() - 1;
+ }
+ QString text = "Index (from 0 to %1) ";
+ TextLabelIJKIndex->setText( text.arg( maxIndex ));
+ SpinBoxIJKIndex->setRange( 0, maxIndex );
+
+ if ( SpinBoxIJKIndex->value() > maxIndex )
+ SpinBoxIJKIndex->setValue( 0 );
+
+ SetCurrentPlaneIJKParam();
+}
+
//=======================================================================
// function : OnPreviewToggle()
// purpose :