From: ouv Date: Fri, 27 Jun 2014 13:20:10 +0000 (+0400) Subject: 0002109: External 20696 2D 3D surfaces X-Git-Tag: CTH_1_10_a~5 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=332149ec0e41410a834a768d20554dc98faac204;p=modules%2Fgui.git 0002109: External 20696 2D 3D surfaces Point 3: Fit range. --- diff --git a/adm_local/win32/Plot3d.vcproj b/adm_local/win32/Plot3d.vcproj index 9f77799b0..fcde70d74 100644 --- a/adm_local/win32/Plot3d.vcproj +++ b/adm_local/win32/Plot3d.vcproj @@ -578,6 +578,30 @@ /> + + + + + + + + + + #include +#include +#include #include #include +#include #include #include -#include #include #include #include #include #include #include +#include #include vtkStandardNewMacro(Plot3d_Actor); @@ -42,6 +48,31 @@ vtkStandardNewMacro(Plot3d_Actor); //============================================================================= Plot3d_Actor::Plot3d_Actor() { + // Pipeline + myWarpScalar = vtkWarpScalar::New(); + myWarpScalar->Delete(); + myWarpScalar->SetScaleFactor( 1 ); + + myImplicitBoolean = vtkImplicitBoolean::New(); + myImplicitBoolean->Delete(); + myImplicitBoolean->SetOperationTypeToIntersection(); + + for( int anIndex = 1; anIndex <= 6; anIndex++ ) + { + vtkSmartPointer aPlane = vtkPlane::New(); + aPlane->Delete(); + myImplicitBoolean->GetFunction()->AddItem( aPlane ); + } + + myExtractGeometry = SALOME_ExtractGeometry::New(); + myExtractGeometry->Delete(); + myExtractGeometry->SetImplicitFunction( myImplicitBoolean ); + myExtractGeometry->SetExtractInside( 1 ); + + myMapper = vtkDataSetMapper::New(); + myMapper->Delete(); + + // Other myColorDic = new Plot3d_ColorDic(); myIsGlobalColorDic = false; @@ -99,7 +130,16 @@ Plot3d_Actor::Plot3d_Actor() // Lookup table myLookupTable = vtkLookupTable::New(); + myLookupTable->Delete(); myLookupTable->SetHueRange( 0.667, 0.0 ); + + // Real (non-clipped) bounds + myRealBounds[0] = VTK_DOUBLE_MAX; + myRealBounds[1] = VTK_DOUBLE_MIN; + myRealBounds[2] = VTK_DOUBLE_MAX; + myRealBounds[3] = VTK_DOUBLE_MIN; + myRealBounds[4] = VTK_DOUBLE_MAX; + myRealBounds[5] = VTK_DOUBLE_MIN; } //============================================================================= @@ -113,8 +153,6 @@ Plot3d_Actor::~Plot3d_Actor() delete myColorDic; myColorDic = 0; } - - myLookupTable->Delete(); } //============================================================================= @@ -175,6 +213,68 @@ void Plot3d_Actor::RemoveFromRender( vtkRenderer* theRenderer ) Superclass::RemoveFromRender( theRenderer ); } +//============================================================================= +// Function : SetClippingPlanesEnabled +// Purpose : +//============================================================================= +void Plot3d_Actor::SetClippingPlanesEnabled( const bool theState ) +{ + if( theState ) + { + myWarpScalar->Update(); + myExtractGeometry->SetInput( myWarpScalar->GetPolyDataOutput() ); + myExtractGeometry->Update(); + myMapper->SetInput( myExtractGeometry->GetOutput() ); + } + else + myMapper->SetInput( myWarpScalar->GetPolyDataOutput() ); + SetMapper( myMapper ); + myMapper->Update(); +} + +//============================================================================= +// Function : SetClippingPlanes +// Purpose : +//============================================================================= +void Plot3d_Actor::SetClippingPlanes( const double theXMin, + const double theXMax, + const double theYMin, + const double theYMax, + const double theZMin, + const double theZMax ) +{ + if( vtkPlane* aPlaneXMin = vtkPlane::SafeDownCast( myImplicitBoolean->GetFunction()->GetItemAsObject( 0 ) ) ) + { + aPlaneXMin->SetNormal( -1, 0, 0 ); + aPlaneXMin->SetOrigin( theXMin, 0, 0 ); + } + if( vtkPlane* aPlaneXMax = vtkPlane::SafeDownCast( myImplicitBoolean->GetFunction()->GetItemAsObject( 1 ) ) ) + { + aPlaneXMax->SetNormal( 1, 0, 0 ); + aPlaneXMax->SetOrigin( theXMax, 0, 0 ); + } + if( vtkPlane* aPlaneYMin = vtkPlane::SafeDownCast( myImplicitBoolean->GetFunction()->GetItemAsObject( 2 ) ) ) + { + aPlaneYMin->SetNormal( 0, -1, 0 ); + aPlaneYMin->SetOrigin( 0, theYMin, 0 ); + } + if( vtkPlane* aPlaneYMax = vtkPlane::SafeDownCast( myImplicitBoolean->GetFunction()->GetItemAsObject( 3 ) ) ) + { + aPlaneYMax->SetNormal( 0, 1, 0 ); + aPlaneYMax->SetOrigin( 0, theYMax, 0 ); + } + if( vtkPlane* aPlaneZMin = vtkPlane::SafeDownCast( myImplicitBoolean->GetFunction()->GetItemAsObject( 4 ) ) ) + { + aPlaneZMin->SetNormal( 0, 0, -1 ); + aPlaneZMin->SetOrigin( 0, 0, theZMin ); + } + if( vtkPlane* aPlaneZMax = vtkPlane::SafeDownCast( myImplicitBoolean->GetFunction()->GetItemAsObject( 5 ) ) ) + { + aPlaneZMax->SetNormal( 0, 0, 1 ); + aPlaneZMax->SetOrigin( 0, 0, theZMax ); + } +} + //============================================================================= // Function : GetColorDic // Purpose : @@ -242,6 +342,13 @@ void Plot3d_Actor::Build( const int theNX, const double theMinValue, const double theMaxValue ) { + myRealBounds[0] = VTK_DOUBLE_MAX; + myRealBounds[1] = VTK_DOUBLE_MIN; + myRealBounds[2] = VTK_DOUBLE_MAX; + myRealBounds[3] = VTK_DOUBLE_MIN; + myRealBounds[4] = theMinValue; + myRealBounds[5] = theMaxValue; + vtkPolyData* aPointSet = vtkPolyData::New(); aPointSet->Allocate( ( theNX - 1 ) * ( theNY - 1 ) ); @@ -250,7 +357,14 @@ void Plot3d_Actor::Build( const int theNX, while( aPntIter.hasNext() ) { const QPointF& aPnt = aPntIter.next(); - aPoints->InsertNextPoint( aPnt.x(), aPnt.y(), 0 ); + double x = aPnt.x(); + double y = aPnt.y(); + aPoints->InsertNextPoint( x, y, 0 ); + + myRealBounds[0] = qMin( myRealBounds[0], x ); + myRealBounds[1] = qMax( myRealBounds[1], x ); + myRealBounds[2] = qMin( myRealBounds[2], y ); + myRealBounds[3] = qMax( myRealBounds[3], y ); } aPointSet->SetPoints( aPoints ); @@ -278,15 +392,12 @@ void Plot3d_Actor::Build( const int theNX, vtkPointData* aPointData = aPointSet->GetPointData(); aPointData->SetScalars( aFloatArray ); - vtkWarpScalar* aWarpScalar = vtkWarpScalar::New(); - aWarpScalar->SetInput( aPointSet ); - aWarpScalar->SetScaleFactor( 1 ); + myWarpScalar->SetInput( aPointSet ); - vtkPolyDataMapper* aMapper = vtkPolyDataMapper::New(); - aMapper->SetInput( aWarpScalar->GetPolyDataOutput() ); - aMapper->SetScalarRange( theMinValue, theMaxValue ); + myMapper->SetInput( myWarpScalar->GetPolyDataOutput() ); + myMapper->SetScalarRange( theMinValue, theMaxValue ); - SetMapper( aMapper ); + SetMapper( myMapper ); aPoints->Delete(); aFloatArray->Delete(); @@ -307,7 +418,7 @@ void Plot3d_Actor::RecomputeLookupTable() if( !aColorDic ) return; - vtkPolyDataMapper* aMapper = dynamic_cast( GetMapper() ); + vtkDataSetMapper* aMapper = dynamic_cast( GetMapper() ); if( !aMapper ) return; @@ -516,3 +627,17 @@ void Plot3d_Actor::SetTextColor( const QColor& theColor ) vtkTextProperty* aScalarBarLabelProp = myScalarBarActor->GetLabelTextProperty(); aScalarBarLabelProp->SetColor( theColor.redF(), theColor.greenF(), theColor.blueF() ); } + +//============================================================================= +// Function : GetRealBounds +// Purpose : +//============================================================================= +void Plot3d_Actor::GetRealBounds( double theBounds[6] ) +{ + theBounds[0] = myRealBounds[0]; + theBounds[1] = myRealBounds[1]; + theBounds[2] = myRealBounds[2]; + theBounds[3] = myRealBounds[3]; + theBounds[4] = myRealBounds[4]; + theBounds[5] = myRealBounds[5]; +} diff --git a/src/Plot3d/Plot3d_Actor.h b/src/Plot3d/Plot3d_Actor.h index aab2b4c38..8679574f1 100644 --- a/src/Plot3d/Plot3d_Actor.h +++ b/src/Plot3d/Plot3d_Actor.h @@ -28,9 +28,14 @@ #include #include +class vtkDataSetMapper; +class vtkImplicitBoolean; class vtkLookupTable; class vtkScalarBarActor; class vtkScalarBarWidget; +class vtkWarpScalar; + +class SALOME_ExtractGeometry; class Plot3d_ColorDic; @@ -48,13 +53,21 @@ public: Plot3d_Actor(); virtual ~Plot3d_Actor(); - virtual void AddToRender( vtkRenderer* theRender ); - virtual void RemoveFromRender(vtkRenderer* theRendere); + virtual void AddToRender( vtkRenderer* theRenderer ); + virtual void RemoveFromRender( vtkRenderer* theRenderer ); virtual void SetVisibility( int ); virtual void SetMapper( vtkMapper* theMapper ); + void SetClippingPlanesEnabled( const bool theState ); + void SetClippingPlanes( const double theXMin, + const double theXMax, + const double theYMin, + const double theYMax, + const double theZMin, + const double theZMax ); + Plot3d_ColorDic* GetColorDic(); void SetIsGlobalColorDic( const bool ); @@ -85,13 +98,22 @@ public: void SetTextColor( const QColor& theColor ); + void GetRealBounds( double theBounds[6] ); + protected: + vtkSmartPointer myWarpScalar; + + vtkSmartPointer myImplicitBoolean; + vtkSmartPointer myExtractGeometry; + + vtkSmartPointer myMapper; + Plot3d_ColorDic* myColorDic; bool myIsGlobalColorDic; Plot3d_ColorDic* myGlobalColorDic; - vtkLookupTable* myLookupTable; + vtkSmartPointer myLookupTable; vtkSmartPointer myScalarBarActor; vtkSmartPointer myScalarBarWg; @@ -102,6 +124,8 @@ protected: int myStartPoint; int myEndPoint; + + double myRealBounds[6]; }; #endif diff --git a/src/Plot3d/Plot3d_FitDataDlg.cxx b/src/Plot3d/Plot3d_FitDataDlg.cxx index dbd276a9e..db91fbf56 100644 --- a/src/Plot3d/Plot3d_FitDataDlg.cxx +++ b/src/Plot3d/Plot3d_FitDataDlg.cxx @@ -33,31 +33,27 @@ /*! Constructor */ -Plot3d_FitDataDlg::Plot3d_FitDataDlg( QWidget* parent, bool secondAxisY ) - : QDialog( parent ? parent : 0, - Qt::WindowTitleHint | Qt::WindowSystemMenuHint ), - myY2MinEdit( 0 ), myY2MaxEdit( 0 ), mySecondAxisY( secondAxisY ) +Plot3d_FitDataDlg::Plot3d_FitDataDlg( QWidget* theParent, bool theIs3D ) +: QDialog( theParent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ), + myIs3D( theIs3D ) { - setObjectName( "Plot3d_FitDataDlg" ); setModal( true ); setWindowTitle( tr( "FIT_DATA_TLT" ) ); - setSizeGripEnabled( TRUE ); - QGridLayout* topLayout = new QGridLayout( this ); - topLayout->setSpacing( SPACING_SIZE ); - topLayout->setMargin( MARGIN_SIZE ); + setSizeGripEnabled( true ); - // 'Range' group - myRangeGrp = new QGroupBox( this ); + QGridLayout* aTopLayout = new QGridLayout( this ); + aTopLayout->setSpacing( SPACING_SIZE ); + aTopLayout->setMargin( MARGIN_SIZE ); + + myRangeGrp = new QGroupBox( tr( "ENABLE" ), this ); + myRangeGrp->setCheckable( true ); + myRangeGrp->setChecked( false ); QGridLayout* aGridLayout = new QGridLayout( myRangeGrp ); myRangeGrp->setLayout( aGridLayout ); aGridLayout->setAlignment( Qt::AlignTop ); aGridLayout->setMargin( MARGIN_SIZE ); aGridLayout->setSpacing( SPACING_SIZE ); - myModeAllRB = new QRadioButton( tr( "FIT_ALL" ), myRangeGrp ); - myModeHorRB = new QRadioButton( tr( "FIT_HORIZONTAL" ), myRangeGrp ); - myModeVerRB = new QRadioButton( tr( "FIT_VERTICAL" ), myRangeGrp ); - QDoubleValidator* aValidator = new QDoubleValidator( this ); myXMinEdit = new QLineEdit( myRangeGrp ); myXMinEdit->setValidator( aValidator ); @@ -83,200 +79,132 @@ Plot3d_FitDataDlg::Plot3d_FitDataDlg( QWidget* parent, bool secondAxisY ) myYMaxEdit->setMinimumSize( MIN_EDIT_SIZE, 0 ); myYMaxEdit->setText( "0.0" ); - if (mySecondAxisY) { - myY2MinEdit = new QLineEdit( myRangeGrp ); - myY2MinEdit->setValidator( aValidator ); - myY2MinEdit->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - myY2MinEdit->setMinimumSize( MIN_EDIT_SIZE, 0 ); - myY2MinEdit->setText( "0.0" ); - - myY2MaxEdit = new QLineEdit( myRangeGrp ); - myY2MaxEdit->setValidator( aValidator ); - myY2MaxEdit->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - myY2MaxEdit->setMinimumSize( MIN_EDIT_SIZE, 0 ); - myY2MaxEdit->setText( "0.0" ); + if( myIs3D ) + { + myZMinEdit = new QLineEdit( myRangeGrp ); + myZMinEdit->setValidator( aValidator ); + myZMinEdit->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + myZMinEdit->setMinimumSize( MIN_EDIT_SIZE, 0 ); + myZMinEdit->setText( "0.0" ); + + myZMaxEdit = new QLineEdit( myRangeGrp ); + myZMaxEdit->setValidator( aValidator ); + myZMaxEdit->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + myZMaxEdit->setMinimumSize( MIN_EDIT_SIZE, 0 ); + myZMaxEdit->setText( "0.0" ); } - QFrame* aHLine = new QFrame( myRangeGrp ); - aHLine->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + myXLabel = new QLabel( tr( "X" ), myRangeGrp ); + myYLabel = new QLabel( tr( "Y" ), myRangeGrp ); - QHBoxLayout* aModeLayout = new QHBoxLayout; - aModeLayout->setMargin( 0 ); - aModeLayout->setSpacing( SPACING_SIZE ); - aModeLayout->addWidget( myModeAllRB ); - aModeLayout->addWidget( myModeHorRB ); - aModeLayout->addWidget( myModeVerRB ); + QFont font = myXLabel->font(); font.setBold( true ); + myXLabel->setFont( font ); myYLabel->setFont( font ); - QLabel* horLab = new QLabel( tr( "HORIZONTAL_AXIS" ), myRangeGrp ); - QLabel* verLab = new QLabel( tr( "VERTICAL_AXIS" ), myRangeGrp ); - if (mySecondAxisY) - verLab->setText( tr( "VERTICAL_LEFT_AXIS" ) ); - - QFont font = horLab->font(); font.setBold( true ); - horLab->setFont( font ); verLab->setFont( font ); - - aGridLayout->addLayout( aModeLayout, 0, 0, 1, 5 ); - aGridLayout->addWidget( aHLine, 1, 0, 1, 5 ); - aGridLayout->addWidget( horLab, 2, 0 ); + aGridLayout->addWidget( myXLabel, 0, 0 ); aGridLayout->addWidget( new QLabel( tr( "MIN_VALUE_LAB" ), myRangeGrp ), - 2, 1 ); - aGridLayout->addWidget( myXMinEdit, 2, 2 ); + 0, 1 ); + aGridLayout->addWidget( myXMinEdit, 0, 2 ); aGridLayout->addWidget( new QLabel( tr( "MAX_VALUE_LAB" ), myRangeGrp ), - 2, 3 ); - aGridLayout->addWidget( myXMaxEdit, 2, 4 ); - aGridLayout->addWidget( verLab, 3, 0 ); + 0, 3 ); + aGridLayout->addWidget( myXMaxEdit, 0, 4 ); + aGridLayout->addWidget( myYLabel, 1, 0 ); aGridLayout->addWidget( new QLabel( tr( "MIN_VALUE_LAB" ), myRangeGrp ), - 3, 1 ); - aGridLayout->addWidget( myYMinEdit, 3, 2 ); + 1, 1 ); + aGridLayout->addWidget( myYMinEdit, 1, 2 ); aGridLayout->addWidget( new QLabel( tr( "MAX_VALUE_LAB" ), myRangeGrp ), - 3, 3 ); - aGridLayout->addWidget( myYMaxEdit, 3, 4 ); - - if (mySecondAxisY) { - QLabel* ver2Lab = new QLabel(tr( "VERTICAL_RIGHT_AXIS" ), myRangeGrp ); - ver2Lab->setFont( font ); - aGridLayout->addWidget( ver2Lab, 4, 0 ); + 1, 3 ); + aGridLayout->addWidget( myYMaxEdit, 1, 4 ); + + myZLabel = 0; + if( myIs3D ) + { + myZLabel = new QLabel( tr( "Z" ), myRangeGrp ); + myZLabel->setFont( font ); + aGridLayout->addWidget( myZLabel, 2, 0 ); aGridLayout->addWidget( new QLabel( tr( "MIN_VALUE_LAB" ), myRangeGrp ), - 4, 1 ); - aGridLayout->addWidget( myY2MinEdit, 4, 2 ); + 2, 1 ); + aGridLayout->addWidget( myZMinEdit, 2, 2 ); aGridLayout->addWidget( new QLabel( tr( "MAX_VALUE_LAB" ), myRangeGrp ), - 4, 3 ); - aGridLayout->addWidget( myY2MaxEdit, 4, 4 ); + 2, 3 ); + aGridLayout->addWidget( myZMaxEdit, 2, 4 ); } - // OK/Cancel buttons myOkBtn = new QPushButton( tr( "BUT_OK" ), this ); - myOkBtn->setObjectName( "buttonOk" ); - myOkBtn->setAutoDefault( TRUE ); - myOkBtn->setDefault( TRUE ); + myOkBtn->setAutoDefault( true ); + myOkBtn->setDefault( true ); + myCancelBtn = new QPushButton( tr( "BUT_CANCEL" ), this ); - myCancelBtn->setObjectName( "buttonCancel" ); - myCancelBtn->setAutoDefault( TRUE ); + myCancelBtn->setAutoDefault( true ); - topLayout->addWidget( myRangeGrp, 0, 0, 1, 3 ); - topLayout->addWidget( myOkBtn, 1, 0 ); - topLayout->setColumnStretch( 1, 5 ); - topLayout->addWidget( myCancelBtn, 1, 2 ); + aTopLayout->addWidget( myRangeGrp, 0, 0, 1, 3 ); + aTopLayout->addWidget( myOkBtn, 1, 0 ); + aTopLayout->setColumnStretch( 1, 5 ); + aTopLayout->addWidget( myCancelBtn, 1, 2 ); // connect signals - connect( myOkBtn, SIGNAL( clicked() ), this, SLOT( accept() ) ); - connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); - connect( myRangeGrp, SIGNAL( clicked( int ) ), this, SLOT( onModeChanged( int ) ) ); + connect( myOkBtn, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); +} - // initial state - myModeAllRB->setChecked( true ); - onModeChanged( 0 ); +/*! + Sets axis titles +*/ +void Plot3d_FitDataDlg::setAxisTitles( const QString& theXTitle, + const QString& theYTitle, + const QString& theZTitle ) +{ + myXLabel->setText( theXTitle ); + myYLabel->setText( theYTitle ); + myZLabel->setText( theZTitle ); } /*! Sets range */ -void Plot3d_FitDataDlg::setRange( const double xMin, +void Plot3d_FitDataDlg::setRange( const bool theIsEnabled, + const double xMin, const double xMax, const double yMin, const double yMax, - const double y2Min, - const double y2Max) + const double zMin, + const double zMax ) { + myRangeGrp->setChecked( theIsEnabled ); myXMinEdit->setText( QString::number( xMin ) ); myXMaxEdit->setText( QString::number( xMax ) ); myYMinEdit->setText( QString::number( yMin ) ); myYMaxEdit->setText( QString::number( yMax ) ); - if (mySecondAxisY) { - myY2MinEdit->setText( QString::number( y2Min ) ); - myY2MaxEdit->setText( QString::number( y2Max ) ); + if( myIs3D ) + { + myZMinEdit->setText( QString::number( zMin ) ); + myZMaxEdit->setText( QString::number( zMax ) ); } } /*! - Gets range, returns mode (see getMode()) + Gets range */ -int Plot3d_FitDataDlg::getRange( double& xMin, - double& xMax, - double& yMin, - double& yMax, - double& y2Min, - double& y2Max) +void Plot3d_FitDataDlg::getRange( bool& theIsEnabled, + double& xMin, + double& xMax, + double& yMin, + double& yMax, + double& zMin, + double& zMax ) { + theIsEnabled = myRangeGrp->isChecked(); xMin = myXMinEdit->text().toDouble(); xMax = myXMaxEdit->text().toDouble(); yMin = myYMinEdit->text().toDouble(); yMax = myYMaxEdit->text().toDouble(); - if (mySecondAxisY) { - y2Min = myY2MinEdit->text().toDouble(); - y2Max = myY2MaxEdit->text().toDouble(); + if( myIs3D ) + { + zMin = myZMinEdit->text().toDouble(); + zMax = myZMaxEdit->text().toDouble(); } - else { - y2Min = 0; - y2Max = 0; - } - int myMode = 0; - if ( myModeAllRB->isChecked() ) - myMode = 0; - if ( myModeHorRB->isChecked() ) - myMode = 1; - if ( myModeVerRB->isChecked() ) - myMode = 2; - return myMode; -} - -/*! - Gets mode : 0 - Fit all; 1 - Fit horizontal, 2 - Fit vertical -*/ -int Plot3d_FitDataDlg::getMode() -{ - int myMode = 0; - if ( myModeAllRB->isChecked() ) - myMode = 0; - if ( myModeHorRB->isChecked() ) - myMode = 1; - if ( myModeVerRB->isChecked() ) - myMode = 2; - return myMode; -} - -/*! - Called when range mode changed -*/ -void Plot3d_FitDataDlg::onModeChanged(int mode) -{ - bool badFocus; - switch( mode ) { - case 0: // fit all mode - myXMinEdit->setEnabled(true); - myXMaxEdit->setEnabled(true); - myYMinEdit->setEnabled(true); - myYMaxEdit->setEnabled(true); - if (mySecondAxisY) { - myY2MinEdit->setEnabled(true); - myY2MaxEdit->setEnabled(true); - } - break; - case 1: // fit horizontal mode - badFocus = myYMinEdit->hasFocus() || myYMaxEdit->hasFocus(); - myXMinEdit->setEnabled(true); - myXMaxEdit->setEnabled(true); - myYMinEdit->setEnabled(false); - myYMaxEdit->setEnabled(false); - if (mySecondAxisY) { - myY2MinEdit->setEnabled(false); - myY2MaxEdit->setEnabled(false); - } - if (badFocus) - myXMinEdit->setFocus(); - break; - case 2: // fit vertical mode - badFocus = myXMinEdit->hasFocus() || myXMaxEdit->hasFocus(); - myXMinEdit->setEnabled(false); - myXMaxEdit->setEnabled(false); - myYMinEdit->setEnabled(true); - myYMaxEdit->setEnabled(true); - if (mySecondAxisY) { - myY2MinEdit->setEnabled(true); - myY2MaxEdit->setEnabled(true); - } - if (badFocus) - myYMinEdit->setFocus(); - break; + else + { + zMin = 0; + zMax = 0; } } diff --git a/src/Plot3d/Plot3d_FitDataDlg.h b/src/Plot3d/Plot3d_FitDataDlg.h index e9104d28a..c9f9db3d2 100644 --- a/src/Plot3d/Plot3d_FitDataDlg.h +++ b/src/Plot3d/Plot3d_FitDataDlg.h @@ -24,7 +24,7 @@ #include class QGroupBox; -class QRadioButton; +class QLabel; class QLineEdit; class QPushButton; @@ -33,44 +33,47 @@ class PLOT3D_EXPORT Plot3d_FitDataDlg : public QDialog Q_OBJECT public: -// constuctor - Plot3d_FitDataDlg( QWidget* parent, bool secondAxisY ); + Plot3d_FitDataDlg( QWidget* theParent, bool theIs3D ); -// sets range - void setRange(const double xMin, - const double xMax, - const double yMin, - const double yMax, - const double y2Min = 0, - const double y2Max = 0); -// gets range, returns mode (see getMode()) - int getRange(double& xMin, - double& xMax, - double& yMin, - double& yMax, - double& y2Min, - double& y2Max); -// gets mode : 0 - Fit all; 1 - Fit horizontal, 2 - Fit vertical - int getMode(); + void setAxisTitles( const QString& theXTitle, + const QString& theYTitle, + const QString& theZTitle ); -protected slots: -// called when range mode changed - void onModeChanged(int); + void setRange( const bool theIsEnabled, + const double xMin, + const double xMax, + const double yMin, + const double yMax, + const double zMin = 0, + const double zMax = 0 ); + + void getRange( bool& theIsEnabled, + double& xMin, + double& xMax, + double& yMin, + double& yMax, + double& zMin, + double& zMax ); private: QGroupBox* myRangeGrp; - QRadioButton* myModeAllRB; - QRadioButton* myModeHorRB; - QRadioButton* myModeVerRB; + + QLabel* myXLabel; QLineEdit* myXMinEdit; - QLineEdit* myYMinEdit; - QLineEdit* myY2MinEdit; QLineEdit* myXMaxEdit; + + QLabel* myYLabel; + QLineEdit* myYMinEdit; QLineEdit* myYMaxEdit; - QLineEdit* myY2MaxEdit; + + QLabel* myZLabel; + QLineEdit* myZMinEdit; + QLineEdit* myZMaxEdit; + QPushButton* myOkBtn; QPushButton* myCancelBtn; - bool mySecondAxisY; + + bool myIs3D; }; #endif diff --git a/src/Plot3d/Plot3d_ViewWindow.cxx b/src/Plot3d/Plot3d_ViewWindow.cxx index 6b8e7a02d..57561d443 100644 --- a/src/Plot3d/Plot3d_ViewWindow.cxx +++ b/src/Plot3d/Plot3d_ViewWindow.cxx @@ -110,6 +110,16 @@ Plot3d_ViewWindow::Plot3d_ViewWindow( SUIT_Desktop* theDesktop ): myLookupTable->ForceBuild(); myScalarBarActor->SetLookupTable( myLookupTable ); + + // Fit data parameters + myIsFitDataInitialized = false; + myIsFitDataEnabled = false; + myFitDataBounds[0] = 0; + myFitDataBounds[1] = -1; + myFitDataBounds[2] = 0; + myFitDataBounds[3] = -1; + myFitDataBounds[4] = 0; + myFitDataBounds[5] = -1; } /*! @@ -159,9 +169,7 @@ void Plot3d_ViewWindow::Initialize( SVTK_ViewModelBase* theModel ) void Plot3d_ViewWindow::contextMenuPopup( QMenu* thePopup ) { thePopup->addAction( tr( "MNU_PLOT3D_SURFACES_SETTINGS" ), this, SLOT( onSurfacesSettings() ) ); - - if( myMode2D ) - thePopup->addAction( tr( "FIT_RANGE" ), this, SLOT( onFitData() ) ); + thePopup->addAction( tr( "MNU_PLOT3D_FIT_RANGE" ), this, SLOT( onFitData() ) ); } /*! @@ -481,40 +489,8 @@ void Plot3d_ViewWindow::onSurfacesSettings() } UpdateScalarBar( false ); - - vtkFloatingPointType aGlobalBounds[6] = { VTK_DOUBLE_MAX, VTK_DOUBLE_MIN, - VTK_DOUBLE_MAX, VTK_DOUBLE_MIN, - VTK_DOUBLE_MAX, VTK_DOUBLE_MIN }; - - for ( i = 0, aSurfIter = aSurfaces.begin(); aSurfIter != aSurfaces.end(); ++aSurfIter, ++i ) - { - if( Plot3d_Actor* aSurface = *aSurfIter ) - { - vtkFloatingPointType aBounds[6]; - aSurface->GetBounds( aBounds ); - aGlobalBounds[0] = qMin( aGlobalBounds[0], aBounds[0] ); - aGlobalBounds[1] = qMax( aGlobalBounds[1], aBounds[1] ); - aGlobalBounds[2] = qMin( aGlobalBounds[2], aBounds[2] ); - aGlobalBounds[3] = qMax( aGlobalBounds[3], aBounds[3] ); - aGlobalBounds[4] = qMin( aGlobalBounds[4], aBounds[4] ); - aGlobalBounds[5] = qMax( aGlobalBounds[5], aBounds[5] ); - } - } - - double aDX = aGlobalBounds[1] - aGlobalBounds[0]; - double aDY = aGlobalBounds[3] - aGlobalBounds[2]; - double aDZ = aGlobalBounds[5] - aGlobalBounds[4]; - - double aScale[3]; - GetScale( aScale ); // take into account the current scale - aDX = fabs( aScale[0] ) > DBL_EPSILON ? aDX / aScale[0] : aDX; - aDY = fabs( aScale[1] ) > DBL_EPSILON ? aDY / aScale[1] : aDY; - aDZ = fabs( aScale[2] ) > DBL_EPSILON ? aDZ / aScale[2] : aDZ; - - aScale[0] = fabs( aDX ) > DBL_EPSILON ? 1.0 / aDX : 1.0; - aScale[1] = fabs( aDY ) > DBL_EPSILON ? 1.0 / aDY : 1.0; - aScale[2] = fabs( aDZ ) > DBL_EPSILON ? 1.0 / aDZ : 1.0; - SetScale( aScale, false ); + UpdateFitData( false ); + NormalizeSurfaces( false ); onFitAll(); } @@ -532,7 +508,110 @@ void Plot3d_ViewWindow::onMergeScalarBars( bool theOn ) */ void Plot3d_ViewWindow::onFitData() { - // to do + vtkRenderer* aRenderer = getRenderer(); + if( !aRenderer ) + return; + + QList< Plot3d_Actor* > aSurfaces; + VTK::ActorCollectionCopy aCopy( aRenderer->GetActors() ); + vtkActorCollection* aCollection = aCopy.GetActors(); + aCollection->InitTraversal(); + while( vtkActor* anActor = aCollection->GetNextActor() ) + if( Plot3d_Actor* aSurface = dynamic_cast( anActor ) ) + aSurfaces << aSurface; + + if( aSurfaces.isEmpty() ) + { + SUIT_MessageBox::warning( this, tr( "WARNING" ), tr( "NO_OBJECTS_TO_FIT" ) ); + return; + } + + // check that the bounds are not yet initialized + if( !myIsFitDataInitialized/* || + myFitDataBounds[1] < myFitDataBounds[0] || + myFitDataBounds[3] < myFitDataBounds[2] || + myFitDataBounds[5] < myFitDataBounds[4]*/ ) + { + myFitDataBounds[0] = VTK_DOUBLE_MAX; + myFitDataBounds[1] = VTK_DOUBLE_MIN; + myFitDataBounds[2] = VTK_DOUBLE_MAX; + myFitDataBounds[3] = VTK_DOUBLE_MIN; + myFitDataBounds[4] = VTK_DOUBLE_MAX; + myFitDataBounds[5] = VTK_DOUBLE_MIN; + + QListIterator< Plot3d_Actor* > anIter( aSurfaces ); + while( anIter.hasNext() ) + { + if( Plot3d_Actor* aSurface = anIter.next() ) + { + vtkFloatingPointType aBounds[6]; + aSurface->GetBounds( aBounds ); + myFitDataBounds[0] = qMin( myFitDataBounds[0], aBounds[0] ); + myFitDataBounds[1] = qMax( myFitDataBounds[1], aBounds[1] ); + myFitDataBounds[2] = qMin( myFitDataBounds[2], aBounds[2] ); + myFitDataBounds[3] = qMax( myFitDataBounds[3], aBounds[3] ); + myFitDataBounds[4] = qMin( myFitDataBounds[4], aBounds[4] ); + myFitDataBounds[5] = qMax( myFitDataBounds[5], aBounds[5] ); + } + } + + double aScale[3]; + GetScale( aScale ); // take into account the current scale + myFitDataBounds[0] = fabs( aScale[0] ) > DBL_EPSILON ? myFitDataBounds[0] / aScale[0] : myFitDataBounds[0]; + myFitDataBounds[1] = fabs( aScale[0] ) > DBL_EPSILON ? myFitDataBounds[1] / aScale[0] : myFitDataBounds[1]; + myFitDataBounds[2] = fabs( aScale[1] ) > DBL_EPSILON ? myFitDataBounds[2] / aScale[1] : myFitDataBounds[2]; + myFitDataBounds[3] = fabs( aScale[1] ) > DBL_EPSILON ? myFitDataBounds[3] / aScale[1] : myFitDataBounds[3]; + myFitDataBounds[4] = fabs( aScale[2] ) > DBL_EPSILON ? myFitDataBounds[4] / aScale[2] : myFitDataBounds[4]; + myFitDataBounds[5] = fabs( aScale[2] ) > DBL_EPSILON ? myFitDataBounds[5] / aScale[2] : myFitDataBounds[5]; + + myIsFitDataInitialized = true; + } + + Plot3d_FitDataDlg aDlg( this, !myMode2D ); + + if( SVTK_CubeAxesActor2D* aCubeAxes = GetRenderer()->GetCubeAxes() ) + { + if( aCubeAxes->GetVisibility() ) + { + vtkAxisActor2D* aXAxis = aCubeAxes->GetXAxisActor2D(); + vtkAxisActor2D* aYAxis = aCubeAxes->GetYAxisActor2D(); + vtkAxisActor2D* aZAxis = aCubeAxes->GetZAxisActor2D(); + if( aXAxis && aYAxis && aZAxis ) + aDlg.setAxisTitles( aXAxis->GetTitle(), + aYAxis->GetTitle(), + aZAxis->GetTitle() ); + } + } + + aDlg.setRange( myIsFitDataEnabled, + myFitDataBounds[0], + myFitDataBounds[1], + myFitDataBounds[2], + myFitDataBounds[3], + myFitDataBounds[4], + myFitDataBounds[5] ); + + if( aDlg.exec() == QDialog::Accepted ) + { + double aZMin = 0, aZMax = 0; + aDlg.getRange( myIsFitDataEnabled, + myFitDataBounds[0], + myFitDataBounds[1], + myFitDataBounds[2], + myFitDataBounds[3], + aZMin, + aZMax ); + + if( !myMode2D ) + { + myFitDataBounds[4] = aZMin; + myFitDataBounds[5] = aZMax; + } + + UpdateFitData( false ); + NormalizeSurfaces( false ); + onFitAll(); + } } /*! @@ -684,3 +763,101 @@ void Plot3d_ViewWindow::UpdateScalarBar( const bool theIsRepaint ) if( theIsRepaint ) Repaint(); } + +/*! + Apply fit data bounds to all displayed actors +*/ +void Plot3d_ViewWindow::UpdateFitData( const bool theIsRepaint ) +{ + if( !myIsFitDataInitialized ) + return; + + vtkRenderer* aRenderer = getRenderer(); + if( !aRenderer ) + return; + + QList< Plot3d_Actor* > aSurfaces; + VTK::ActorCollectionCopy aCopy( aRenderer->GetActors() ); + vtkActorCollection* aCollection = aCopy.GetActors(); + aCollection->InitTraversal(); + while( vtkActor* anActor = aCollection->GetNextActor() ) + if( Plot3d_Actor* aSurface = dynamic_cast( anActor ) ) + aSurfaces << aSurface; + + if( aSurfaces.isEmpty() ) + { + myIsFitDataInitialized = false; + myIsFitDataEnabled = false; + return; + } + + QListIterator< Plot3d_Actor* > anIter( aSurfaces ); + while( anIter.hasNext() ) + { + if( Plot3d_Actor* aSurface = anIter.next() ) + { + aSurface->SetClippingPlanes( myFitDataBounds[0], + myFitDataBounds[1], + myFitDataBounds[2], + myFitDataBounds[3], + myFitDataBounds[4], + myFitDataBounds[5] ); + aSurface->SetClippingPlanesEnabled( myIsFitDataEnabled ); + } + } + + if( theIsRepaint ) + Repaint(); +} + +/*! + Arrange the view scale to normalize the displayed surfaces +*/ +void Plot3d_ViewWindow::NormalizeSurfaces( const bool theIsRepaint ) +{ + vtkRenderer* aRenderer = getRenderer(); + if( !aRenderer ) + return; + + vtkFloatingPointType aGlobalBounds[6] = { VTK_DOUBLE_MAX, VTK_DOUBLE_MIN, + VTK_DOUBLE_MAX, VTK_DOUBLE_MIN, + VTK_DOUBLE_MAX, VTK_DOUBLE_MIN }; + + VTK::ActorCollectionCopy aCopy( aRenderer->GetActors() ); + vtkActorCollection* aCollection = aCopy.GetActors(); + aCollection->InitTraversal(); + while( vtkActor* anActor = aCollection->GetNextActor() ) + { + if( Plot3d_Actor* aSurface = dynamic_cast( anActor ) ) + { + vtkFloatingPointType aBounds[6]; + //aSurface->GetRealBounds( aBounds ); + aSurface->GetBounds( aBounds ); + aGlobalBounds[0] = qMin( aGlobalBounds[0], aBounds[0] ); + aGlobalBounds[1] = qMax( aGlobalBounds[1], aBounds[1] ); + aGlobalBounds[2] = qMin( aGlobalBounds[2], aBounds[2] ); + aGlobalBounds[3] = qMax( aGlobalBounds[3], aBounds[3] ); + aGlobalBounds[4] = qMin( aGlobalBounds[4], aBounds[4] ); + aGlobalBounds[5] = qMax( aGlobalBounds[5], aBounds[5] ); + } + } + + double aDX = aGlobalBounds[1] - aGlobalBounds[0]; + double aDY = aGlobalBounds[3] - aGlobalBounds[2]; + double aDZ = aGlobalBounds[5] - aGlobalBounds[4]; + + double aScale[3]; + + GetScale( aScale ); // take into account the current scale + aDX = fabs( aScale[0] ) > DBL_EPSILON ? aDX / aScale[0] : aDX; + aDY = fabs( aScale[1] ) > DBL_EPSILON ? aDY / aScale[1] : aDY; + aDZ = fabs( aScale[2] ) > DBL_EPSILON ? aDZ / aScale[2] : aDZ; + + aScale[0] = fabs( aDX ) > DBL_EPSILON ? 1.0 / aDX : 1.0; + aScale[1] = fabs( aDY ) > DBL_EPSILON ? 1.0 / aDY : 1.0; + aScale[2] = fabs( aDZ ) > DBL_EPSILON ? 1.0 / aDZ : 1.0; + SetScale( aScale, false ); + + if( theIsRepaint ) + Repaint(); +} diff --git a/src/Plot3d/Plot3d_ViewWindow.h b/src/Plot3d/Plot3d_ViewWindow.h index d55b4c408..18ce20042 100644 --- a/src/Plot3d/Plot3d_ViewWindow.h +++ b/src/Plot3d/Plot3d_ViewWindow.h @@ -57,6 +57,10 @@ public: vtkSmartPointer GetScalarBarActor() const; void UpdateScalarBar( const bool theIsRepaint = true ); + void UpdateFitData( const bool theIsRepaint = true ); + + void NormalizeSurfaces( const bool theIsRepaint = true ); + public slots: void onMode2D( bool theOn ); void onSurfacesSettings(); @@ -99,6 +103,10 @@ protected: vtkSmartPointer myScalarBarActor; vtkSmartPointer myScalarBarWg; bool myToDisplayScalarBar; + + bool myIsFitDataInitialized; + bool myIsFitDataEnabled; + double myFitDataBounds[6]; }; #endif diff --git a/src/Plot3d/SALOME_ExtractGeometry.cxx b/src/Plot3d/SALOME_ExtractGeometry.cxx new file mode 100644 index 000000000..a42f959c4 --- /dev/null +++ b/src/Plot3d/SALOME_ExtractGeometry.cxx @@ -0,0 +1,391 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SALOME_ExtractGeometry.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#if defined __GNUC__ + #if __GNUC__ == 2 + #define __GNUC_2__ + #endif +#endif + +#define TOLERANCE 1e-3 // selected empirically + +//---------------------------------------------------------------------------- +vtkStandardNewMacro(SALOME_ExtractGeometry); + + +//---------------------------------------------------------------------------- +SALOME_ExtractGeometry +::SALOME_ExtractGeometry(): + myStoreMapping(false), + myIsDoneShallowCopy(false) +{} + +SALOME_ExtractGeometry +::~SALOME_ExtractGeometry() +{} + + +//---------------------------------------------------------------------------- +vtkImplicitBoolean* +SALOME_ExtractGeometry +::GetImplicitBoolean() +{ + return myImplicitBoolean.GetPointer(); +} + + +void +SALOME_ExtractGeometry +::SetImplicitFunction(vtkImplicitFunction* theImplicitFunction) +{ + myImplicitBoolean = dynamic_cast(theImplicitFunction); + Superclass::SetImplicitFunction(theImplicitFunction); +} + + +//---------------------------------------------------------------------------- +void +SALOME_ExtractGeometry +::SetStoreMapping(bool theStoreMapping) +{ + if(myStoreMapping != theStoreMapping){ + myStoreMapping = theStoreMapping; + Modified(); + } +} + +bool +SALOME_ExtractGeometry +::GetStoreMapping() const +{ + return myStoreMapping; +} + + +//---------------------------------------------------------------------------- +vtkIdType +SALOME_ExtractGeometry +::GetElemVTKId(vtkIdType theID) +{ + if(!myStoreMapping || myIsDoneShallowCopy) + return theID; + + vtkIdType iEnd = myElemVTK2ObjIds.size(); + for(vtkIdType i = 0; i < iEnd; i++) + if(myElemVTK2ObjIds[i] == theID) + return i; + + return -1; +} + +vtkIdType +SALOME_ExtractGeometry +::GetNodeVTKId(vtkIdType theID) +{ + if(!myStoreMapping || myIsDoneShallowCopy) + return theID; + + vtkIdType iEnd = myNodeVTK2ObjIds.size(); + for(vtkIdType i = 0; i < iEnd; i++) + if(myNodeVTK2ObjIds[i] == theID) + return i; + + return -1; +} + + +//---------------------------------------------------------------------------- +vtkIdType +SALOME_ExtractGeometry +::GetElemObjId(vtkIdType theVtkID) +{ + if(!myStoreMapping || myIsDoneShallowCopy) + return theVtkID; + + if(theVtkID < (vtkIdType)myElemVTK2ObjIds.size()) + return myElemVTK2ObjIds[theVtkID]; + + return -1; +} + + +vtkIdType +SALOME_ExtractGeometry +::GetNodeObjId(vtkIdType theVtkID) +{ + if(!myStoreMapping || myIsDoneShallowCopy) + return theVtkID; + + if(theVtkID < (vtkIdType)myNodeVTK2ObjIds.size()) + return myNodeVTK2ObjIds[theVtkID]; + + return -1; +} + + +//---------------------------------------------------------------------------- +int +SALOME_ExtractGeometry +::RequestData(vtkInformation *request, + vtkInformationVector **inputVector, + vtkInformationVector *outputVector) +{ + // get the info objects + vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); + vtkInformation *outInfo = outputVector->GetInformationObject(0); + + // get the input and ouptut + vtkDataSet *input = vtkDataSet::SafeDownCast( + inInfo->Get(vtkDataObject::DATA_OBJECT())); + vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast( + outInfo->Get(vtkDataObject::DATA_OBJECT())); + + myElemVTK2ObjIds.clear(); + myNodeVTK2ObjIds.clear(); + // + myIsDoneShallowCopy = !this->ImplicitFunction; + + if(!myIsDoneShallowCopy && myImplicitBoolean.GetPointer()) + if(vtkImplicitFunctionCollection* aFunction = myImplicitBoolean->GetFunction()) + myIsDoneShallowCopy = aFunction->GetNumberOfItems() == 0; + + if(myIsDoneShallowCopy){ + output->ShallowCopy(input); + return 1; + } + + return RequestData2(request,inputVector,outputVector); +} + + +//---------------------------------------------------------------------------- +int +SALOME_ExtractGeometry +::RequestData2(vtkInformation *vtkNotUsed(request), + vtkInformationVector **inputVector, + vtkInformationVector *outputVector) +{ + // get the info objects + vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); + vtkInformation *outInfo = outputVector->GetInformationObject(0); + + // get the input and ouptut + vtkDataSet *input = vtkDataSet::SafeDownCast( + inInfo->Get(vtkDataObject::DATA_OBJECT())); + vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast( + outInfo->Get(vtkDataObject::DATA_OBJECT())); + + vtkIdType ptId, numPts, numCells, i, cellId, newCellId, newId, *pointMap; + vtkIdList *cellPts; + vtkCell *cell; + int numCellPts; + vtkFloatingPointType *x; + vtkFloatingPointType multiplier; + vtkPoints *newPts; + vtkIdList *newCellPts; + vtkPointData *pd = input->GetPointData(); + vtkCellData *cd = input->GetCellData(); + vtkPointData *outputPD = output->GetPointData(); + vtkCellData *outputCD = output->GetCellData(); + int npts; + numCells = input->GetNumberOfCells(); + numPts = input->GetNumberOfPoints(); + + if ( ! this->ImplicitFunction ) + { + vtkErrorMacro(<<"No implicit function specified"); + return 0; + } + + newCellPts = vtkIdList::New(); + newCellPts->Allocate(VTK_CELL_SIZE); + + if ( this->ExtractInside ) + { + multiplier = 1.0; + } + else + { + multiplier = -1.0; + } + + // Loop over all points determining whether they are inside the + // implicit function. Copy the points and point data if they are. + // + pointMap = new vtkIdType[numPts]; // maps old point ids into new + for (i=0; i < numPts; i++) + { + pointMap[i] = -1; + } + + output->Allocate(numCells/4); //allocate storage for geometry/topology + newPts = vtkPoints::New(); + newPts->Allocate(numPts/4,numPts); + outputPD->CopyAllocate(pd); + outputCD->CopyAllocate(cd); + vtkFloatArray *newScalars = NULL; + + if(myStoreMapping){ + myElemVTK2ObjIds.reserve(numCells); + myNodeVTK2ObjIds.reserve(numPts); + } + + if ( ! this->ExtractBoundaryCells ) + { + for ( ptId=0; ptId < numPts; ptId++ ) + { + x = input->GetPoint(ptId); + // Value 0.0 below has replaced with TOLERANCE (to extract the points, + // which have a negative value or a value close enough to zero). + if ( (this->ImplicitFunction->FunctionValue(x)*multiplier) < TOLERANCE ) // 0.0 + { + newId = newPts->InsertNextPoint(x); + pointMap[ptId] = newId; + if(myStoreMapping) + myNodeVTK2ObjIds.push_back(ptId); + outputPD->CopyData(pd,ptId,newId); + } + } + } + else + { + // To extract boundary cells, we have to create supplemental information + if ( this->ExtractBoundaryCells ) + { + vtkFloatingPointType val; + newScalars = vtkFloatArray::New(); + newScalars->SetNumberOfValues(numPts); + + for (ptId=0; ptId < numPts; ptId++ ) + { + x = input->GetPoint(ptId); + val = this->ImplicitFunction->FunctionValue(x) * multiplier; + newScalars->SetValue(ptId, val); + if ( val < 0.0 ) + { + newId = newPts->InsertNextPoint(x); + pointMap[ptId] = newId; + if(myStoreMapping) + myNodeVTK2ObjIds.push_back(ptId); + outputPD->CopyData(pd,ptId,newId); + } + } + } + } + + // Now loop over all cells to see whether they are inside implicit + // function (or on boundary if ExtractBoundaryCells is on). + // + for (cellId=0; cellId < numCells; cellId++) + { + cell = input->GetCell(cellId); + cellPts = cell->GetPointIds(); + numCellPts = cell->GetNumberOfPoints(); + + newCellPts->Reset(); + if ( ! this->ExtractBoundaryCells ) //requires less work + { + for ( npts=0, i=0; i < numCellPts; i++, npts++) + { + ptId = cellPts->GetId(i); + if ( pointMap[ptId] < 0 ) + { + break; //this cell won't be inserted + } + else + { + newCellPts->InsertId(i,pointMap[ptId]); + } + } + } //if don't want to extract boundary cells + + else //want boundary cells + { + for ( npts=0, i=0; i < numCellPts; i++ ) + { + ptId = cellPts->GetId(i); + if ( newScalars->GetValue(ptId) <= 0.0 ) + { + npts++; + } + } + if ( npts > 0 ) + { + for ( i=0; i < numCellPts; i++ ) + { + ptId = cellPts->GetId(i); + if ( pointMap[ptId] < 0 ) + { + x = input->GetPoint(ptId); + newId = newPts->InsertNextPoint(x); + pointMap[ptId] = newId; + if(myStoreMapping) + myNodeVTK2ObjIds.push_back(ptId); + outputPD->CopyData(pd,ptId,newId); + } + newCellPts->InsertId(i,pointMap[ptId]); + } + }//a boundary or interior cell + }//if mapping boundary cells + + if ( npts >= numCellPts || (this->ExtractBoundaryCells && npts > 0) ) + { + newCellId = output->InsertNextCell(cell->GetCellType(),newCellPts); + if(myStoreMapping) + myElemVTK2ObjIds.push_back(cellId); + outputCD->CopyData(cd,cellId,newCellId); + } + }//for all cells + + // Update ourselves and release memory + // + delete [] pointMap; + newCellPts->Delete(); + output->SetPoints(newPts); + newPts->Delete(); + + if ( this->ExtractBoundaryCells ) + { + newScalars->Delete(); + } + + output->Squeeze(); + + return 1; +} diff --git a/src/Plot3d/SALOME_ExtractGeometry.h b/src/Plot3d/SALOME_ExtractGeometry.h new file mode 100644 index 000000000..e0d827346 --- /dev/null +++ b/src/Plot3d/SALOME_ExtractGeometry.h @@ -0,0 +1,100 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef SALOME_ExtractGeometry_H +#define SALOME_ExtractGeometry_H + +#include "Plot3d.h" + +#include +#include + +#include + +class vtkImplicitBoolean; + +class PLOT3D_EXPORT SALOME_ExtractGeometry : public vtkExtractGeometry +{ +public: + vtkTypeMacro(SALOME_ExtractGeometry, vtkExtractGeometry); + + static + SALOME_ExtractGeometry* + New(); + + virtual + void + SetImplicitFunction(vtkImplicitFunction* theImplicitFunction); + + vtkImplicitBoolean* + GetImplicitBoolean(); + + bool + GetStoreMapping() const; + + void + SetStoreMapping(bool theStoreMapping); + + virtual + vtkIdType + GetNodeObjId(vtkIdType theID); + + virtual + vtkIdType + GetElemObjId(vtkIdType theID); + + virtual + vtkIdType + GetNodeVTKId(vtkIdType theID); + + virtual + vtkIdType + GetElemVTKId(vtkIdType theID); + +protected: + SALOME_ExtractGeometry(); + ~SALOME_ExtractGeometry(); + + // Usual data generation method + virtual + int + RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + + virtual + int + RequestData2(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + +private: + bool myStoreMapping; + bool myIsDoneShallowCopy; + + typedef std::vector TVectorId; + TVectorId myElemVTK2ObjIds; + TVectorId myNodeVTK2ObjIds; + + vtkSmartPointer myImplicitBoolean; + + SALOME_ExtractGeometry(const SALOME_ExtractGeometry&); // Not implemented. + void operator=(const SALOME_ExtractGeometry&); // Not implemented. +}; + +#endif diff --git a/src/Plot3d/resources/Plot3d_msg_en.ts b/src/Plot3d/resources/Plot3d_msg_en.ts index 3cc3c51fd..35e941a55 100644 --- a/src/Plot3d/resources/Plot3d_msg_en.ts +++ b/src/Plot3d/resources/Plot3d_msg_en.ts @@ -18,6 +18,10 @@ The scale has been switched to linear. minimum value of the range is less or equal zero. Correct the range or switch to linear scale? + + NO_OBJECTS_TO_FIT + No objects to fit + WARNING Warning @@ -30,20 +34,12 @@ Correct the range or switch to linear scale? Plot3d_FitDataDlg - FIT_ALL - Fit both - - - FIT_HORIZONTAL - Fit horizontally - - - FIT_VERTICAL - Fit vertically + ENABLE + Enable - HORIZONTAL_AXIS - Horizontal axis + FIT_DATA_TLT + Fit Data Range MAX_VALUE_LAB @@ -53,18 +49,6 @@ Correct the range or switch to linear scale? MIN_VALUE_LAB Min: - - VERTICAL_AXIS - Vertical axis - - - VERTICAL_LEFT_AXIS - Vertical left axis - - - VERTICAL_RIGHT_AXIS - Vertical right axis - Plot3d_SetupColorScaleDlg @@ -271,7 +255,7 @@ or equal zero in case of logarithmic interpolation. Surfaces settings - FIT_RANGE + MNU_PLOT3D_FIT_RANGE Fit range diff --git a/src/VTKViewer/VTKViewer_Utilities.cxx b/src/VTKViewer/VTKViewer_Utilities.cxx index 9133ee012..f1225a954 100755 --- a/src/VTKViewer/VTKViewer_Utilities.cxx +++ b/src/VTKViewer/VTKViewer_Utilities.cxx @@ -201,6 +201,15 @@ ComputeTrihedronSize( vtkRenderer* theRenderer, bnd[ 1 ] = bnd[ 3 ] = bnd[ 5 ] = 100; bnd[ 0 ] = bnd[ 2 ] = bnd[ 4 ] = 0; } + + if( bnd[ 1 ] < bnd[ 0 ] || + bnd[ 3 ] < bnd[ 2 ] || + bnd[ 5 ] < bnd[ 4 ] ) + { + theNewSize = 1; + return false; + } + vtkFloatingPointType aLength = 0; aLength = bnd[ 1 ]-bnd[ 0 ];