From: rnv Date: Wed, 16 Oct 2013 12:56:06 +0000 (+0000) Subject: First step for the "21793: [CEA 625] Clipping : from coordinates or from bounding... X-Git-Tag: V7_3_0a1~121 X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=commitdiff_plain;h=824f011cef0dc8fee10a7eaca511e9f61690766b First step for the "21793: [CEA 625] Clipping : from coordinates or from bounding box" issue. --- diff --git a/doc/salome/gui/SMESH/images/Clipping_Absolute.png b/doc/salome/gui/SMESH/images/Clipping_Absolute.png new file mode 100644 index 000000000..9657d812e Binary files /dev/null and b/doc/salome/gui/SMESH/images/Clipping_Absolute.png differ diff --git a/doc/salome/gui/SMESH/images/Clipping_Relative.png b/doc/salome/gui/SMESH/images/Clipping_Relative.png new file mode 100644 index 000000000..4fd7dbeb2 Binary files /dev/null and b/doc/salome/gui/SMESH/images/Clipping_Relative.png differ diff --git a/doc/salome/gui/SMESH/images/before_clipping.png b/doc/salome/gui/SMESH/images/before_clipping.png new file mode 100644 index 000000000..41e14d233 Binary files /dev/null and b/doc/salome/gui/SMESH/images/before_clipping.png differ diff --git a/doc/salome/gui/SMESH/images/before_clipping_preview.png b/doc/salome/gui/SMESH/images/before_clipping_preview.png new file mode 100644 index 000000000..f0740cf26 Binary files /dev/null and b/doc/salome/gui/SMESH/images/before_clipping_preview.png differ diff --git a/doc/salome/gui/SMESH/images/dataset_clipping.png b/doc/salome/gui/SMESH/images/dataset_clipping.png new file mode 100644 index 000000000..b50e38a5c Binary files /dev/null and b/doc/salome/gui/SMESH/images/dataset_clipping.png differ diff --git a/doc/salome/gui/SMESH/images/opengl_clipping.png b/doc/salome/gui/SMESH/images/opengl_clipping.png new file mode 100644 index 000000000..475151a04 Binary files /dev/null and b/doc/salome/gui/SMESH/images/opengl_clipping.png differ diff --git a/src/OBJECT/SMESH_Actor.cxx b/src/OBJECT/SMESH_Actor.cxx index ec2a7c949..715f70791 100644 --- a/src/OBJECT/SMESH_Actor.cxx +++ b/src/OBJECT/SMESH_Actor.cxx @@ -75,6 +75,7 @@ #include #include +#include #include #include @@ -534,6 +535,8 @@ SMESH_ActorDef::SMESH_ActorDef() myImplicitBoolean = vtkImplicitBoolean::New(); myImplicitBoolean->SetOperationTypeToIntersection(); + myPlaneCollection = vtkPlaneCollection::New(); + //Quadratic 2D elements representation //----------------------------------------------------------------------------- int aQuadratic2DMode = mgr->integerValue( "SMESH", "quadratic_mode", 0); @@ -619,6 +622,7 @@ SMESH_ActorDef::~SMESH_ActorDef() //my0DExtActor->Delete(); myImplicitBoolean->Delete(); + myPlaneCollection->Delete(); #ifndef DISABLE_PLOT2DVIEWER if(my2dHistogram) { @@ -2149,10 +2153,67 @@ SMESH_ActorDef::AddClippingPlane(vtkPlane* thePlane) return myCippingPlaneCont.size(); } +void +SMESH_ActorDef::AddOpenGLClippingPlane(vtkPlane* thePlane) +{ + if(thePlane) + myPlaneCollection->AddItem( thePlane ); +} + +void +SMESH_ActorDef::SetOpenGLClippingPlane() +{ + // before use this method you must add clipping planes using method + // SMESH_ActorDef::AddOpenGLClippingPlane(vtkPlane* thePlane) + if( !myPlaneCollection->GetNumberOfItems() ) + return; + + // It is necessary to set plane collection for each mapper of actor + // and update current inputs of mapper + myNodeActor->SetPlaneCollection( myPlaneCollection ); + myNodeActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + myBaseActor->SetPlaneCollection( myPlaneCollection ); + myBaseActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + myHighlitableActor->SetPlaneCollection( myPlaneCollection ); + myHighlitableActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + my1DActor->SetPlaneCollection( myPlaneCollection ); + my1DActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + my2DActor->SetPlaneCollection( myPlaneCollection ); + my2DActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + myNodeExtActor->SetPlaneCollection( myPlaneCollection ); + myNodeExtActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + my0DActor->SetPlaneCollection( myPlaneCollection ); + my0DActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + myBallActor->SetPlaneCollection( myPlaneCollection ); + myBallActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + my1DExtActor->SetPlaneCollection( myPlaneCollection ); + my1DExtActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + my2DExtActor->SetPlaneCollection( myPlaneCollection ); + my2DExtActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + my3DActor->SetPlaneCollection( myPlaneCollection ); + my3DActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + my3DExtActor->SetPlaneCollection( myPlaneCollection ); + my3DExtActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + + Modified(); +} + void SMESH_ActorDef:: RemoveAllClippingPlanes() { + myPlaneCollection->RemoveAllItems(); myImplicitBoolean->GetFunction()->RemoveAllItems(); myImplicitBoolean->GetFunction()->Modified(); // VTK bug myCippingPlaneCont.clear(); diff --git a/src/OBJECT/SMESH_Actor.h b/src/OBJECT/SMESH_Actor.h index 3d60fe899..b64ba3147 100644 --- a/src/OBJECT/SMESH_Actor.h +++ b/src/OBJECT/SMESH_Actor.h @@ -154,6 +154,8 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor virtual vtkIdType GetNumberOfClippingPlanes() = 0; virtual vtkPlane* GetClippingPlane(vtkIdType theID) = 0; virtual vtkIdType AddClippingPlane(vtkPlane* thePlane) = 0; + virtual void AddOpenGLClippingPlane(vtkPlane* thePlane) = 0; + virtual void SetOpenGLClippingPlane() = 0; virtual TVisualObjPtr GetObject() = 0; diff --git a/src/OBJECT/SMESH_ActorDef.h b/src/OBJECT/SMESH_ActorDef.h index c891d3cc8..c5c9f412d 100644 --- a/src/OBJECT/SMESH_ActorDef.h +++ b/src/OBJECT/SMESH_ActorDef.h @@ -65,6 +65,7 @@ class vtkLookupTable; class vtkPlane; class vtkImplicitBoolean; class vtkTimeStamp; +class vtkPlaneCollection; class SMESH_DeviceActor; class SMESH_NodeLabelActor; @@ -212,6 +213,8 @@ class SMESH_ActorDef : public SMESH_Actor virtual vtkIdType GetNumberOfClippingPlanes(); virtual vtkPlane* GetClippingPlane(vtkIdType theID); virtual vtkIdType AddClippingPlane(vtkPlane* thePlane); + virtual void AddOpenGLClippingPlane(vtkPlane* thePlane); + virtual void SetOpenGLClippingPlane(); virtual TVisualObjPtr GetObject() { return myVisualObj;} @@ -296,6 +299,7 @@ class SMESH_ActorDef : public SMESH_Actor bool myIsShrunk; vtkImplicitBoolean* myImplicitBoolean; + vtkPlaneCollection* myPlaneCollection; typedef TVTKSmartPtr TPlanePtr; typedef std::vector TCippingPlaneCont; TCippingPlaneCont myCippingPlaneCont; diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx index 4a46932cc..02eefc529 100644 --- a/src/OBJECT/SMESH_DeviceActor.cxx +++ b/src/OBJECT/SMESH_DeviceActor.cxx @@ -63,6 +63,8 @@ #include +#include + #include "utilities.h" #ifdef _DEBUG_ @@ -90,6 +92,7 @@ SMESH_DeviceActor myProperty = vtkProperty::New(); myMapper = VTKViewer_PolyDataMapper::New(); + myPlaneCollection = vtkPlaneCollection::New(); vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor, myPolygonOffsetUnits); @@ -139,6 +142,7 @@ SMESH_DeviceActor if(MYDEBUG) MESSAGE("~SMESH_DeviceActor - "<Delete(); + myPlaneCollection->Delete(); myProperty->Delete(); @@ -256,12 +260,20 @@ SMESH_DeviceActor anId++; // 5 myMapper->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() ); + if( myPlaneCollection->GetNumberOfItems() ) + myMapper->SetClippingPlanes( myPlaneCollection ); vtkLODActor::SetMapper( myMapper ); Modified(); } } +void +SMESH_DeviceActor +::SetPlaneCollection( vtkPlaneCollection* theCollection ) +{ + myPlaneCollection = theCollection; +} VTKViewer_ExtractUnstructuredGrid* SMESH_DeviceActor diff --git a/src/OBJECT/SMESH_DeviceActor.h b/src/OBJECT/SMESH_DeviceActor.h index e3c63a761..e2931d88f 100644 --- a/src/OBJECT/SMESH_DeviceActor.h +++ b/src/OBJECT/SMESH_DeviceActor.h @@ -45,6 +45,7 @@ class vtkUnstructuredGrid; class vtkLookupTable; class vtkImplicitBoolean; class vtkPassThroughFilter; +class vtkPlaneCollection; class VTKViewer_Transform; class VTKViewer_TransformFilter; @@ -119,6 +120,8 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{ VTKViewer_ExtractUnstructuredGrid* GetExtractUnstructuredGrid(); vtkUnstructuredGrid* GetUnstructuredGrid(); + void SetPlaneCollection( vtkPlaneCollection* theCollection ); + void SetControlMode(SMESH::Controls::FunctorPtr theFunctor, SMESH_ScalarBarActor* theScalarBarActor, vtkLookupTable* theLookupTable); @@ -158,6 +161,7 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{ VTKViewer_PolyDataMapper *myMapper; TVisualObjPtr myVisualObj; + vtkPlaneCollection* myPlaneCollection; vtkProperty *myProperty; EReperesent myRepresentation; diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 2486a5099..fe84076d7 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -960,7 +960,7 @@ { SMESH::SMESH_GroupBase_var aGroupObject = aListOfGroups[i]; //SALOMEDS::Color aColor = aGroupObject->GetColor(); - + #ifdef SIMPLE_AUTOCOLOR // simplified algorithm for auto-colors SALOMEDS::Color aColor = SMESHGUI::getPredefinedUniqueColor(); #else // old algorithm for auto-colors @@ -1004,7 +1004,7 @@ SALOME_ListIO selected; if( aSel ) aSel->selectedObjects( selected ); - + if ( selected.IsEmpty() ) return; SALOME_ListIteratorOfListIO It( selected ); for ( ; It.More(); It.Next() ) { @@ -1228,7 +1228,7 @@ SALOME_ListIO selected; if( aSel ) { aSel->selectedObjects( selected ); - + if(selected.Extent()){ Handle(SALOME_InteractiveObject) anIObject = selected.First(); _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); @@ -2065,7 +2065,7 @@ bool SMESHGUI::automaticUpdate( SMESH::SMESH_Mesh_ptr theMesh, } total += nbBalls; } - + return autoUpdate && !exceeded; } @@ -3505,7 +3505,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) tr( "NOT_A_VTK_VIEWER" ) ); } break; - case 6032: + case 6032: OverallMeshQuality(); break; case 9010: @@ -4516,7 +4516,7 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert ( action( 6031 ), aSubId, -1 ); // EQUAL_VOLUME popupMgr()->setRule( action( 6031 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6031 ), "controlMode = 'eCoincidentElems3D'", QtxPopupMgr::ToggleRule ); - + popupMgr()->insert( separator(), anId, -1 ); popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP @@ -5533,13 +5533,34 @@ void SMESHGUI::storeVisualParameters (int savePoint) aPropertyName += gSeparator; aPropertyName += QString::number( anId ); - QString aPropertyValue = QString::number( (int)aPlane->GetOrientation() ).toLatin1().constData(); + QString aPropertyValue = QString::number( (int)aPlane->PlaneMode ).toLatin1().constData(); aPropertyValue += gDigitsSep; - aPropertyValue += QString::number( aPlane->GetDistance() ).toLatin1().constData(); + aPropertyValue += QString::number( aPlane->IsOpenGLClipping ).toLatin1().constData(); aPropertyValue += gDigitsSep; - aPropertyValue += QString::number( aPlane->myAngle[0] ).toLatin1().constData(); - aPropertyValue += gDigitsSep; - aPropertyValue += QString::number( aPlane->myAngle[1] ).toLatin1().constData(); + if ( aPlane->PlaneMode == SMESH::Absolute ) { + aPropertyValue += QString::number( aPlane->myAbsoluteOrientation ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->X ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->Y ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->Z ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->Dx ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->Dy ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->Dz ).toLatin1().constData(); + } + else if ( aPlane->PlaneMode == SMESH::Relative ) { + aPropertyValue += QString::number( (int)aPlane->myRelativeOrientation ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->GetDistance() ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->myAngle[0] ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->myAngle[1] ).toLatin1().constData(); + } ip->setProperty( aPropertyName.toStdString(), aPropertyValue.toStdString() ); } @@ -5749,9 +5770,13 @@ void SMESHGUI::storeVisualParameters (int savePoint) // data structures for clipping planes processing typedef struct { int Id; - vtkIdType Orientation; + int Mode; + bool isOpenGLClipping; + vtkIdType RelativeOrientation; double Distance; double Angle[2]; + int AbsoluteOrientation; + double X, Y, Z, Dx, Dy, Dz; } TPlaneData; typedef std::list TPlaneDataList; typedef std::map TPlaneDataMap; @@ -5868,31 +5893,80 @@ void SMESHGUI::restoreVisualParameters (int savePoint) continue; QStringList aPropertyValueList = aPropertyValue.split( gDigitsSep, QString::SkipEmptyParts ); - if( aPropertyValueList.size() != 4 ) + if( aPropertyValueList.size() != 6 && aPropertyValueList.size() != 9 ) continue; TPlaneData aPlaneData; aPlaneData.Id = aClippingPlaneId; ok = false; - aPlaneData.Orientation = aPropertyValueList[0].toInt( &ok ); + aPlaneData.Mode = aPropertyValueList[0].toInt( &ok ); if( !ok ) continue; - + ok = false; - aPlaneData.Distance = aPropertyValueList[1].toDouble( &ok ); + aPlaneData.isOpenGLClipping = aPropertyValueList[1].toInt( &ok ); if( !ok ) continue; - ok = false; - aPlaneData.Angle[0] = aPropertyValueList[2].toDouble( &ok ); - if( !ok ) - continue; + if ( (SMESH::Mode)aPlaneData.Mode == SMESH::Absolute ) + { + ok = false; + aPlaneData.AbsoluteOrientation = aPropertyValueList[2].toInt( &ok ); + if( !ok ) + continue; - ok = false; - aPlaneData.Angle[1] = aPropertyValueList[3].toDouble( &ok ); - if( !ok ) - continue; + ok = false; + aPlaneData.X = aPropertyValueList[3].toDouble( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Y = aPropertyValueList[4].toDouble( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Z = aPropertyValueList[5].toDouble( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Dx = aPropertyValueList[6].toDouble( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Dy = aPropertyValueList[7].toDouble( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Dz = aPropertyValueList[8].toDouble( &ok ); + if( !ok ) + continue; + } + else if ( (SMESH::Mode)aPlaneData.Mode == SMESH::Relative ) { + ok = false; + aPlaneData.RelativeOrientation = aPropertyValueList[2].toInt( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Distance = aPropertyValueList[3].toDouble( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Angle[0] = aPropertyValueList[4].toDouble( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Angle[1] = aPropertyValueList[5].toDouble( &ok ); + if( !ok ) + continue; + } TPlaneDataList& aPlaneDataList = aPlaneDataMap[ aViewId ]; aPlaneDataList.push_back( aPlaneData ); @@ -6315,21 +6389,18 @@ void SMESHGUI::restoreVisualParameters (int savePoint) // Clipping else if (paramNameStr.startsWith("ClippingPlane")) { QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts); - // old format - val looks like "Off" or "0:0.5:0:0" (orientation, distance, two angles) + // old format - val looks like "Off" or "1:0:0:0.5:0:0" + // (mode(relative), is OpenGL clipping plane, orientation, distance, two angles) + // or "0:1:1:10.5:1.0:1.0:15.0:10.0:10.0" + // (mode(absolute), is OpenGL clipping plane, orientation, base point(x, y, z), direction (dx, dy, dz)) // new format - val looks like "Off" or "0" (plane id) // (note: in new format "Off" value is used only for consistency, // so it is processed together with values in old format) - bool anIsOldFormat = ( vals.count() == 4 || val == "Off" ); + bool anIsOldFormat = ( vals.count() == 6 || vals.count() == 9 || val == "Off" ); if( anIsOldFormat ) { if (paramNameStr == "ClippingPlane1" || val == "Off") aSmeshActor->RemoveAllClippingPlanes(); if (val != "Off") { - SMESH::Orientation anOrientation = (SMESH::Orientation)vals[0].toInt(); - double aDistance = vals[1].toFloat(); - double anAngle[2]; - anAngle[0] = vals[2].toFloat(); - anAngle[1] = vals[3].toFloat(); - QList lst; getApp()->viewManagers(viewerTypStr, lst); // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager @@ -6341,13 +6412,35 @@ void SMESHGUI::restoreVisualParameters (int savePoint) SMESH::TActorList anActorList; anActorList.push_back( aSmeshActor ); - SMESH::OrientedPlane* aPlane = - SMESHGUI_ClippingDlg::AddPlane(anActorList, vtkView, anOrientation, aDistance, anAngle); + SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New( vtkView ); + aPlane->myViewWindow = vtkView; + SMESH::Mode aMode = ( SMESH::Mode )vals[0].toInt(); + aPlane->PlaneMode = aMode; + bool isOpenGLClipping = ( bool )vals[1].toInt(); + aPlane->IsOpenGLClipping = isOpenGLClipping; + if ( aMode == SMESH::Absolute ) { + aPlane->myAbsoluteOrientation = vals[2].toInt(); + aPlane->X = vals[3].toFloat(); + aPlane->Y = vals[4].toFloat(); + aPlane->Z = vals[5].toFloat(); + aPlane->Dx = vals[6].toFloat(); + aPlane->Dy = vals[7].toFloat(); + aPlane->Dz = vals[8].toFloat(); + } + else if ( aMode == SMESH::Relative ) { + aPlane->myRelativeOrientation = (SMESH::Orientation)vals[2].toInt(); + aPlane->myDistance = vals[3].toFloat(); + aPlane->myAngle[0] = vals[4].toFloat(); + aPlane->myAngle[1] = vals[5].toFloat(); + } + if( aPlane ) { - SMESH::ClippingPlaneInfo aClippingPlaneInfo; - aClippingPlaneInfo.Plane = aPlane; - aClippingPlaneInfo.ActorList = anActorList; - aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); + if ( SMESHGUI_ClippingDlg::AddPlane( anActorList, aPlane ) ) { + SMESH::ClippingPlaneInfo aClippingPlaneInfo; + aClippingPlaneInfo.Plane = aPlane; + aClippingPlaneInfo.ActorList = anActorList; + aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); + } } } } @@ -6468,23 +6561,40 @@ void SMESHGUI::restoreVisualParameters (int savePoint) for( ; anIter4 != aPlaneDataList.end(); anIter4++ ) { const TPlaneData& aPlaneData = *anIter4; if( aPlaneData.Id == aPlaneId ) { - SMESH::OrientedPlane* aPlane = - SMESHGUI_ClippingDlg::AddPlane( anActorList, - aViewWindow, - (SMESH::Orientation)aPlaneData.Orientation, - aPlaneData.Distance, - aPlaneData.Angle ); + SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New( aViewWindow ); + aPlane->myViewWindow = aViewWindow; + aPlane->PlaneMode = (SMESH::Mode)aPlaneData.Mode; + aPlane->IsOpenGLClipping = aPlaneData.isOpenGLClipping; + if ( aPlane->PlaneMode == SMESH::Absolute ) { + aPlane->myAbsoluteOrientation = aPlaneData.AbsoluteOrientation; + aPlane->X = aPlaneData.X; + aPlane->Y = aPlaneData.Y; + aPlane->Z = aPlaneData.Z; + aPlane->Dx = aPlaneData.Dx; + aPlane->Dy = aPlaneData.Dy; + aPlane->Dz = aPlaneData.Dz; + } + else if ( aPlane->PlaneMode == SMESH::Relative ) { + aPlane->myRelativeOrientation = (SMESH::Orientation)aPlaneData.RelativeOrientation; + aPlane->myDistance = aPlaneData.Distance; + aPlane->myAngle[0] = aPlaneData.Angle[0]; + aPlane->myAngle[1] = aPlaneData.Angle[1]; + } if( aPlane ) { - SMESH::ClippingPlaneInfo aClippingPlaneInfo; - aClippingPlaneInfo.Plane = aPlane; - aClippingPlaneInfo.ActorList = anActorList; - aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); + if ( SMESHGUI_ClippingDlg::AddPlane( anActorList, aPlane ) ) { + SMESH::ClippingPlaneInfo aClippingPlaneInfo; + aClippingPlaneInfo.Plane = aPlane; + aClippingPlaneInfo.ActorList = anActorList; + aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); + } } break; } } + } } + // update all VTK views QList lst; @@ -6493,6 +6603,14 @@ void SMESHGUI::restoreVisualParameters (int savePoint) SUIT_ViewModel* vmodel = (*it)->getViewModel(); if (vmodel && vmodel->getType() == SVTK_Viewer::Type()) { SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) (*it)->getActiveView(); + // set OpenGL clipping planes + VTK::ActorCollectionCopy aCopy( vtkView->getRenderer()->GetActors() ); + vtkActorCollection* anAllActors = aCopy.GetActors(); + anAllActors->InitTraversal(); + while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActor->SetOpenGLClippingPlane(); + vtkView->getRenderer()->ResetCameraClippingRange(); vtkView->Repaint(); } @@ -6691,7 +6809,6 @@ bool SMESHGUI::renameObject( const QString& entry, const QString& name) { return false; } - SALOMEDS::Color SMESHGUI::getPredefinedUniqueColor() { static QList colors; diff --git a/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx b/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx index c1e63059d..9078e7b6e 100644 --- a/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx @@ -52,6 +52,7 @@ #include #include +#include // Qt includes #include @@ -64,6 +65,9 @@ #include #include #include +#include +#include +#include // VTK includes #include @@ -72,64 +76,113 @@ #include #include #include +#include +#include + +#include #define SPACING 6 #define MARGIN 11 +#define SIZEFACTOR 1.1 -//================================================================================= -// class : OrientedPlane -// purpose : -//================================================================================= +/*! + Create new object of class OrientedPlane + */ SMESH::OrientedPlane* SMESH::OrientedPlane::New() { return new OrientedPlane(); } -SMESH::OrientedPlane* SMESH::OrientedPlane::New(SVTK_ViewWindow* theViewWindow) +/*! + Create new object of class OrientedPlane + */ +SMESH::OrientedPlane* SMESH::OrientedPlane::New( SVTK_ViewWindow* theViewWindow ) { - return new OrientedPlane(theViewWindow); + return new OrientedPlane( theViewWindow ); } -void SMESH::OrientedPlane::ShallowCopy(SMESH::OrientedPlane* theOrientedPlane) +/*! + Copy the object of class OrientedPlane + */ +void SMESH::OrientedPlane::ShallowCopy( SMESH::OrientedPlane* theOrientedPlane ) { - SetNormal(theOrientedPlane->GetNormal()); - SetOrigin(theOrientedPlane->GetOrigin()); + SetNormal( theOrientedPlane->GetNormal() ); + SetOrigin( theOrientedPlane->GetOrigin() ); - myOrientation = theOrientedPlane->GetOrientation(); + myRelativeOrientation = theOrientedPlane->GetOrientation(); myDistance = theOrientedPlane->GetDistance(); + IsOpenGLClipping = theOrientedPlane->IsOpenGLClipping; + myAngle[0] = theOrientedPlane->myAngle[0]; myAngle[1] = theOrientedPlane->myAngle[1]; - myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal()); - myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin()); - myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1()); - myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2()); + myAbsoluteOrientation = theOrientedPlane->myAbsoluteOrientation; + X = theOrientedPlane->X; + Y = theOrientedPlane->Y; + Z = theOrientedPlane->Z; + Dx = theOrientedPlane->Dx; + Dy = theOrientedPlane->Dy; + Dz = theOrientedPlane->Dz; + + PlaneMode = theOrientedPlane->PlaneMode; + + myPlaneSource->SetNormal( theOrientedPlane->myPlaneSource->GetNormal() ); + myPlaneSource->SetOrigin( theOrientedPlane->myPlaneSource->GetOrigin() ); + myPlaneSource->SetPoint1( theOrientedPlane->myPlaneSource->GetPoint1() ); + myPlaneSource->SetPoint2( theOrientedPlane->myPlaneSource->GetPoint2() ); myPlaneSource->Update(); } +/*! + Invert current clipping plane in contrary direction + */ +SMESH::OrientedPlane* SMESH::OrientedPlane::InvertPlane() +{ + OrientedPlane* aPlane = new OrientedPlane(); + aPlane->ShallowCopy( this ); + double* aNormal = aPlane->GetNormal(); + for( int i=0; i<3; i++ ) + aNormal[i] = -aNormal[i]; + aPlane->SetNormal( aNormal ); + return aPlane; +} + +/*! + Constructor of class OrientedPlane + */ SMESH::OrientedPlane::OrientedPlane(SVTK_ViewWindow* theViewWindow): - myViewWindow(theViewWindow), - myOrientation(SMESH::XY), - myDistance(0.5) + myViewWindow(theViewWindow) { Init(); myViewWindow->AddActor(myActor, false, false); // don't adjust actors } +/*! + Constructor of class OrientedPlane + */ SMESH::OrientedPlane::OrientedPlane(): - myOrientation(SMESH::XY), - myViewWindow(NULL), - myDistance(0.5) + myViewWindow(NULL) { Init(); } +/*! + Initialize parameters of class OrientedPlane + */ void SMESH::OrientedPlane::Init() { myPlaneSource = vtkPlaneSource::New(); + PlaneMode = SMESH::Absolute; + X = Y = Z = 0.0; + Dx = Dy = Dz = 1.0; + myAbsoluteOrientation = 0; // CUSTOM + myRelativeOrientation = SMESH::XY; + myDistance = 0.5; myAngle[0] = myAngle[1] = 0.0; + IsInvert = false; + IsOpenGLClipping = false; // Create and display actor myMapper = vtkDataSetMapper::New(); @@ -160,6 +213,9 @@ void SMESH::OrientedPlane::Init() aBackProp->Delete(); } +/*! + Destructor of class OrientedPlane + */ SMESH::OrientedPlane::~OrientedPlane() { if (myViewWindow) @@ -170,14 +226,13 @@ SMESH::OrientedPlane::~OrientedPlane() myMapper->Delete(); // commented: porting to vtk 5.0 - // myPlaneSource->UnRegisterAllOutputs(); + // myPlaneSource->UnRegisterAllOutputs(); myPlaneSource->Delete(); } -//================================================================================= -// class : ActorItem -// purpose : -//================================================================================= +/*! + Definition of class ActorItem + */ class ActorItem : public QListWidgetItem { public: @@ -191,11 +246,11 @@ private: SMESH_Actor* myActor; }; -//================================================================================= -// class : TSetVisibility -// purpose : -//================================================================================= +/*! + Definition of class TSetVisibility + */ struct TSetVisibility { + // Set visibility of cutting plane TSetVisibility(int theIsVisible): myIsVisible(theIsVisible){} void operator()(SMESH::TPlaneData& thePlaneData){ bool anIsEmpty = thePlaneData.ActorList.empty(); @@ -204,147 +259,13 @@ struct TSetVisibility { int myIsVisible; }; -//================================================================================= -// used in SMESHGUI::restoreVisualParameters() to avoid -// declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx -//================================================================================= -SMESH::OrientedPlane* SMESHGUI_ClippingDlg::AddPlane (SMESH::TActorList theActorList, - SVTK_ViewWindow* theViewWindow, - SMESH::Orientation theOrientation, - double theDistance, - const double theAngle[2]) -{ - SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(theViewWindow); - - aPlane->myAngle[0] = theAngle[0]; - aPlane->myAngle[1] = theAngle[1]; - - aPlane->SetOrientation(theOrientation); - aPlane->SetDistance(theDistance); - - double aNormal[3]; - double aDir[2][3] = {{0, 0, 0}, {0, 0, 0}}; - { - static double aCoeff = vtkMath::Pi()/180.0; - - double anU[2] = {cos(aCoeff * theAngle[0]), cos(aCoeff * theAngle[1])}; - double aV[2] = {sqrt(1.0 - anU[0]*anU[0]), sqrt(1.0 - anU[1]*anU[1])}; - aV[0] = theAngle[0] > 0? aV[0]: -aV[0]; - aV[1] = theAngle[1] > 0? aV[1]: -aV[1]; - - switch (theOrientation) { - case SMESH::XY: - aDir[0][1] = anU[0]; - aDir[0][2] = aV[0]; - - aDir[1][0] = anU[1]; - aDir[1][2] = aV[1]; - - break; - case SMESH::YZ: - aDir[0][2] = anU[0]; - aDir[0][0] = aV[0]; - - aDir[1][1] = anU[1]; - aDir[1][0] = aV[1]; - - break; - case SMESH::ZX: - aDir[0][0] = anU[0]; - aDir[0][1] = aV[0]; - - aDir[1][2] = anU[1]; - aDir[1][1] = aV[1]; - - break; - } - - vtkMath::Cross(aDir[1],aDir[0],aNormal); - vtkMath::Normalize(aNormal); - vtkMath::Cross(aNormal,aDir[1],aDir[0]); - } - - double aBounds[6]; - double anOrigin[3]; - - bool anIsOk = false; - if( theActorList.empty() ) { - // to support planes with empty actor list we should create - // a nullified plane that will be initialized later - anOrigin[0] = anOrigin[1] = anOrigin[2] = 0; - aBounds[0] = aBounds[2] = aBounds[4] = 0; - aBounds[1] = aBounds[3] = aBounds[5] = 0; - anIsOk = true; - } - else - anIsOk = SMESH::ComputeClippingPlaneParameters( theActorList, - aNormal, - theDistance, - aBounds, - anOrigin ); - if( !anIsOk ) - return NULL; - - aPlane->SetNormal( aNormal ); - aPlane->SetOrigin( anOrigin ); - - double aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2., - ( aBounds[2] + aBounds[3] ) / 2., - ( aBounds[4] + aBounds[5] ) / 2. }; - - double aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) + - pow( aBounds[3] - aBounds[2], 2 ) + - pow( aBounds[5] - aBounds[4], 2 ), 0.5 ); - - double aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel}, - {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}}; - double aParam, aPnt0[3], aPnt1[3], aPnt2[3]; - - double aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0], - aPnt[1] - aDelta[0][1] - aDelta[1][1], - aPnt[2] - aDelta[0][2] - aDelta[1][2]}; - double aPnt02[3] = {aPnt01[0] + aNormal[0], - aPnt01[1] + aNormal[1], - aPnt01[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0); - - double aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0], - aPnt[1] - aDelta[0][1] + aDelta[1][1], - aPnt[2] - aDelta[0][2] + aDelta[1][2]}; - double aPnt12[3] = {aPnt11[0] + aNormal[0], - aPnt11[1] + aNormal[1], - aPnt11[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1); - - double aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0], - aPnt[1] + aDelta[0][1] - aDelta[1][1], - aPnt[2] + aDelta[0][2] - aDelta[1][2]}; - double aPnt22[3] = {aPnt21[0] + aNormal[0], - aPnt21[1] + aNormal[1], - aPnt21[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2); - - vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource; - aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]); - aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]); - aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]); - aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]); - aPlaneSource->Update(); - - SMESH::TActorList::iterator anIter = theActorList.begin(); - for ( ; anIter != theActorList.end(); anIter++ ) - if( vtkActor* aVTKActor = *anIter ) - if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) - anActor->AddClippingPlane( aPlane ); - - return aPlane; -} +/********************************************************************************* + ********************* class SMESHGUI_ClippingDlg ********************* + *********************************************************************************/ -//================================================================================= -// class : SMESHGUI_ClippingDlg() -// purpose : -// -//================================================================================= +/*! + Constructor +*/ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow* theViewWindow ): QDialog( SMESH::GetDesktop(theModule) ), mySMESHGUI(theModule), @@ -355,6 +276,14 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow setWindowTitle(tr("SMESH_CLIPPING_TITLE")); setSizeGripEnabled(true); + myPreviewWidget = vtkImplicitPlaneWidget::New(); + myCallback = vtkCallbackCommand::New(); + myCallback->SetClientData( this ); + myCallback->SetCallback( SMESHGUI_ClippingDlg::ProcessEvents ); + myPreviewWidget = createPreviewWidget(); + + myIsPreviewMoved = false; + QVBoxLayout* SMESHGUI_ClippingDlgLayout = new QVBoxLayout(this); SMESHGUI_ClippingDlgLayout->setSpacing(SPACING); SMESHGUI_ClippingDlgLayout->setMargin(MARGIN); @@ -367,8 +296,17 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow ComboBoxPlanes = new QComboBox(GroupPlanes); + isOpenGLClipping = new QCheckBox( GroupPlanes ); + isOpenGLClipping->setText( tr( "IS_OPENGL_CLIPPING" ) ); + buttonNew = new QPushButton(tr("SMESH_BUT_NEW"), GroupPlanes); + MenuMode = new QMenu( "MenuMode", buttonNew ); + MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) ); + MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) ); + buttonNew->setMenu( MenuMode ); + CurrentMode = SMESH::Absolute; + buttonDelete = new QPushButton(tr("SMESH_BUT_DELETE"), GroupPlanes); QLabel* aLabel = new QLabel(tr("MESHES_SUBMESHES_GROUPS"), GroupPlanes); @@ -379,705 +317,769 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow SelectAllCheckBox = new QCheckBox(tr("SELECT_ALL"), GroupPlanes); GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0); - GroupPlanesLayout->addWidget(new QWidget(), 0, 1); - GroupPlanesLayout->addWidget(buttonNew, 0, 2); - GroupPlanesLayout->addWidget(buttonDelete, 0, 3); - GroupPlanesLayout->addWidget(aLabel, 1, 0, 1, 4); - GroupPlanesLayout->addWidget(ActorList, 2, 0, 1, 4); - GroupPlanesLayout->addWidget(SelectAllCheckBox, 3, 0, 1, 4); + GroupPlanesLayout->addWidget(isOpenGLClipping, 0, 1); + GroupPlanesLayout->addWidget(new QWidget(), 0, 2); + GroupPlanesLayout->addWidget(buttonNew, 0, 3); + GroupPlanesLayout->addWidget(buttonDelete, 0, 4); + GroupPlanesLayout->addWidget(aLabel, 1, 0, 1, 5); + GroupPlanesLayout->addWidget(ActorList, 2, 0, 1, 5); + GroupPlanesLayout->addWidget(SelectAllCheckBox, 3, 0, 1, 5); GroupPlanesLayout->setColumnStretch( 1, 1 ); - // Controls for defining plane parameters - QGroupBox* GroupParameters = new QGroupBox(tr("SMESH_PARAMETERS"), this); - QGridLayout* GroupParametersLayout = new QGridLayout(GroupParameters); - GroupParametersLayout->setSpacing(SPACING); - GroupParametersLayout->setMargin(MARGIN); - - TextLabelOrientation = new QLabel(tr("SMESH_ORIENTATION"), GroupParameters); - - ComboBoxOrientation = new QComboBox(GroupParameters); - - TextLabelDistance = new QLabel(tr("SMESH_DISTANCE"), GroupParameters); - - SpinBoxDistance = new SMESHGUI_SpinBox(GroupParameters); - - TextLabelRot1 = new QLabel(tr("ROTATION_AROUND_X_Y2Z"), GroupParameters); - - SpinBoxRot1 = new SMESHGUI_SpinBox(GroupParameters); - - TextLabelRot2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters); - - SpinBoxRot2 = new SMESHGUI_SpinBox(GroupParameters); - - PreviewCheckBox = new QCheckBox(tr("SHOW_PREVIEW"), GroupParameters); - PreviewCheckBox->setChecked(true); - - AutoApplyCheckBox = new QCheckBox(tr("AUTO_APPLY"), GroupParameters); - AutoApplyCheckBox->setChecked(false); - - GroupParametersLayout->addWidget(TextLabelOrientation, 0, 0); - GroupParametersLayout->addWidget(ComboBoxOrientation, 0, 1); - GroupParametersLayout->addWidget(TextLabelDistance, 1, 0); - GroupParametersLayout->addWidget(SpinBoxDistance, 1, 1); - GroupParametersLayout->addWidget(TextLabelRot1, 2, 0); - GroupParametersLayout->addWidget(SpinBoxRot1, 2, 1); - GroupParametersLayout->addWidget(TextLabelRot2, 3, 0); - GroupParametersLayout->addWidget(SpinBoxRot2, 3, 1); - GroupParametersLayout->addWidget(PreviewCheckBox, 4, 0); - GroupParametersLayout->addWidget(AutoApplyCheckBox, 4, 1); + ModeStackedLayout = new QStackedLayout(); + // Controls for defining plane parameters + /********************** Mode Absolute **********************/ + /* Controls for absolute mode of clipping plane: + X, Y, Z - coordinates of the intersection of cutting plane and the three axes + Dx, Dy, Dz - components of normal to the cutting plane + Orientation - direction of cutting plane + */ + const double min = -1e+7; + const double max = 1e+7; + const double step = 5; + const int precision = -7; + + // Croup Point + QGroupBox* GroupAbsolutePoint = new QGroupBox( this ); + GroupAbsolutePoint->setObjectName( "GroupPoint" ); + GroupAbsolutePoint->setTitle( tr("BASE_POINT") ); + QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint ); + GroupPointLayout->setAlignment( Qt::AlignTop ); + GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 ); + + TextLabelX = new QLabel( GroupAbsolutePoint ); + TextLabelX->setObjectName( "TextLabelX" ); + TextLabelX->setText( tr("X:") ); + GroupPointLayout->addWidget( TextLabelX, 0, 0 ); + + SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint ); + SpinBox_X->setObjectName("SpinBox_X" ); + SpinBox_X->setPrecision( precision ); + GroupPointLayout->addWidget( SpinBox_X, 0, 1 ); + + TextLabelY = new QLabel( GroupAbsolutePoint ); + TextLabelY->setObjectName( "TextLabelY" ); + TextLabelY->setText( tr("Y:") ); + GroupPointLayout->addWidget( TextLabelY, 0, 2 ); + + SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint ); + SpinBox_Y->setObjectName("SpinBox_Y" ); + SpinBox_Y->setPrecision( precision ); + GroupPointLayout->addWidget( SpinBox_Y, 0, 3 ); + + TextLabelZ = new QLabel( GroupAbsolutePoint ); + TextLabelZ->setObjectName( "TextLabelZ" ); + TextLabelZ->setText( tr("Z:") ); + GroupPointLayout->addWidget( TextLabelZ, 0, 4 ); + + SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint ); + SpinBox_Z->setObjectName("SpinBox_Z" ); + SpinBox_Z->setPrecision( precision ); + GroupPointLayout->addWidget( SpinBox_Z, 0, 5 ); + + resetButton = new QPushButton( GroupAbsolutePoint ); + resetButton->setObjectName( "resetButton" ); + resetButton->setText( tr( "RESET" ) ); + GroupPointLayout->addWidget( resetButton, 0, 6 ); + + // Group Direction + GroupAbsoluteDirection = new QGroupBox( this ); + GroupAbsoluteDirection->setObjectName( "GroupDirection" ); + GroupAbsoluteDirection->setTitle( tr("DIRECTION") ); + QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection ); + GroupDirectionLayout->setAlignment( Qt::AlignTop ); + GroupDirectionLayout->setSpacing( 6 ); + GroupDirectionLayout->setMargin( 11 ); + + TextLabelDx = new QLabel( GroupAbsoluteDirection ); + TextLabelDx->setObjectName( "TextLabelDx" ); + TextLabelDx->setText( tr("Dx:") ); + GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 ); + + SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection ); + SpinBox_Dx->setObjectName("SpinBox_Dx" ); + SpinBox_Dx->setPrecision( precision ); + GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 ); + + TextLabelDy = new QLabel( GroupAbsoluteDirection ); + TextLabelDy->setObjectName( "TextLabelDy" ); + TextLabelDy->setText( tr("Dy:") ); + GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 ); + + SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection ); + SpinBox_Dy->setObjectName("SpinBox_Dy" ); + SpinBox_Dy->setPrecision( precision ); + GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 ); + + TextLabelDz = new QLabel( GroupAbsoluteDirection ); + TextLabelDz->setObjectName( "TextLabelDz" ); + TextLabelDz->setText( tr("Dz:") ); + GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 ); + + SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection ); + SpinBox_Dz->setObjectName("SpinBox_Dz" ); + SpinBox_Dz->setPrecision( precision ); + GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 ); + + invertButton = new QPushButton( GroupAbsoluteDirection ); + invertButton->setObjectName( "invertButton" ); + invertButton->setText( tr( "INVERT" ) ); + GroupDirectionLayout->addWidget( invertButton, 0, 6 ); + + CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection ); + CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" ); + CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) ); + CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) ); + CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) ); + CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) ); + GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 ); + + QVBoxLayout* ModeActiveLayout = new QVBoxLayout(); + ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 ); + ModeActiveLayout->addWidget( GroupAbsolutePoint ); + ModeActiveLayout->addWidget( GroupAbsoluteDirection ); + + QWidget* ModeActiveWidget = new QWidget( this ); + ModeActiveWidget->setLayout( ModeActiveLayout ); + + /********************** Mode Relative **********************/ + /* Controls for relative mode of clipping plane: + Distance - Value from 0 to 1. + Specifies the distance from the minimum value in a given direction of bounding box to the current position + Rotation1, Rotation2 - turn angles of cutting plane in given directions + Orientation - direction of cutting plane + */ + QGroupBox* GroupParameters = new QGroupBox( tr("SMESH_PARAMETERS"), this ); + QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters ); + GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 ); + + TextLabelOrientation = new QLabel( tr("SMESH_ORIENTATION"), GroupParameters); + TextLabelOrientation->setObjectName( "TextLabelOrientation" ); + GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 ); + + CBRelativeOrientation = new QComboBox(GroupParameters); + CBRelativeOrientation->setObjectName( "RelativeOrientation" ); + CBRelativeOrientation->addItem( tr("ALONG_XY") ); + CBRelativeOrientation->addItem( tr("ALONG_YZ") ); + CBRelativeOrientation->addItem( tr("ALONG_ZX") ); + GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 ); + + TLValueDistance = new QLabel( GroupParameters ); + TLValueDistance->setObjectName( "TLValueDistance" ); + TLValueDistance->setAlignment( Qt::AlignCenter ); + TLValueDistance->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + QFont fnt = TLValueDistance->font(); fnt.setBold( true ); TLValueDistance->setFont( fnt ); + GroupParametersLayout->addWidget( TLValueDistance, 1, 1 ); + + TextLabelDistance = new QLabel( tr("SMESH_DISTANCE"), GroupParameters ); + TextLabelDistance->setObjectName( "TextLabelDistance" ); + GroupParametersLayout->addWidget( TextLabelDistance, 2, 0 ); + + SliderDistance = new QSlider( Qt::Horizontal, GroupParameters ); + SliderDistance->setObjectName( "SliderDistance" ); + SliderDistance->setFocusPolicy( Qt::NoFocus ); + SliderDistance->setMinimumSize( 300, 0 ); + SliderDistance->setMinimum( 0 ); + SliderDistance->setMaximum( 100 ); + SliderDistance->setSingleStep( 1 ); + SliderDistance->setPageStep( 10 ); + SliderDistance->setTracking( false ); + GroupParametersLayout->addWidget( SliderDistance, 2, 1 ); + + TLValueRotation1 = new QLabel( GroupParameters ); + TLValueRotation1->setObjectName( "TLValueRotation1" ); + TLValueRotation1->setAlignment( Qt::AlignCenter ); + TLValueRotation1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + TLValueRotation1->setFont( fnt ); + GroupParametersLayout->addWidget( TLValueRotation1, 3, 1 ); + + TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters ); + TextLabelRotation1->setObjectName( "TextLabelRotation1" ); + GroupParametersLayout->addWidget( TextLabelRotation1, 4, 0 ); + + SliderRotation1 = new QSlider( Qt::Horizontal, GroupParameters ); + SliderRotation1->setObjectName( "SliderRotation1" ); + SliderRotation1->setFocusPolicy( Qt::NoFocus ); + SliderRotation1->setMinimumSize( 300, 0 ); + SliderRotation1->setMinimum( -180 ); + SliderRotation1->setMaximum( 180 ); + SliderRotation1->setSingleStep( 1 ); + SliderRotation1->setPageStep( 10 ); + SliderRotation1->setTracking(false); + GroupParametersLayout->addWidget( SliderRotation1, 4, 1 ); + + TLValueRotation2 = new QLabel( GroupParameters ); + TLValueRotation2->setObjectName( "TLValueRotation2" ); + TLValueRotation2->setAlignment( Qt::AlignCenter ); + TLValueRotation2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + TLValueRotation2->setFont( fnt ); + GroupParametersLayout->addWidget( TLValueRotation2, 5, 1 ); + + TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters); + TextLabelRotation2->setObjectName( "TextLabelRotation2" ); + TextLabelRotation2->setObjectName( "TextLabelRotation2" ); + GroupParametersLayout->addWidget( TextLabelRotation2, 6, 0 ); + + SliderRotation2 = new QSlider( Qt::Horizontal, GroupParameters ); + SliderRotation2->setObjectName( "SliderRotation2" ); + SliderRotation2->setFocusPolicy( Qt::NoFocus ); + SliderRotation2->setMinimumSize( 300, 0 ); + SliderRotation2->setMinimum( -180 ); + SliderRotation2->setMaximum( 180 ); + SliderRotation2->setSingleStep( 1 ); + SliderRotation2->setPageStep( 10 ); + SliderRotation2->setTracking(false); + GroupParametersLayout->addWidget( SliderRotation2, 6, 1 ); + + /***************************************************************/ + QWidget* CheckBoxWidget = new QWidget( this ); + QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget ); + + PreviewCheckBox = new QCheckBox( tr("SHOW_PREVIEW"), CheckBoxWidget ); + PreviewCheckBox->setObjectName( "PreviewCheckBox" ); + PreviewCheckBox->setChecked( true ); + CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter ); + + AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget ); + AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" ); + CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter ); + + /***************************************************************/ // Controls for "Ok", "Apply" and "Close" button QGroupBox* GroupButtons = new QGroupBox(this); QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons); GroupButtonsLayout->setSpacing(SPACING); GroupButtonsLayout->setMargin(MARGIN); - buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons); - buttonOk->setAutoDefault(true); - buttonOk->setDefault(true); - buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons); - buttonApply->setAutoDefault(true); - buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons); - buttonCancel->setAutoDefault(true); - buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons); - buttonHelp->setAutoDefault(true); - GroupButtonsLayout->addWidget(buttonOk); + buttonOk = new QPushButton( tr( "SMESH_BUT_APPLY_AND_CLOSE" ), GroupButtons ); + buttonOk->setAutoDefault( true ); + buttonOk->setDefault( true ); + buttonApply = new QPushButton( tr( "SMESH_BUT_APPLY" ), GroupButtons ); + buttonApply->setAutoDefault( true ); + buttonCancel = new QPushButton( tr( "SMESH_BUT_CLOSE" ), GroupButtons ); + buttonCancel->setAutoDefault( true ); + buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons ); + buttonHelp->setAutoDefault( true ); + GroupButtonsLayout->addWidget( buttonOk ); GroupButtonsLayout->addSpacing(10); - GroupButtonsLayout->addWidget(buttonApply); + GroupButtonsLayout->addWidget( buttonApply ); GroupButtonsLayout->addSpacing(10); GroupButtonsLayout->addStretch(); - GroupButtonsLayout->addWidget(buttonCancel); - GroupButtonsLayout->addWidget(buttonHelp); + GroupButtonsLayout->addWidget( buttonCancel ); + GroupButtonsLayout->addWidget( buttonHelp ); - SMESHGUI_ClippingDlgLayout->addWidget(GroupPlanes); - SMESHGUI_ClippingDlgLayout->addWidget(GroupParameters); - SMESHGUI_ClippingDlgLayout->addWidget(GroupButtons); + ModeStackedLayout->addWidget( ModeActiveWidget ); + ModeStackedLayout->addWidget( GroupParameters ); - // Initial state - SpinBoxDistance->RangeStepAndValidator(0.0, 1.0, 0.01, "length_precision" ); - SpinBoxRot1->RangeStepAndValidator(-180.0, 180.0, 1, "angle_precision" ); - SpinBoxRot2->RangeStepAndValidator(-180.0, 180.0, 1, "angle_precision" ); + SMESHGUI_ClippingDlgLayout->addWidget( GroupPlanes ); + SMESHGUI_ClippingDlgLayout->addLayout( ModeStackedLayout ); + SMESHGUI_ClippingDlgLayout->addWidget( CheckBoxWidget ); + SMESHGUI_ClippingDlgLayout->addWidget( GroupButtons ); - ComboBoxOrientation->addItem(tr("ALONG_XY")); - ComboBoxOrientation->addItem(tr("ALONG_YZ")); - ComboBoxOrientation->addItem(tr("ALONG_ZX")); - - SpinBoxDistance->SetValue(0.5); + // Initializations + initParam(); myIsSelectPlane = false; - initializePlaneData(); - synchronize(); - myHelpFileName = "clipping_page.html"; // signals and slots connections : - connect(ComboBoxPlanes, SIGNAL(activated(int)), this, SLOT(onSelectPlane(int))); - connect(buttonNew, SIGNAL(clicked()), this, SLOT(ClickOnNew())); - connect(buttonDelete, SIGNAL(clicked()), this, SLOT(ClickOnDelete())); - connect(ActorList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(onActorItemChanged(QListWidgetItem*))); - connect(SelectAllCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onSelectAll(int))); - 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(PreviewCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnPreviewToggle(bool))); - connect(AutoApplyCheckBox, SIGNAL(toggled(bool)), this, SLOT(onAutoApply(bool))); - connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk())); - connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject())); - connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); - connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); - connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(reject())); + connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) ); + connect( isOpenGLClipping, SIGNAL( toggled( bool ) ), this, SLOT( onIsOpenGLClipping( bool ) ) ); + connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) ); + connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) ); + connect( ActorList, SIGNAL( itemChanged( QListWidgetItem* ) ), this, SLOT( onActorItemChanged( QListWidgetItem*) ) ); + connect( SelectAllCheckBox, SIGNAL( stateChanged( int ) ), this, SLOT( onSelectAll( int ) ) ); + + connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ; + connect( resetButton, SIGNAL (clicked() ), this, SLOT( onReset() ) ); + connect( SpinBox_X, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) ); + connect( SpinBox_Y, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) ); + connect( SpinBox_Z, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) ); + connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) ); + connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) ); + connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ), this, SLOT( SetCurrentPlaneParam() ) ); + connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onSelectAbsoluteOrientation( int ) ) ) ; + + connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onSelectRelativeOrientation( int ) ) ); + connect( SliderDistance, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderDistanceHasMoved( int ) ) ); + connect( SliderDistance, SIGNAL( valueChanged( int ) ), this, SLOT( SliderDistanceHasMoved( int ) ) ); + connect( SliderRotation1, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderRotation1HasMoved( int ) ) ); + connect( SliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( SliderRotation1HasMoved( int ) ) ); + connect( SliderRotation2, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderRotation2HasMoved( int ) ) ); + connect( SliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( SliderRotation2HasMoved( int ) ) ); + + connect( PreviewCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( OnPreviewToggle( bool ) ) ); + connect( AutoApplyCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) ); + connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); + connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ); + connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) ); + connect( mySMESHGUI, SIGNAL ( SignalCloseAllDialogs() ), this, SLOT( reject() ) ); /* to close dialog if study frame change */ - connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), this, SLOT(reject())); + connect( mySMESHGUI, SIGNAL ( SignalStudyFrameChanged() ), this, SLOT( reject() ) ); + + initializePlaneData(); + synchronize(); this->show(); } -//================================================================================= -// function : ~SMESHGUI_ClippingDlg() -// purpose : -//================================================================================= +/*! + Destructor + Destroys the object and frees any allocated resources +*/ SMESHGUI_ClippingDlg::~SMESHGUI_ClippingDlg() { // no need to delete child widgets, Qt does it all for us std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(false)); if (myViewWindow) SMESH::RenderViewWindow(myViewWindow); + + for( int i=0; i< myPlanes.size(); i++ ) { + SMESH::TPlaneData aPlaneData = myPlanes[i]; + aPlaneData.Plane->Delete(); + } + + if (myPreviewWidget) { + myPreviewWidget->Off(); + myPreviewWidget->Delete(); + } + myPreviewWidget = 0; + myCallback->Delete(); + + myViewWindow->Repaint(); } +/*! + Get distance for cutting plane in relative mode +*/ double SMESHGUI_ClippingDlg::getDistance() const { - return SpinBoxDistance->GetValue(); + return TLValueDistance->text().toDouble(); } +/*! + Set distance of cutting plane in relative mode +*/ void SMESHGUI_ClippingDlg::setDistance( const double theDistance ) { - SpinBoxDistance->SetValue( theDistance ); + SliderDistance->setValue( theDistance*100 ); } +/*! + Get rotation1 for cutting plane in relative mode +*/ double SMESHGUI_ClippingDlg::getRotation1() const { - return SpinBoxRot1->GetValue(); + return TLValueRotation1->text().remove("\xB0").toInt(); } +/*! + Get rotation2 for cutting plane in relative mode +*/ double SMESHGUI_ClippingDlg::getRotation2() const { - return SpinBoxRot2->GetValue(); + return TLValueRotation2->text().remove("\xB0").toInt(); } -//======================================================================= -// function : ClickOnApply() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::ClickOnApply() +/*! + Set angles of clipping plane in relative mode +*/ +void SMESHGUI_ClippingDlg::setRotation (const double theRot1, const double theRot2) { - if (myViewWindow) { - SUIT_OverrideCursor wc; - - QWidget *aCurrWid = this->focusWidget(); - aCurrWid->clearFocus(); - aCurrWid->setFocus(); - - SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap(); - SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = aClippingPlaneInfoMap[ myViewWindow->getViewManager() ]; - - // clean memory allocated for planes - SMESHGUI_ClippingPlaneInfoList::iterator anIter1 = aClippingPlaneInfoList.begin(); - for( ; anIter1 != aClippingPlaneInfoList.end(); anIter1++ ) - if( SMESH::OrientedPlane* aPlane = (*anIter1).Plane ) - aPlane->Delete(); + SliderRotation1->setValue( theRot1 ); + SliderRotation2->setValue( theRot2 ); +} - aClippingPlaneInfoList.clear(); +/*! + Set coordinates of origin point in dialog box +*/ +void SMESHGUI_ClippingDlg::setOrigin( double theVal[3] ) +{ + int anOrientation = CBAbsoluteOrientation->currentIndex(); + if( anOrientation == 0 || anOrientation == 2 ) + SpinBox_X->setValue( theVal[0] ); + if( anOrientation == 0 || anOrientation == 3 ) + SpinBox_Y->setValue( theVal[1] ); + if( anOrientation == 0 || anOrientation == 1 ) + SpinBox_Z->setValue( theVal[2] ); +} - VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); - vtkActorCollection* anAllActors = aCopy.GetActors(); - anAllActors->InitTraversal(); - while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) - if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) - anActor->RemoveAllClippingPlanes(); +/*! + Set coordinates of normal vector in dialog box +*/ +void SMESHGUI_ClippingDlg::setDirection( double theVal[3] ) +{ + int anOrientation = CBAbsoluteOrientation->currentIndex(); + if( anOrientation == 0 ) { + SpinBox_Dx->setValue( theVal[0] ); + SpinBox_Dy->setValue( theVal[1] ); + SpinBox_Dz->setValue( theVal[2] ); + } +} - SMESH::TPlaneDataVector::iterator anIter2 = myPlanes.begin(); - for( ; anIter2 != myPlanes.end(); anIter2++ ) { - SMESH::TPlaneData aPlaneData = *anIter2; - SMESH::TPlane aPlane = aPlaneData.Plane; - SMESH::TActorList anActorList = aPlaneData.ActorList; +/*! + Create a new widget for preview clipping plane +*/ +vtkImplicitPlaneWidget* SMESHGUI_ClippingDlg::createPreviewWidget() +{ + vtkImplicitPlaneWidget* aPlaneWgt = vtkImplicitPlaneWidget::New(); - // the check is disabled to support planes with empty actor list - //if( anActorList.empty() ) - // continue; + aPlaneWgt->SetInteractor( myViewWindow->getInteractor() ); + aPlaneWgt->SetPlaceFactor( SIZEFACTOR ); + aPlaneWgt->ScaleEnabledOff(); + aPlaneWgt->SetOrigin( 0, 0, 0 ); + aPlaneWgt->SetNormal( -1, -1, -1 ); + aPlaneWgt->Off(); - SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow); - anOrientedPlane->ShallowCopy(aPlane.GetPointer()); + double anRGB[3]; + SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) ); - SMESH::TActorList::iterator anIter3 = anActorList.begin(); - for( ; anIter3 != anActorList.end(); anIter3++ ) - if( vtkActor* aVTKActor = *anIter3 ) - if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) - anActor->AddClippingPlane(anOrientedPlane); + aPlaneWgt->GetPlaneProperty()->SetColor( anRGB[0],anRGB[1],anRGB[2] ); + aPlaneWgt->GetPlaneProperty()->SetOpacity( 0.2 );; - SMESH::ClippingPlaneInfo aClippingPlaneInfo; - aClippingPlaneInfo.Plane = anOrientedPlane; - aClippingPlaneInfo.ActorList = anActorList; + aPlaneWgt->GetSelectedPlaneProperty()->SetColor( anRGB[0],anRGB[1],anRGB[2] ); + aPlaneWgt->GetSelectedPlaneProperty()->SetOpacity( 0.2 ); + aPlaneWgt->GetSelectedPlaneProperty()->SetLineWidth( 2.0 ); - aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); - } + aPlaneWgt->AddObserver(vtkCommand::InteractionEvent, myCallback, 0.); - SMESH::RenderViewWindow( myViewWindow ); - } + return aPlaneWgt; } -//======================================================================= -// function : ClickOnOk() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::ClickOnOk() +/*! + Translate two angles of plane to normal +*/ +void rotationToNormal ( double theRotation[2], + int theOrientation, + double theNormal[3], + double theDir[2][3] ) { - ClickOnApply(); - reject(); -} + static double aCoeff = M_PI/180.0; + + double anU[2] = { cos( aCoeff * theRotation[0] ), cos( aCoeff * theRotation[1] ) }; + double aV[2] = { sqrt( 1.0 - anU[0]*anU[0] ), sqrt( 1.0 - anU[1] * anU[1] ) }; + aV[0] = theRotation[0] > 0? aV[0]: -aV[0]; + aV[1] = theRotation[1] > 0? aV[1]: -aV[1]; + + switch ( theOrientation ) { + case 0: + case 1: + theDir[0][1] = anU[0]; + theDir[0][2] = aV[0]; + theDir[1][0] = anU[1]; + theDir[1][2] = aV[1]; + break; + case 2: + theDir[0][2] = anU[0]; + theDir[0][0] = aV[0]; + theDir[1][1] = anU[1]; + theDir[1][0] = aV[1]; + break; + case 3: + theDir[0][0] = anU[0]; + theDir[0][1] = aV[0]; + theDir[1][2] = anU[1]; + theDir[1][1] = aV[1]; + break; + } -//======================================================================= -// function : reject() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::reject() -{ - //here we can insert actions to do at close. - QDialog::reject(); + vtkMath::Cross( theDir[1], theDir[0], theNormal ); + vtkMath::Normalize( theNormal ); + vtkMath::Cross( theNormal, theDir[1], theDir[0] ); } -//================================================================================= -// function : ClickOnHelp() -// purpose : -//================================================================================= -void SMESHGUI_ClippingDlg::ClickOnHelp() +/*! + Used in SMESHGUI::restoreVisualParameters() to avoid + Declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx +*/ +bool SMESHGUI_ClippingDlg::AddPlane ( SMESH::TActorList theActorList, + SMESH::OrientedPlane* thePlane ) { - LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) - app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); - else { - QString platform; -#ifdef WIN32 - platform = "winapplication"; -#else - platform = "application"; -#endif - SUIT_MessageBox::warning(this, tr("WRN_WARNING"), - tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", - platform)). - arg(myHelpFileName)); + double aNormal[3]; + double aDir[2][3] = {{0, 0, 0}, {0, 0, 0}}; + static double aCoeff = vtkMath::Pi()/180.0; + + int anOrientation; + if ( thePlane->PlaneMode == SMESH::Absolute ) + anOrientation = thePlane->myAbsoluteOrientation; + else if ( thePlane->PlaneMode == SMESH::Relative ) + anOrientation = thePlane->myRelativeOrientation + 1; + + if ( anOrientation == 0 ) { + // compute a direction for plane in absolute mode + double znam = sqrt( thePlane->Dx*thePlane->Dx + thePlane->Dy*thePlane->Dy + thePlane->Dz*thePlane->Dz ); + double aRotation = acos( thePlane->Dy/znam )/aCoeff; + if ( thePlane->Dy >= 0.0 && thePlane->Dz >= 0.0 ) thePlane->myAngle[0] = 90.0 + aRotation; + else if ( thePlane->Dy >= 0.0 && thePlane->Dz < 0.0 ) thePlane->myAngle[0] = 90.0 - aRotation; + else if ( thePlane->Dy < 0.0 && thePlane->Dz >= 0.0 ) thePlane->myAngle[0] = aRotation - 90.0; + else if ( thePlane->Dy < 0.0 && thePlane->Dz < 0.0 ) thePlane->myAngle[0] = 270.0 - aRotation; + + aRotation = acos( thePlane->Dx/znam )/aCoeff; + if ( thePlane->Dx >= 0.0 && thePlane->Dz >= 0.0 ) thePlane->myAngle[1] = 90.0 + aRotation; + else if ( thePlane->Dx >= 0.0 && thePlane->Dz < 0.0 ) thePlane->myAngle[1] = 90.0 - aRotation; + else if ( thePlane->Dx < 0.0 && thePlane->Dz >= 0.0 ) thePlane->myAngle[1] = aRotation - 90.0; + else if ( thePlane->Dx < 0.0 && thePlane->Dz < 0.0 ) thePlane->myAngle[1] = 270.0 - aRotation; } -} -//======================================================================= -// function : onSelectPlane() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex) -{ - if (myPlanes.empty()) - return; + // compute a normal + rotationToNormal( thePlane->myAngle, anOrientation, aNormal, aDir ); - SMESH::TPlaneData aPlaneData = myPlanes[theIndex]; - SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer(); + double aBounds[6]; + double anOrigin[3]; - // Orientation - SMESH::Orientation anOrientation = aPlane->GetOrientation(); + if ( thePlane->PlaneMode == SMESH::Absolute ) { + aNormal[0] = thePlane->Dx; + aNormal[1] = thePlane->Dy; + aNormal[2] = thePlane->Dz; + } - // Rotations - double aRot[2] = {aPlane->myAngle[0], aPlane->myAngle[1]}; + bool anIsOk = false; + if( theActorList.empty() ) { + // to support planes with empty actor list we should create + // a nullified plane that will be initialized later + anOrigin[0] = anOrigin[1] = anOrigin[2] = 0; + aBounds[0] = aBounds[2] = aBounds[4] = 0; + aBounds[1] = aBounds[3] = aBounds[5] = 0; + anIsOk = true; + } + else + anIsOk = SMESH::ComputeClippingPlaneParameters( theActorList, + aNormal, + thePlane->myDistance, + aBounds, + anOrigin ); + if( !anIsOk ) + return false; - // Set plane parameters in the dialog - myIsSelectPlane = true; - setDistance(aPlane->GetDistance()); - setRotation(aRot[0], aRot[1]); - switch (anOrientation) { - case SMESH::XY: - ComboBoxOrientation->setCurrentIndex(0); - onSelectOrientation(0); - break; - case SMESH::YZ: - ComboBoxOrientation->setCurrentIndex(1); - onSelectOrientation(1); - break; - case SMESH::ZX: - ComboBoxOrientation->setCurrentIndex(2); - onSelectOrientation(2); - break; + if ( thePlane->PlaneMode == SMESH::Absolute ) { + anOrigin[0] = thePlane->X; + anOrigin[1] = thePlane->Y; + anOrigin[2] = thePlane->Z; } - myIsSelectPlane = false; + thePlane->SetNormal( aNormal ); + thePlane->SetOrigin( anOrigin ); - // Actors - bool anIsBlocked = ActorList->blockSignals( true ); - updateActorList(); - ActorList->blockSignals( anIsBlocked ); -} -//======================================================================= -// function : ClickOnNew() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::ClickOnNew() -{ - if(myViewWindow){ - SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(myViewWindow); - SMESH::TPlane aTPlane(aPlane); + double aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2., + ( aBounds[2] + aBounds[3] ) / 2., + ( aBounds[4] + aBounds[5] ) / 2. }; - SMESH::TActorList anActorList; - VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); - vtkActorCollection* anAllActors = aCopy.GetActors(); - anAllActors->InitTraversal(); - while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) - if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) - anActorList.push_back( anActor ); + double aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) + + pow( aBounds[3] - aBounds[2], 2 ) + + pow( aBounds[5] - aBounds[4], 2 ), 0.5 ); - SMESH::TPlaneData aPlaneData(aTPlane, anActorList); + double aDelta[2][3] = { { aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel }, + { aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel } }; + double aParam, aPnt0[3], aPnt1[3], aPnt2[3]; - myPlanes.push_back(aPlaneData); + double aPnt01[3] = { aPnt[0] - aDelta[0][0] - aDelta[1][0], + aPnt[1] - aDelta[0][1] - aDelta[1][1], + aPnt[2] - aDelta[0][2] - aDelta[1][2] }; + double aPnt02[3] = { aPnt01[0] + aNormal[0], + aPnt01[1] + aNormal[1], + aPnt01[2] + aNormal[2] }; + vtkPlane::IntersectWithLine( aPnt01, aPnt02, aNormal, anOrigin, aParam, aPnt0 ); + + double aPnt11[3] = { aPnt[0] - aDelta[0][0] + aDelta[1][0], + aPnt[1] - aDelta[0][1] + aDelta[1][1], + aPnt[2] - aDelta[0][2] + aDelta[1][2] }; + double aPnt12[3] = { aPnt11[0] + aNormal[0], + aPnt11[1] + aNormal[1], + aPnt11[2] + aNormal[2] }; + vtkPlane::IntersectWithLine( aPnt11, aPnt12, aNormal, anOrigin, aParam, aPnt1); + + double aPnt21[3] = { aPnt[0] + aDelta[0][0] - aDelta[1][0], + aPnt[1] + aDelta[0][1] - aDelta[1][1], + aPnt[2] + aDelta[0][2] - aDelta[1][2] }; + double aPnt22[3] = { aPnt21[0] + aNormal[0], + aPnt21[1] + aNormal[1], + aPnt21[2] + aNormal[2] }; + vtkPlane::IntersectWithLine( aPnt21, aPnt22, aNormal, anOrigin, aParam, aPnt2); + + vtkPlaneSource* aPlaneSource = thePlane->myPlaneSource; + aPlaneSource->SetNormal( aNormal[0], aNormal[1], aNormal[2] ); + aPlaneSource->SetOrigin( aPnt0[0], aPnt0[1], aPnt0[2] ); + aPlaneSource->SetPoint1( aPnt1[0], aPnt1[1], aPnt1[2] ); + aPlaneSource->SetPoint2( aPnt2[0], aPnt2[1], aPnt2[2] ); + aPlaneSource->Update(); - if (PreviewCheckBox->isChecked()) - aTPlane->myActor->VisibilityOn(); + SMESH::TActorList::iterator anIter = theActorList.begin(); + for ( ; anIter != theActorList.end(); anIter++ ) + if( vtkActor* aVTKActor = *anIter ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) { + if( thePlane->IsOpenGLClipping ) + anActor->AddOpenGLClippingPlane( thePlane->InvertPlane() ); + else + anActor->AddClippingPlane( thePlane ); + } - bool anIsBlocked = ActorList->blockSignals( true ); + return true; +} - synchronize(); - SetCurrentPlaneParam(); +/*! + Custom handling of events +*/ +void SMESHGUI_ClippingDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; - ActorList->blockSignals( anIsBlocked ); + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + ClickOnHelp(); } } -//======================================================================= -// function : ClickOnDelete() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::ClickOnDelete() +/*! + Handles the char preview widget activation event +*/ +void SMESHGUI_ClippingDlg::ProcessEvents( vtkObject* theObject, + unsigned long theEvent, + void* theClientData, + void* vtkNotUsed( theCallData ) ) { - if (myPlanes.empty()) - return; + vtkImplicitPlaneWidget* aWidget = vtkImplicitPlaneWidget::SafeDownCast( theObject ); + if ( aWidget == NULL ) return; + if ( theClientData == NULL ) return; - int aPlaneIndex = ComboBoxPlanes->currentIndex(); + SMESHGUI_ClippingDlg* aDlg = (SMESHGUI_ClippingDlg*) theClientData; - SMESH::TPlaneDataVector::iterator anIter = myPlanes.begin() + aPlaneIndex; - SMESH::TPlaneData aPlaneData = *anIter; - aPlaneData.Plane.GetPointer()->myActor->SetVisibility(false); - myPlanes.erase(anIter); + double anOrigin[3]; + double aDir[3]; - if(AutoApplyCheckBox->isChecked()) - ClickOnApply(); + switch( theEvent ){ + case vtkCommand::InteractionEvent: + aWidget->GetOrigin( anOrigin ); + aWidget->GetNormal( aDir ); - synchronize(); - SMESH::RenderViewWindow( myViewWindow ); -} - -//======================================================================= -// function : updateActorItem() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::updateActorItem( QListWidgetItem* theItem, - bool theUpdateSelectAll, - bool theUpdateClippingPlaneMap ) -{ - // update Select All check box - if( theUpdateSelectAll ) { - int aNbItems = ActorList->count(), aNbChecked = 0; - for( int i = 0; i < aNbItems; i++ ) - if( QListWidgetItem* anItem = ActorList->item( i ) ) - if( anItem->checkState() == Qt::Checked ) - aNbChecked++; - - bool anIsBlocked = SelectAllCheckBox->blockSignals( true ); - SelectAllCheckBox->setCheckState( aNbChecked == aNbItems ? Qt::Checked : Qt::Unchecked); - SelectAllCheckBox->blockSignals( anIsBlocked ); - } + aDlg->myIsSelectPlane = true; - // update clipping plane map - if( theUpdateClippingPlaneMap ) { - int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - if( ActorItem* anItem = dynamic_cast( theItem ) ) { - if( SMESH_Actor* anActor = anItem->getActor() ) { - SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ]; - SMESH::TActorList& anActorList = aPlaneData.ActorList; - bool anIsPushed = false; - SMESH::TActorList::iterator anIter = anActorList.begin(); - for ( ; anIter != anActorList.end(); anIter++ ) { - if( anActor == *anIter ) { - anIsPushed = true; - break; - } - } - if( theItem->checkState() == Qt::Checked && !anIsPushed ) - anActorList.push_back( anActor ); - else if( theItem->checkState() == Qt::Unchecked && anIsPushed ) - anActorList.remove( anActor ); - } + if( aDlg->CurrentMode == SMESH::Absolute ) { + aDlg->setOrigin( anOrigin ); + aDlg->setDirection( aDir ); + aDlg->myIsPreviewMoved = true; } - } -} + else if( aDlg->CurrentMode == SMESH::Relative ) { + aDlg->absolutePlaneToRelative( anOrigin, aDir ); + } + aDlg->myIsSelectPlane = false; -//======================================================================= -// function : onActorItemChanged() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::onActorItemChanged( QListWidgetItem* theItem ) -{ - updateActorItem( theItem, true, true ); - SetCurrentPlaneParam(); + aDlg->SetCurrentPlaneParam(); + aDlg->myIsPreviewMoved = false; + break; + } } -//======================================================================= -// function : onSelectAll() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::onSelectAll( int theState ) +/*! + Initialize the planes's data when the dialog opened +*/ +void SMESHGUI_ClippingDlg::initializePlaneData() { - if( theState == Qt::PartiallyChecked ) { - SelectAllCheckBox->setCheckState( Qt::Checked ); - return; - } - - bool anIsBlocked = ActorList->blockSignals( true ); - for( int i = 0, n = ActorList->count(); i < n; i++ ) { - if( QListWidgetItem* anItem = ActorList->item( i ) ) { - anItem->setCheckState( theState == Qt::Checked ? Qt::Checked : Qt::Unchecked ); - updateActorItem( anItem, false, true ); + const SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap(); + SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter1 = aClippingPlaneInfoMap.find( myViewWindow->getViewManager() ); + if( anIter1 != aClippingPlaneInfoMap.end() ) { + const SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second; + SMESHGUI_ClippingPlaneInfoList::const_iterator anIter2 = aClippingPlaneInfoList.begin(); + for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) { + const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2; + SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow); + anOrientedPlane->ShallowCopy(aClippingPlaneInfo.Plane); + SMESH::TPlane aTPlane( anOrientedPlane ); + SMESH::TPlaneData aPlaneData( aTPlane, aClippingPlaneInfo.ActorList ); + myPlanes.push_back( aPlaneData ); } } - SelectAllCheckBox->setTristate( false ); - ActorList->blockSignals( anIsBlocked ); - SetCurrentPlaneParam(); + std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) ); + if( myPlanes.size() ) + myPreviewWidget->SetEnabled( PreviewCheckBox->isChecked() ); } -//======================================================================= -// function : onSelectOrientation() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::onSelectOrientation (int theItem) +/*! + Initialization of initial values of widgets +*/ +void SMESHGUI_ClippingDlg::initParam() { - if (myPlanes.empty()) - return; - - if (theItem == 0) { - TextLabelRot1->setText(tr("ROTATION_AROUND_X_Y2Z")); - TextLabelRot2->setText(tr("ROTATION_AROUND_Y_X2Z")); - } - else if (theItem == 1) { - TextLabelRot1->setText(tr("ROTATION_AROUND_Y_Z2X")); - TextLabelRot2->setText(tr("ROTATION_AROUND_Z_Y2X")); - } - else if (theItem == 2) { - TextLabelRot1->setText(tr("ROTATION_AROUND_Z_X2Y")); - TextLabelRot2->setText(tr("ROTATION_AROUND_X_Z2Y")); - } - - if((QComboBox*)sender() == ComboBoxOrientation) - SetCurrentPlaneParam(); + SpinBox_X->setValue( 0.0 ); + SpinBox_Y->setValue( 0.0 ); + SpinBox_Z->setValue( 0.0 ); + + SpinBox_Dx->setValue( 1.0 ); + SpinBox_Dy->setValue( 1.0 ); + SpinBox_Dz->setValue( 1.0 ); + + CBAbsoluteOrientation->setCurrentIndex(0); + + TLValueDistance->setText( "0.5" ); + TLValueRotation1->setText( "0\xB0" ); + TLValueRotation2->setText( "0\xB0" ); + CBRelativeOrientation->setCurrentIndex( 0 ); + SliderDistance->setValue( 50 ); + SliderRotation1->setValue( 0 ); + SliderRotation2->setValue( 0 ); } -//======================================================================= -// function : synchronize() -// purpose : -//======================================================================= +/*! + Synchronize dialog's widgets with data +*/ void SMESHGUI_ClippingDlg::synchronize() { int aNbPlanes = myPlanes.size(); ComboBoxPlanes->clear(); QString aName; - for(int i = 1; i<=aNbPlanes; i++) { - aName = QString(tr("PLANE_NUM")).arg(i); - ComboBoxPlanes->addItem(aName); + for( int i = 1; i<=aNbPlanes; i++ ) { + aName = QString( tr( "PLANE_NUM" ) ).arg(i); + ComboBoxPlanes->addItem( aName ); } int aPos = ComboBoxPlanes->count() - 1; - ComboBoxPlanes->setCurrentIndex(aPos); + ComboBoxPlanes->setCurrentIndex( aPos ); - bool anIsControlsEnable = (aPos >= 0); - if (anIsControlsEnable) { - onSelectPlane(aPos); + bool anIsControlsEnable = ( aPos >= 0 ); + if ( anIsControlsEnable ) { + onSelectPlane( aPos ); updateActorList(); - } else { - ComboBoxPlanes->addItem(tr("NO_PLANES")); - ActorList->clear(); - SpinBoxRot1->SetValue(0.0); - SpinBoxRot2->SetValue(0.0); - SpinBoxDistance->SetValue(0.5); - } - - ActorList->setEnabled(anIsControlsEnable); - SelectAllCheckBox->setEnabled(anIsControlsEnable); - buttonDelete->setEnabled(anIsControlsEnable); - // the following 3 controls should be enabled - //buttonApply->setEnabled(anIsControlsEnable); - //PreviewCheckBox->setEnabled(anIsControlsEnable); - //AutoApplyCheckBox->setEnabled(anIsControlsEnable); - ComboBoxOrientation->setEnabled(anIsControlsEnable); - SpinBoxDistance->setEnabled(anIsControlsEnable); - SpinBoxRot1->setEnabled(anIsControlsEnable); - SpinBoxRot2->setEnabled(anIsControlsEnable); -} - -//======================================================================= -// function : setRotation() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::setRotation (const double theRot1, const double theRot2) -{ - SpinBoxRot1->SetValue(theRot1); - SpinBoxRot2->SetValue(theRot2); -} - -//======================================================================= -// function : SetCurrentPlaneParam() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::SetCurrentPlaneParam() -{ - if (myPlanes.empty() || myIsSelectPlane) - return; - - int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - - SMESH::TPlaneData aPlaneData = myPlanes[aCurPlaneIndex]; - SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer(); - - double aNormal[3]; - SMESH::Orientation anOrientation; - double aDir[3][3] = {{0, 0, 0}, {0, 0, 0}}; - { - static double aCoeff = vtkMath::Pi()/180.0; - - double aRot[2] = {getRotation1(), getRotation2()}; - aPlane->myAngle[0] = aRot[0]; - aPlane->myAngle[1] = aRot[1]; - - double anU[2] = {cos(aCoeff*aRot[0]), cos(aCoeff*aRot[1])}; - double aV[2] = {sqrt(1.0-anU[0]*anU[0]), sqrt(1.0-anU[1]*anU[1])}; - aV[0] = aRot[0] > 0? aV[0]: -aV[0]; - aV[1] = aRot[1] > 0? aV[1]: -aV[1]; - - switch (ComboBoxOrientation->currentIndex()) { - case 0: - anOrientation = SMESH::XY; - - aDir[0][1] = anU[0]; - aDir[0][2] = aV[0]; - - aDir[1][0] = anU[1]; - aDir[1][2] = aV[1]; - - break; - case 1: - anOrientation = SMESH::YZ; - - aDir[0][2] = anU[0]; - aDir[0][0] = aV[0]; - - aDir[1][1] = anU[1]; - aDir[1][0] = aV[1]; - - break; - case 2: - anOrientation = SMESH::ZX; - - aDir[0][0] = anU[0]; - aDir[0][1] = aV[0]; - - aDir[1][2] = anU[1]; - aDir[1][1] = aV[1]; - - break; - } - - vtkMath::Cross(aDir[1],aDir[0],aNormal); - vtkMath::Normalize(aNormal); - vtkMath::Cross(aNormal,aDir[1],aDir[0]); + if( PreviewCheckBox->isChecked() ) + myPreviewWidget->On(); } - - aPlane->SetOrientation(anOrientation); - aPlane->SetDistance(getDistance()); - - SMESH::TActorList anActorList = aPlaneData.ActorList; - - double aBounds[6]; - double anOrigin[3]; - bool anIsOk = SMESH::ComputeClippingPlaneParameters( anActorList, - aNormal, - getDistance(), - aBounds, - anOrigin ); - - aPlane->myActor->SetVisibility( anIsOk && PreviewCheckBox->isChecked() ); - - if( anIsOk ) { - aPlane->SetNormal( aNormal ); - aPlane->SetOrigin( anOrigin ); - - double aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2., - ( aBounds[2] + aBounds[3] ) / 2., - ( aBounds[4] + aBounds[5] ) / 2. }; - - double aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) + - pow( aBounds[3] - aBounds[2], 2 ) + - pow( aBounds[5] - aBounds[4], 2 ), 0.5 ); - - double aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel}, - {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}}; - double aParam, aPnt0[3], aPnt1[3], aPnt2[3]; - - double aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0], - aPnt[1] - aDelta[0][1] - aDelta[1][1], - aPnt[2] - aDelta[0][2] - aDelta[1][2]}; - double aPnt02[3] = {aPnt01[0] + aNormal[0], - aPnt01[1] + aNormal[1], - aPnt01[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0); - - double aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0], - aPnt[1] - aDelta[0][1] + aDelta[1][1], - aPnt[2] - aDelta[0][2] + aDelta[1][2]}; - double aPnt12[3] = {aPnt11[0] + aNormal[0], - aPnt11[1] + aNormal[1], - aPnt11[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1); - - double aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0], - aPnt[1] + aDelta[0][1] - aDelta[1][1], - aPnt[2] + aDelta[0][2] - aDelta[1][2]}; - double aPnt22[3] = {aPnt21[0] + aNormal[0], - aPnt21[1] + aNormal[1], - aPnt21[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2); - - vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource; - aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]); - aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]); - aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]); - aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]); - aPlaneSource->Update(); + else { + ComboBoxPlanes->addItem( tr( "NO_PLANES" ) ); + ActorList->clear(); + initParam(); + if( PreviewCheckBox->isChecked() ) + myPreviewWidget->Off(); } - if(AutoApplyCheckBox->isChecked()) - ClickOnApply(); - - SMESH::RenderViewWindow( myViewWindow ); -} - -//======================================================================= -// function : OnPreviewToggle() -// purpose : -//======================================================================= -void SMESHGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled) -{ - std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(theIsToggled)); - SMESH::RenderViewWindow( myViewWindow ); -} - -//================================================================================= -// function : keyPressEvent() -// purpose : -//================================================================================= -void SMESHGUI_ClippingDlg::keyPressEvent( QKeyEvent* e ) -{ - QDialog::keyPressEvent( e ); - if ( e->isAccepted() ) - return; - - if ( e->key() == Qt::Key_F1 ) { - e->accept(); - ClickOnHelp(); + isOpenGLClipping->setEnabled( anIsControlsEnable ); + ActorList->setEnabled( anIsControlsEnable ); + SelectAllCheckBox->setEnabled( anIsControlsEnable ); + buttonDelete->setEnabled( anIsControlsEnable ); + if ( CurrentMode == SMESH::Absolute ) { + SpinBox_X->setEnabled( anIsControlsEnable ); + SpinBox_Y->setEnabled( anIsControlsEnable ); + SpinBox_Z->setEnabled( anIsControlsEnable ); + SpinBox_Dx->setEnabled( anIsControlsEnable ); + SpinBox_Dy->setEnabled( anIsControlsEnable ); + SpinBox_Dz->setEnabled( anIsControlsEnable ); + CBAbsoluteOrientation->setEnabled( anIsControlsEnable ); + invertButton->setEnabled( anIsControlsEnable ); + resetButton->setEnabled( anIsControlsEnable ); } -} - -//================================================================================= -// function : initializePlaneData() -// purpose : -//================================================================================= -void SMESHGUI_ClippingDlg::initializePlaneData() -{ - const SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap(); - SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter1 = aClippingPlaneInfoMap.find( myViewWindow->getViewManager() ); - if( anIter1 != aClippingPlaneInfoMap.end() ) { - const SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second; - SMESHGUI_ClippingPlaneInfoList::const_iterator anIter2 = aClippingPlaneInfoList.begin(); - for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) { - const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2; - SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow); - anOrientedPlane->ShallowCopy(aClippingPlaneInfo.Plane); - SMESH::TPlane aTPlane( anOrientedPlane ); - SMESH::TPlaneData aPlaneData( aTPlane, aClippingPlaneInfo.ActorList ); - myPlanes.push_back( aPlaneData ); - } + else if ( CurrentMode == SMESH::Relative ) { + CBRelativeOrientation->setEnabled( anIsControlsEnable ); + SliderDistance->setEnabled( anIsControlsEnable ); + SliderRotation1->setEnabled( anIsControlsEnable ); + SliderRotation2->setEnabled( anIsControlsEnable ); } - std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) ); } -//================================================================================= -// function : updateActorList() -// purpose : -//================================================================================= +/*! + Update the list of actors +*/ void SMESHGUI_ClippingDlg::updateActorList() { ActorList->clear(); @@ -1097,6 +1099,9 @@ void SMESHGUI_ClippingDlg::updateActorList() const SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ]; const SMESH::TActorList& anActorList = aPlaneData.ActorList; + std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) ); + aPlaneData.Plane.GetPointer()->myActor->SetVisibility( false ); + VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); vtkActorCollection* anAllActors = aCopy.GetActors(); anAllActors->InitTraversal(); @@ -1127,10 +1132,57 @@ void SMESHGUI_ClippingDlg::updateActorList() } } -//================================================================================= -// function : getCurrentActors() -// purpose : -//================================================================================= +/*! + Update an actor in actor's list +*/ +void SMESHGUI_ClippingDlg::updateActorItem( QListWidgetItem* theItem, + bool theUpdateSelectAll, + bool theUpdateClippingPlaneMap ) +{ + // update Select All check box + if( theUpdateSelectAll ) { + int aNbItems = ActorList->count(), aNbChecked = 0; + for( int i = 0; i < aNbItems; i++ ) + if( QListWidgetItem* anItem = ActorList->item( i ) ) + if( anItem->checkState() == Qt::Checked ) + aNbChecked++; + + bool anIsBlocked = SelectAllCheckBox->blockSignals( true ); + SelectAllCheckBox->setCheckState( aNbChecked == aNbItems ? Qt::Checked : Qt::Unchecked); + SelectAllCheckBox->blockSignals( anIsBlocked ); + } + + // update clipping plane map + if( theUpdateClippingPlaneMap ) { + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + if( ActorItem* anItem = dynamic_cast( theItem ) ) { + if( SMESH_Actor* anActor = anItem->getActor() ) { + SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ]; + SMESH::TActorList& anActorList = aPlaneData.ActorList; + bool anIsPushed = false; + SMESH::TActorList::iterator anIter = anActorList.begin(); + for ( ; anIter != anActorList.end(); anIter++ ) { + if( anActor == *anIter ) { + anIsPushed = true; + break; + } + } + if( theItem->checkState() == Qt::Checked && !anIsPushed ) + anActorList.push_back( anActor ); + else if( theItem->checkState() == Qt::Unchecked && anIsPushed ) + anActorList.remove( anActor ); + + SMESH::ComputeBounds( anActorList, myBounds ); + myPreviewWidget->PlaceWidget( myBounds[0], myBounds[1], myBounds[2], + myBounds[3], myBounds[4], myBounds[5] ); + } + } + } +} + +/*! + Get the list of current actors +*/ SMESH::TActorList SMESHGUI_ClippingDlg::getCurrentActors() { SMESH::TActorList anActorList; @@ -1142,10 +1194,9 @@ SMESH::TActorList SMESHGUI_ClippingDlg::getCurrentActors() return anActorList; } -//================================================================================= -// function : dumpPlaneData() -// purpose : -//================================================================================= +/*! + Dump the parameters of clipping planes +*/ void SMESHGUI_ClippingDlg::dumpPlaneData() const { printf( "----------- Plane Data -----------\n" ); @@ -1174,7 +1225,789 @@ void SMESHGUI_ClippingDlg::dumpPlaneData() const printf( "----------------------------------\n" ); } -void SMESHGUI_ClippingDlg::onAutoApply(bool toggled) +/*! + SLOT on close button click: rejects dialog +*/ +void SMESHGUI_ClippingDlg::reject() { - if ( toggled ) ClickOnApply(); + //here we can insert actions to do at close. + QDialog::reject(); +} + +/*! + Set absolute mode of clipping plane +*/ +void SMESHGUI_ClippingDlg::onModeAbsolute() +{ + ModeStackedLayout->setCurrentIndex(0); + CurrentMode = SMESH::Absolute; + ClickOnNew(); + SetCurrentPlaneParam(); +} + +/*! + Set relative mode of clipping plane +*/ +void SMESHGUI_ClippingDlg::onModeRelative() +{ + ModeStackedLayout->setCurrentIndex(1); + CurrentMode = SMESH::Relative; + ClickOnNew(); + SetCurrentPlaneParam(); } + +/*! + SLOT on new button click: create a new clipping plane +*/ +void SMESHGUI_ClippingDlg::ClickOnNew() +{ + if(myViewWindow) { + SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(myViewWindow); + SMESH::TPlane aTPlane(aPlane); + aPlane->PlaneMode = CurrentMode; + SMESH::TActorList anActorList; + VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); + vtkActorCollection* anAllActors = aCopy.GetActors(); + anAllActors->InitTraversal(); + while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActorList.push_back( anActor ); + + SMESH::TPlaneData aPlaneData(aTPlane, anActorList); + + myPlanes.push_back(aPlaneData); + + + std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) ); + aPlane->myActor->SetVisibility( false ); + + bool anIsBlocked = ActorList->blockSignals( true ); + + SMESH::ComputeBounds( anActorList, myBounds ); + myPreviewWidget->PlaceWidget( myBounds[0],myBounds[1],myBounds[2], + myBounds[3],myBounds[4],myBounds[5] ); + synchronize(); + SetCurrentPlaneParam(); + + ActorList->blockSignals( anIsBlocked ); + } +} + +/*! + SLOT on delete button click: Delete selected clipping plane +*/ +void SMESHGUI_ClippingDlg::ClickOnDelete() +{ + if (myPlanes.empty()) + return; + + int aPlaneIndex = ComboBoxPlanes->currentIndex(); + + SMESH::TPlaneDataVector::iterator anIter = myPlanes.begin() + aPlaneIndex; + SMESH::TPlaneData aPlaneData = *anIter; + aPlaneData.Plane.GetPointer()->myActor->SetVisibility(false); + myPlanes.erase(anIter); + + if(AutoApplyCheckBox->isChecked()) + ClickOnApply(); + + synchronize(); + SMESH::RenderViewWindow( myViewWindow ); +} + +/*! + Set current parameters of selected plane +*/ +void SMESHGUI_ClippingDlg::onSelectPlane ( int theIndex ) +{ + if ( myPlanes.empty() ) + return; + + SMESH::TPlaneData aPlaneData = myPlanes[theIndex]; + SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer(); + + myIsSelectPlane = true; + isOpenGLClipping->setChecked( aPlane->IsOpenGLClipping ); + + if ( aPlane->PlaneMode == SMESH::Absolute ) { + ModeStackedLayout->setCurrentIndex( 0 ); + CurrentMode = SMESH::Absolute; + int anOrientation = aPlane->myAbsoluteOrientation; + // Set plane parameters in the dialog + double anOrigin[3], aDir[3]; + anOrigin[0] = aPlane->X; + anOrigin[1] = aPlane->Y; + anOrigin[2] = aPlane->Z; + setOrigin( anOrigin ); + aDir[0] = aPlane->Dx; + aDir[1] = aPlane->Dy; + aDir[2] = aPlane->Dz; + setDirection( aDir ); + CBAbsoluteOrientation->setCurrentIndex( anOrientation ); + onSelectAbsoluteOrientation( anOrientation ); + } + else if ( aPlane->PlaneMode == SMESH::Relative ) { + ModeStackedLayout->setCurrentIndex( 1 ); + CurrentMode = SMESH::Relative; + SMESH::Orientation anOrientation = aPlane->GetOrientation(); + double aRot[2] = { aPlane->myAngle[0], aPlane->myAngle[1] }; + // Set plane parameters in the dialog + setDistance( aPlane->GetDistance() ); + setRotation( aRot[0], aRot[1] ); + switch ( anOrientation ) { + case SMESH::XY: + CBRelativeOrientation->setCurrentIndex(0); + onSelectRelativeOrientation(0); + break; + case SMESH::YZ: + CBRelativeOrientation->setCurrentIndex(1); + onSelectRelativeOrientation(1); + break; + case SMESH::ZX: + CBRelativeOrientation->setCurrentIndex(2); + onSelectRelativeOrientation(2); + break; + } + } + myIsSelectPlane = false; + SMESH::ComputeBounds( aPlaneData.ActorList, myBounds ); + myPreviewWidget->PlaceWidget( myBounds[0], myBounds[1], myBounds[2], + myBounds[3], myBounds[4], myBounds[5] ); + SetCurrentPlaneParam(); + + // Actors + bool anIsBlocked = ActorList->blockSignals( true ); + updateActorList(); + ActorList->blockSignals( anIsBlocked ); +} + +/*! + SLOT: called on OpenGLClipping check box toggled +*/ +void SMESHGUI_ClippingDlg::onIsOpenGLClipping( bool toggled ) +{ + if ( myPlanes.empty() || myIsSelectPlane ) + return; + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + SMESH::TPlaneData aPlane = myPlanes[aCurPlaneIndex]; + SMESH::OrientedPlane* aPlaneData = aPlane.Plane.GetPointer(); + aPlaneData->IsOpenGLClipping = toggled; + + if( AutoApplyCheckBox->isChecked() ) + ClickOnApply(); +} + +/*! + SLOT: called on SelectAll check box toggled +*/ +void SMESHGUI_ClippingDlg::onSelectAll( int theState ) +{ + if( theState == Qt::PartiallyChecked ) { + SelectAllCheckBox->setCheckState( Qt::Checked ); + return; + } + + bool anIsBlocked = ActorList->blockSignals( true ); + for( int i = 0, n = ActorList->count(); i < n; i++ ) { + if( QListWidgetItem* anItem = ActorList->item( i ) ) { + anItem->setCheckState( theState == Qt::Checked ? Qt::Checked : Qt::Unchecked ); + updateActorItem( anItem, false, true ); + } + } + SelectAllCheckBox->setTristate( false ); + ActorList->blockSignals( anIsBlocked ); + SetCurrentPlaneParam(); +} + +/*! + SLOT: called when actor item was changed +*/ +void SMESHGUI_ClippingDlg::onActorItemChanged( QListWidgetItem* theItem ) +{ + updateActorItem( theItem, true, true ); + SetCurrentPlaneParam(); +} + +/*! + Restore parameters of selected plane +*/ +void SMESHGUI_ClippingDlg::SetCurrentPlaneParam() +{ + if ( myPlanes.empty() || myIsSelectPlane ) + return; + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + + SMESH::TPlaneData aPlaneData = myPlanes[aCurPlaneIndex]; + SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer(); + + if ( aPlane->PlaneMode == SMESH::Absolute ) { + aPlane->myAbsoluteOrientation = CBAbsoluteOrientation->currentIndex(); + aPlane->X = SpinBox_X->value(); + aPlane->Y = SpinBox_Y->value(); + aPlane->Z = SpinBox_Z->value(); + aPlane->Dx = SpinBox_Dx->value(); + aPlane->Dy = SpinBox_Dy->value(); + aPlane->Dz = SpinBox_Dz->value(); + } + + double aNormal[3]; + double aDir[2][3] = { {0, 0, 0}, {0, 0, 0} }; + static double aCoeff = vtkMath::Pi()/180.0; + + double aRot[2] = { getRotation1(), getRotation2() }; + int anOrient; + if ( aPlane->PlaneMode == SMESH::Absolute ) + anOrient = CBAbsoluteOrientation->currentIndex(); + else if ( aPlane->PlaneMode == SMESH::Relative ) + anOrient = CBRelativeOrientation->currentIndex() + 1; + + if ( aPlane->PlaneMode == SMESH::Relative ) { + aPlane->myAngle[0] = aRot[0]; + aPlane->myAngle[1] = aRot[1]; + aPlane->SetOrientation( SMESH::Orientation( CBRelativeOrientation->currentIndex() ) ); + aPlane->SetDistance( getDistance() ); + } + + if ( anOrient == 0 ) { + // compute a direction for plane in absolute mode + double znam = sqrt( aPlane->Dx*aPlane->Dx + aPlane->Dy*aPlane->Dy + aPlane->Dz*aPlane->Dz ); + double aRotation = acos( aPlane->Dy/znam )/aCoeff; + if ( aPlane->Dy >= 0.0 && aPlane->Dz >= 0.0 ) aRot[0] = 90.0 + aRotation; + else if ( aPlane->Dy >= 0.0 && aPlane->Dz < 0.0 ) aRot[0] = 90.0 - aRotation; + else if ( aPlane->Dy < 0.0 && aPlane->Dz >= 0.0 ) aRot[0] = aRotation - 90.0; + else if ( aPlane->Dy < 0.0 && aPlane->Dz < 0.0 ) aRot[0] = 270.0 - aRotation; + + aRotation = acos( aPlane->Dx/znam )/aCoeff; + if ( aPlane->Dx >= 0.0 && aPlane->Dz >= 0.0 ) aRot[1] = 90.0 + aRotation; + else if ( aPlane->Dx >= 0.0 && aPlane->Dz < 0.0 ) aRot[1] = 90.0 - aRotation; + else if ( aPlane->Dx < 0.0 && aPlane->Dz >= 0.0 ) aRot[1] = aRotation - 90.0; + else if ( aPlane->Dx < 0.0 && aPlane->Dz < 0.0 ) aRot[1] = 270.0 - aRotation; + } + + // compute a normal + rotationToNormal( aRot, anOrient, aNormal, aDir ); + + + SMESH::TActorList anActorList = aPlaneData.ActorList; + + double aBounds[6]; + double anOrigin[3]; + double aDistance; + aDistance = getDistance(); + if ( aPlane->PlaneMode == SMESH::Absolute ) { + aNormal[0] = aPlane->Dx; + aNormal[1] = aPlane->Dy; + aNormal[2] = aPlane->Dz; + } + + bool anIsOk = SMESH::ComputeClippingPlaneParameters( anActorList, + aNormal, + aDistance, + aBounds, + anOrigin ); + + if ( aPlane->PlaneMode == SMESH::Absolute ) { + anOrigin[0] = aPlane->X; + anOrigin[1] = aPlane->Y; + anOrigin[2] = aPlane->Z; + } + + if( anIsOk ) { + aPlane->SetNormal( aNormal ); + aPlane->SetOrigin( anOrigin ); + + double aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2., + ( aBounds[2] + aBounds[3] ) / 2., + ( aBounds[4] + aBounds[5] ) / 2. }; + + double aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) + + pow( aBounds[3] - aBounds[2], 2 ) + + pow( aBounds[5] - aBounds[4], 2 ), 0.5 ); + + double aDelta[2][3] = { { aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel }, + { aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel } }; + double aParam, aPnt0[3], aPnt1[3], aPnt2[3]; + + double aPnt01[3] = { aPnt[0] - aDelta[0][0] - aDelta[1][0], + aPnt[1] - aDelta[0][1] - aDelta[1][1], + aPnt[2] - aDelta[0][2] - aDelta[1][2] }; + double aPnt02[3] = { aPnt01[0] + aNormal[0], + aPnt01[1] + aNormal[1], + aPnt01[2] + aNormal[2] }; + vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0); + + double aPnt11[3] = { aPnt[0] - aDelta[0][0] + aDelta[1][0], + aPnt[1] - aDelta[0][1] + aDelta[1][1], + aPnt[2] - aDelta[0][2] + aDelta[1][2] }; + double aPnt12[3] = { aPnt11[0] + aNormal[0], + aPnt11[1] + aNormal[1], + aPnt11[2] + aNormal[2] }; + vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1); + + double aPnt21[3] = { aPnt[0] + aDelta[0][0] - aDelta[1][0], + aPnt[1] + aDelta[0][1] - aDelta[1][1], + aPnt[2] + aDelta[0][2] - aDelta[1][2] }; + double aPnt22[3] = { aPnt21[0] + aNormal[0], + aPnt21[1] + aNormal[1], + aPnt21[2] + aNormal[2] }; + vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2); + + vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource; + + aPlaneSource->SetNormal( aNormal[0], aNormal[1], aNormal[2] ); + aPlaneSource->SetOrigin( aPnt0[0], aPnt0[1], aPnt0[2] ); + aPlaneSource->SetPoint1( aPnt1[0], aPnt1[1], aPnt1[2] ); + aPlaneSource->SetPoint2( aPnt2[0], aPnt2[1], aPnt2[2] ); + aPlaneSource->Update(); + } + + setBoundsForPreviewWidget(); + + myPreviewWidget->SetOrigin( anOrigin ); + myPreviewWidget->SetNormal( aNormal ); + + if(AutoApplyCheckBox->isChecked()) + ClickOnApply(); + + SMESH::RenderViewWindow( myViewWindow ); +} + +/*! + Set current bounds for preview widget +*/ +void SMESHGUI_ClippingDlg::setBoundsForPreviewWidget() +{ + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + SMESH::TPlaneData aPlaneData = myPlanes[aCurPlaneIndex]; + SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer(); + SMESH::TActorList anActorList = aPlaneData.ActorList; + + double* anOrigin = aPlane->GetOrigin(); + + double aBounds[6]; + SMESH::ComputeBounds( anActorList, aBounds ); + + bool isBoundsChanged = false; + + if( myIsPreviewMoved ) { + // if widget has moved by hand the bounds can to minimize + if( anOrigin[0] > myBounds[0] && anOrigin[0] < aBounds[0] ) { + myBounds[0] = anOrigin[0]; isBoundsChanged = true; } + if( anOrigin[0] < myBounds[1] && anOrigin[0] > aBounds[1] ) { + myBounds[1] = anOrigin[0]; isBoundsChanged = true; } + if( anOrigin[1] > myBounds[2] && anOrigin[1] < aBounds[2] ) { + myBounds[2] = anOrigin[1]; isBoundsChanged = true; } + if( anOrigin[1] < myBounds[3] && anOrigin[1] > aBounds[3] ) { + myBounds[3] = anOrigin[1]; isBoundsChanged = true; } + if( anOrigin[2] > myBounds[4] && anOrigin[2] < aBounds[4] ) { + myBounds[4] = anOrigin[2]; isBoundsChanged = true; } + if( anOrigin[2] < myBounds[5] && anOrigin[2] > aBounds[5] ) { + myBounds[5] = anOrigin[2]; isBoundsChanged = true; } + } + else { + // if widget has moved by dialog data the bounds can to take necessary size + if( anOrigin[0] < aBounds[0] ) { + myBounds[0] = anOrigin[0]; isBoundsChanged = true; } + if( anOrigin[0] > aBounds[1] ) { + myBounds[1] = anOrigin[0]; isBoundsChanged = true; } + if( anOrigin[1] < aBounds[2] ) { + myBounds[2] = anOrigin[1]; isBoundsChanged = true; } + if( anOrigin[1] > aBounds[3] ) { + myBounds[3] = anOrigin[1]; isBoundsChanged = true; } + if( anOrigin[2] < aBounds[4] ) { + myBounds[4] = anOrigin[2]; isBoundsChanged = true; } + if( anOrigin[2] > aBounds[5] ) { + myBounds[5] = anOrigin[2]; isBoundsChanged = true; } + } + + if( isBoundsChanged ) + myPreviewWidget->PlaceWidget( myBounds[0],myBounds[1],myBounds[2], + myBounds[3],myBounds[4],myBounds[5] ); + else if( !myIsPreviewMoved ) + myPreviewWidget->PlaceWidget( aBounds[0],aBounds[1],aBounds[2], + aBounds[3],aBounds[4],aBounds[5] ); + +} + +/*! + Convert absolute coordinates of plane to relative mode +*/ +void SMESHGUI_ClippingDlg::absolutePlaneToRelative ( double theOrigin[3], double theDir[3] ) +{ + double aRot[2]; + + aRot[0] = getRotation1(); + aRot[1] = getRotation2(); + + double eps = 0.0001; + + int anOrientation = CBRelativeOrientation->currentIndex(); + double aDirection[3]; + double aRotation1, aRotation2; + switch( anOrientation ) { + case 0: + aDirection[0] = theDir[0] + eps; + aDirection[1] = theDir[1] + eps; + aDirection[2] = theDir[2] + eps; + aRotation1 = atan2( theDir[2], theDir[1] )*180.0/M_PI; + aRotation2 = atan2( theDir[2], theDir[0] )*180.0/M_PI; + break; + case 1: + aDirection[0] = theDir[1] + eps; + aDirection[1] = theDir[2] + eps; + aDirection[2] = theDir[0] + eps; + aRotation1 = atan2( theDir[0], theDir[2] )*180.0/M_PI; + aRotation2 = atan2( theDir[0], theDir[1] )*180.0/M_PI; + break; + case 2: + aDirection[0] = theDir[2] + eps; + aDirection[1] = theDir[0] + eps; + aDirection[2] = theDir[1] + eps; + aRotation1 = atan2( theDir[1], theDir[0] )*180.0/M_PI; + aRotation2 = atan2( theDir[1], theDir[2] )*180.0/M_PI; + break; + } + + if( aDirection[0] > 0 && aDirection[1] > 0 && aDirection[2] > 0 && aRot[0] <= 0 ) { + aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 - 90.0; } + else if( aDirection[0] > 0 && aDirection[1] > 0 && aDirection[2] > 0 && aRot[0] > 0 ) { + aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 + 90.0; } + else if( aDirection[0] > 0 && aDirection[1] > 0 && aDirection[2] < 0 && aRot[0] <= 0 ) { + aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 + 90.0; } + else if( aDirection[0] > 0 && aDirection[1] > 0 && aDirection[2] < 0 && aRot[0] > 0 ) { + aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 - 90.0; } + else if( aDirection[0] > 0 && aDirection[1] < 0 && aDirection[2] > 0 && aRot[0] <= 0 ) { + aRot[0] = aRotation1 - 270.0; aRot[1] = aRotation2 + 90.0; } + else if( aDirection[0] > 0 && aDirection[1] < 0 && aDirection[2] > 0 && aRot[0] > 0 ) { + aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 - 90.0; } + else if( aDirection[0] > 0 && aDirection[1] < 0 && aDirection[2] < 0 && aRot[0] <= 0 ) { + aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 - 90.0; } + else if( aDirection[0] > 0 && aDirection[1] < 0 && aDirection[2] < 0 && aRot[0] > 0 ) { + aRot[0] = aRotation1 + 270.0; aRot[1] = aRotation2 + 90.0; } + else if( aDirection[0] < 0 && aDirection[1] > 0 && aDirection[2] > 0 && aRot[0] <= 0 ) { + aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 - 90.0; } + else if( aDirection[0] < 0 && aDirection[1] > 0 && aDirection[2] > 0 && aRot[0] > 0 ) { + aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 - 270.0; } + else if( aDirection[0] < 0 && aDirection[1] > 0 && aDirection[2] < 0 && aRot[0] <= 0 ) { + aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 + 90.0; } + else if( aDirection[0] < 0 && aDirection[1] > 0 && aDirection[2] < 0 && aRot[0] > 0 ) { + aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 + 270.0; } + else if( aDirection[0] < 0 && aDirection[1] < 0 && aDirection[2] > 0 && aRot[0] <= 0 ) { + aRot[0] = aRotation1 - 270.0; aRot[1] = aRotation2 - 270.0; } + else if( aDirection[0] < 0 && aDirection[1] < 0 && aDirection[2] > 0 && aRot[0] > 0 ) { + aRot[0] = aRotation1 - 90.0; aRot[1] = aRotation2 - 90.0; } + else if( aDirection[0] < 0 && aDirection[1] < 0 && aDirection[2] < 0 && aRot[0] <= 0 ) { + aRot[0] = aRotation1 + 90.0; aRot[1] = aRotation2 + 270.0; } + else if( aDirection[0] < 0 && aDirection[1] < 0 && aDirection[2] < 0 && aRot[0] > 0 ) { + aRot[0] = aRotation1 + 270.0; aRot[1] = aRotation2 + 90.0; } + + SliderRotation1HasMoved( round( aRot[0] ) ); + SliderRotation1->setValue( round( aRot[0] ) ); + SliderRotation2HasMoved( round( aRot[1] ) ); + SliderRotation2->setValue( round( aRot[1] ) ); + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + const SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ]; + const SMESH::TActorList& anActorList = aPlaneData.ActorList; + + double aBounds[6]; + double aDist; + SMESH::ComputeBounds( anActorList, aBounds ); + SMESH::PositionToDistance( aBounds, theDir, theOrigin, aDist ); + aDist = 1.0 - aDist; + if( aDist>1.0 ) + aDist = 1.0; + else if( aDist < 0.0 ) + aDist = 0.0; + + SliderDistanceHasMoved( round( aDist*100 ) ); + SliderDistance->setValue( round( aDist*100 ) ); + return; +} + +/*! + SLOT: called on preview check box toggled +*/ +void SMESHGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled) +{ + std::for_each( myPlanes.begin(), myPlanes.end(), TSetVisibility( theIsToggled ) ); + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + SMESH::TPlaneData aPlane = myPlanes[aCurPlaneIndex]; + SMESH::OrientedPlane* aPlaneData = aPlane.Plane.GetPointer(); + aPlaneData->myActor->SetVisibility( false ); + if( theIsToggled ) + myPreviewWidget->On(); + else + myPreviewWidget->Off(); + SMESH::RenderViewWindow( myViewWindow ); +} + +/*! + SLOT: called on Auto Apply check box toggled +*/ +void SMESHGUI_ClippingDlg::onAutoApply(bool toggled) +{ + if ( toggled ) ClickOnApply(); +} + +/*! + SLOT on ok button click: sets cutting plane and closes dialog +*/ +void SMESHGUI_ClippingDlg::ClickOnOk() +{ + ClickOnApply(); + accept(); +} + + +/*! + SLOT on Apply button click: sets cutting plane and update viewer +*/ +void SMESHGUI_ClippingDlg::ClickOnApply() +{ + if (myViewWindow) { + SUIT_OverrideCursor wc; + + QWidget *aCurrWid = this->focusWidget(); + aCurrWid->clearFocus(); + aCurrWid->setFocus(); + + SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap(); + SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = aClippingPlaneInfoMap[ myViewWindow->getViewManager() ]; + + // clean memory allocated for planes + SMESHGUI_ClippingPlaneInfoList::iterator anIter1 = aClippingPlaneInfoList.begin(); + for( ; anIter1 != aClippingPlaneInfoList.end(); anIter1++ ) + if( SMESH::OrientedPlane* aPlane = (*anIter1).Plane ) + aPlane->Delete(); + + aClippingPlaneInfoList.clear(); + + VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); + vtkActorCollection* anAllActors = aCopy.GetActors(); + anAllActors->InitTraversal(); + while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActor->RemoveAllClippingPlanes(); + + SMESH::TPlaneDataVector::iterator anIter2 = myPlanes.begin(); + for( ; anIter2 != myPlanes.end(); anIter2++ ) { + SMESH::TPlaneData aPlaneData = *anIter2; + SMESH::TPlane aPlane = aPlaneData.Plane; + SMESH::TActorList anActorList = aPlaneData.ActorList; + + // the check is disabled to support planes with empty actor list + //if( anActorList.empty() ) + // continue; + + SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow); + anOrientedPlane->ShallowCopy(aPlane.GetPointer()); + SMESH::TActorList::iterator anIter3 = anActorList.begin(); + for( ; anIter3 != anActorList.end(); anIter3++ ) + if( vtkActor* aVTKActor = *anIter3 ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) { + if( anOrientedPlane->IsOpenGLClipping ) + anActor->AddOpenGLClippingPlane( anOrientedPlane->InvertPlane() ); + else + anActor->AddClippingPlane( anOrientedPlane ); + } + + SMESH::ClippingPlaneInfo aClippingPlaneInfo; + aClippingPlaneInfo.Plane = anOrientedPlane; + aClippingPlaneInfo.ActorList = anActorList; + + aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); + } + + SMESH_Actor* anSMESHActor; + anAllActors->InitTraversal(); + while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) { + anSMESHActor = anActor; + anActor->SetOpenGLClippingPlane(); + } + + SMESH::RenderViewWindow( myViewWindow ); + } +} + +/*! + SLOT on help button click: opens a help page +*/ +void SMESHGUI_ClippingDlg::ClickOnHelp() +{ + LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); + if (app) + app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); + else { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + SUIT_MessageBox::warning(this, tr("WRN_WARNING"), + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); + } +} + +/*! + SLOT: Called when value of slider distance change +*/ +void SMESHGUI_ClippingDlg::SliderDistanceHasMoved( int value ) +{ + double new_value = value/100.; + TLValueDistance->setText( QString("%1").arg( new_value ) ); + SetCurrentPlaneParam(); +} + +/*! + SLOT: Called when value of slider rotation1 change +*/ +void SMESHGUI_ClippingDlg::SliderRotation1HasMoved( int value ) +{ + TLValueRotation1->setText( QString("%1\xB0").arg( value ) ); + SetCurrentPlaneParam(); +} + +/*! + SLOT: Called when value of slider rotation2 change +*/ +void SMESHGUI_ClippingDlg::SliderRotation2HasMoved( int value ) +{ + TLValueRotation2->setText( QString("%1\xB0").arg( value ) ); + SetCurrentPlaneParam(); +} + +void SMESHGUI_ClippingDlg::onSelectAbsoluteOrientation( int mode ) +{ + bool isUserMode = (mode==0); + + TextLabelX->setEnabled( isUserMode ); + TextLabelY->setEnabled( isUserMode ); + TextLabelZ->setEnabled( isUserMode ); + + SpinBox_X->setEnabled( isUserMode ); + SpinBox_Y->setEnabled( isUserMode ); + SpinBox_Z->setEnabled( isUserMode ); + + TextLabelDx->setEnabled( isUserMode ); + TextLabelDy->setEnabled( isUserMode ); + TextLabelDz->setEnabled( isUserMode ); + + SpinBox_Dx->setEnabled( isUserMode ); + SpinBox_Dy->setEnabled( isUserMode ); + SpinBox_Dz->setEnabled( isUserMode ); + + if ( isUserMode ) + return; + + double aDx = 0, aDy = 0, aDz = 0; + + if ( mode == 1 ) + { + aDz = 1; + TextLabelZ->setEnabled( true ); + SpinBox_Z->setEnabled( true ); + SpinBox_Z->setFocus(); + } + else if ( mode == 2 ) + { + aDx = 1; + TextLabelX->setEnabled( true ); + SpinBox_X->setEnabled( true ); + SpinBox_X->setFocus(); + } + else if ( mode == 3 ) + { + aDy = 1; + TextLabelY->setEnabled( true ); + SpinBox_Y->setEnabled( true ); + SpinBox_Y->setFocus(); + } + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + SMESH::TPlaneData aPlane = myPlanes[aCurPlaneIndex]; + SMESH::OrientedPlane* aPlaneData = aPlane.Plane.GetPointer(); + + if ( aPlaneData->IsInvert == true ) { + aDx = -aDx; aDy = -aDy; aDz = -aDz; + } + + myIsSelectPlane = true; + SpinBox_Dx->setValue( aDx ); + SpinBox_Dy->setValue( aDy ); + SpinBox_Dz->setValue( aDz ); + myIsSelectPlane = false; + + SetCurrentPlaneParam(); +} + +/*! + SLOT: called on orientation of clipping plane in relative mode changed +*/ +void SMESHGUI_ClippingDlg::onSelectRelativeOrientation ( int theItem ) +{ + if ( myPlanes.empty() ) + return; + + if ( theItem == 0 ) { + TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) ); + TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) ); + } + else if ( theItem == 1 ) { + TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) ); + TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) ); + } + else if ( theItem == 2 ) { + TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) ); + TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) ); + } + + if( (QComboBox*)sender() == CBRelativeOrientation ) + SetCurrentPlaneParam(); +} + +/*! + SLOT on reset button click: sets default values +*/ +void SMESHGUI_ClippingDlg::onReset() +{ + myIsSelectPlane = true; + SpinBox_X->setValue(0); + SpinBox_Y->setValue(0); + SpinBox_Z->setValue(0); + myIsSelectPlane = false; + + SetCurrentPlaneParam(); +} + +/*! + SLOT on invert button click: inverts normal of cutting plane +*/ +void SMESHGUI_ClippingDlg::onInvert() +{ + double Dx = SpinBox_Dx->value(); + double Dy = SpinBox_Dy->value(); + double Dz = SpinBox_Dz->value(); + + myIsSelectPlane = true; + SpinBox_Dx->setValue( -Dx ); + SpinBox_Dy->setValue( -Dy ); + SpinBox_Dz->setValue( -Dz ); + myIsSelectPlane = false; + + if ( !myPlanes.empty() ) { + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + SMESH::TPlaneData aPlane = myPlanes[aCurPlaneIndex]; + SMESH::OrientedPlane* aPlaneData = aPlane.Plane.GetPointer(); + aPlaneData->IsInvert = !aPlaneData->IsInvert; + } + SetCurrentPlaneParam(); +} + diff --git a/src/SMESHGUI/SMESHGUI_ClippingDlg.h b/src/SMESHGUI/SMESHGUI_ClippingDlg.h index d36c92cc1..b66c6f149 100644 --- a/src/SMESHGUI/SMESHGUI_ClippingDlg.h +++ b/src/SMESHGUI/SMESHGUI_ClippingDlg.h @@ -46,60 +46,74 @@ #include #include +class QGroupBox; class QLabel; class QPushButton; class QCheckBox; class QComboBox; class QListWidget; class QListWidgetItem; +class QStackedLayout; +class QSlider; +class QMenu; class SALOME_Actor; class SMESHGUI; class SMESH_Actor; -class SMESHGUI_SpinBox; +class QtxDoubleSpinBox; class vtkActor; class vtkDataSetMapper; class vtkPlaneSource; +class vtkCallbackCommand; +class vtkObject; +class vtkImplicitPlaneWidget; namespace SMESH { + enum Mode { Absolute, Relative }; enum Orientation { XY, YZ, ZX }; class OrientedPlane: public vtkPlane { - QPointer myViewWindow; vtkDataSetMapper* myMapper; - public: - static OrientedPlane *New(); - static OrientedPlane *New(SVTK_ViewWindow* theViewWindow); - vtkTypeMacro (OrientedPlane, vtkPlane); + public: + static OrientedPlane *New(); + static OrientedPlane *New(SVTK_ViewWindow* theViewWindow); + vtkTypeMacro (OrientedPlane, vtkPlane); - SMESH::Orientation myOrientation; - float myDistance; - double myAngle[2]; + QPointer myViewWindow; + SMESH::Orientation myRelativeOrientation; + float myDistance; + double myAngle[2]; + double X, Y, Z, Dx, Dy, Dz; + int myAbsoluteOrientation; + bool IsInvert; + bool IsOpenGLClipping; + Mode PlaneMode; - vtkPlaneSource* myPlaneSource; - SALOME_Actor *myActor; + vtkPlaneSource* myPlaneSource; + SALOME_Actor *myActor; - void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; } - SMESH::Orientation GetOrientation() { return myOrientation; } + void SetOrientation (SMESH::Orientation theOrientation) { myRelativeOrientation = theOrientation; } + SMESH::Orientation GetOrientation() { return myRelativeOrientation; } - void SetDistance (float theDistance) { myDistance = theDistance; } - float GetDistance() { return myDistance; } + void SetDistance (float theDistance) { myDistance = theDistance; } + float GetDistance() { return myDistance; } - void ShallowCopy (OrientedPlane* theOrientedPlane); + void ShallowCopy (OrientedPlane* theOrientedPlane); + OrientedPlane* InvertPlane (); - protected: - OrientedPlane(SVTK_ViewWindow* theViewWindow); - OrientedPlane(); + protected: + OrientedPlane(SVTK_ViewWindow* theViewWindow); + OrientedPlane(); - void Init(); + void Init(); - ~OrientedPlane(); - private: - // Not implemented. - OrientedPlane (const OrientedPlane&); - void operator= (const OrientedPlane&); + ~OrientedPlane(); + private: + // Not implemented. + OrientedPlane (const OrientedPlane&); + void operator= (const OrientedPlane&); }; typedef vtkSmartPointer TPlane; @@ -132,82 +146,133 @@ class SMESHGUI_EXPORT SMESHGUI_ClippingDlg : public QDialog public: SMESHGUI_ClippingDlg( SMESHGUI*, SVTK_ViewWindow* ); ~SMESHGUI_ClippingDlg(); - - double getDistance() const; - void setDistance( const double ); - double getRotation1() const; - double getRotation2() const; - void setRotation( const double, const double ); - - // used in SMESHGUI::restoreVisualParameters() to avoid - // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx - static SMESH::OrientedPlane* AddPlane (SMESH::TActorList theActorList, - SVTK_ViewWindow* theViewWindow, - SMESH::Orientation theOrientation, - double theDistance, - const double theAngle[2]); - -protected: - void keyPressEvent( QKeyEvent* ); + static bool AddPlane ( SMESH::TActorList theActorList, + SMESH::OrientedPlane* thePlane ); +protected: + void keyPressEvent( QKeyEvent* ); + static void ProcessEvents( vtkObject* theObject, + unsigned long theEvent, + void* theClientData, + void* theCallData); private: - void initializePlaneData(); - - void synchronize(); - - void updateActorList(); - SMESH::TActorList getCurrentActors(); + double getDistance() const; + void setDistance( const double ); + double getRotation1() const; + double getRotation2() const; + void setRotation( const double, const double ); + + void setOrigin(double theVal[3]); + void setDirection(double theVal[3]); + + void initializePlaneData(); + void initParam(); + void synchronize(); + void updateActorList(); + void updateActorItem( QListWidgetItem* theItem, + bool theUpdateSelectAll, + bool theUpdateClippingPlaneMap ); + SMESH::TActorList getCurrentActors(); + + void dumpPlaneData() const; + void absolutePlaneToRelative ( double theOrigin[3], double theDir[3] ); + void setBoundsForPreviewWidget(); + vtkImplicitPlaneWidget* createPreviewWidget(); - void updateActorItem( QListWidgetItem* theItem, - bool theUpdateSelectAll, - bool theUpdateClippingPlaneMap ); - - void dumpPlaneData() const; private: SMESHGUI* mySMESHGUI; SVTK_ViewWindow* myViewWindow; SMESH::TPlaneDataVector myPlanes; + + vtkCallbackCommand* myCallback; + vtkImplicitPlaneWidget* myPreviewWidget; + double myBounds[6]; QComboBox* ComboBoxPlanes; + QCheckBox* isOpenGLClipping; QPushButton* buttonNew; + QMenu* MenuMode; QPushButton* buttonDelete; + QListWidget* ActorList; QCheckBox* SelectAllCheckBox; + + QStackedLayout* ModeStackedLayout; + + QGroupBox* GroupAbsolutePoint; + QLabel* TextLabelX; + QLabel* TextLabelY; + QLabel* TextLabelZ; + QtxDoubleSpinBox* SpinBox_X; + QtxDoubleSpinBox* SpinBox_Y; + QtxDoubleSpinBox* SpinBox_Z; + QPushButton* resetButton; + + QGroupBox* GroupAbsoluteDirection; + QLabel* TextLabelDx; + QLabel* TextLabelDy; + QLabel* TextLabelDz; + QtxDoubleSpinBox* SpinBox_Dx; + QtxDoubleSpinBox* SpinBox_Dy; + QtxDoubleSpinBox* SpinBox_Dz; + QPushButton* invertButton; + QComboBox* CBAbsoluteOrientation; + + QGroupBox* GroupRelative; QLabel* TextLabelOrientation; - QComboBox* ComboBoxOrientation; QLabel* TextLabelDistance; - SMESHGUI_SpinBox* SpinBoxDistance; - QLabel* TextLabelRot1; - SMESHGUI_SpinBox* SpinBoxRot1; - QLabel* TextLabelRot2; - SMESHGUI_SpinBox* SpinBoxRot2; + QLabel* TextLabelRotation1; + QLabel* TextLabelRotation2; + QLabel* TLValueDistance; + QLabel* TLValueRotation1; + QLabel* TLValueRotation2; + QSlider* SliderDistance; + QSlider* SliderRotation1; + QSlider* SliderRotation2; + QComboBox* CBRelativeOrientation; + QCheckBox* PreviewCheckBox; QCheckBox* AutoApplyCheckBox; + QPushButton* buttonOk; QPushButton* buttonCancel; QPushButton* buttonApply; QPushButton* buttonHelp; bool myIsSelectPlane; + bool myIsPreviewMoved; QString myHelpFileName; + SMESH::Mode CurrentMode; + protected slots: - virtual void reject(); + virtual void reject(); public slots: - void onSelectPlane( int ); - void ClickOnNew(); - void ClickOnDelete(); - void onActorItemChanged( QListWidgetItem* ); - void onSelectAll( int ); - void onSelectOrientation( int ); - void SetCurrentPlaneParam(); - void OnPreviewToggle( bool ); - void onAutoApply(bool); - void ClickOnOk(); - void ClickOnApply(); - void ClickOnHelp(); + void onModeAbsolute(); + void onModeRelative(); + void ClickOnNew(); + void ClickOnDelete(); + void onSelectPlane( int ); + void onSelectAll( int ); + void onActorItemChanged( QListWidgetItem* ); + void SetCurrentPlaneParam(); + + void onIsOpenGLClipping(bool); + void OnPreviewToggle( bool ); + void onAutoApply(bool); + void ClickOnOk(); + void ClickOnApply(); + void ClickOnHelp(); + + void SliderDistanceHasMoved(int); + void SliderRotation1HasMoved(int); + void SliderRotation2HasMoved(int); + void onSelectAbsoluteOrientation( int ); + void onSelectRelativeOrientation( int ); + void onReset(); + void onInvert(); }; #endif // SMESHGUI_CLIPPINGDLG_H diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx index efc82df3d..4a72abca5 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -1396,6 +1396,20 @@ namespace SMESH double theDist, double theBounds[6], double theOrigin[3] ) + { + bool anIsOk = false; + anIsOk = ComputeBounds( theActorList, theBounds ); + + + if( !anIsOk ) + return false; + + DistanceToPosition( theBounds, theNormal, theDist, theOrigin ); + return true; + } + + bool ComputeBounds( std::list theActorList, + double theBounds[6]) { bool anIsOk = false; theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX; @@ -1416,12 +1430,7 @@ namespace SMESH } } } - - if( !anIsOk ) - return false; - - DistanceToPosition( theBounds, theNormal, theDist, theOrigin ); - return true; + return anIsOk; } #ifndef DISABLE_PLOT2DVIEWER diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.h b/src/SMESHGUI/SMESHGUI_VTKUtils.h index 0250fb30a..c45edf22f 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.h +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.h @@ -206,6 +206,14 @@ SMESHGUI_EXPORT double theDist, double theBounds[6], double theOrigin[3] ); + + bool ComputeBounds( std::list theActorList, + double theBounds[6]); + + void PositionToDistance( double theBounds[6], + double theDirection[3], + double thePos[3], + double& theDist ); SMESHGUI_EXPORT void RemoveVisualObjectWithActors( const char* theEntry, bool fromAllViews = false ); }; diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index 3920df48b..711dc55b9 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -6548,6 +6548,10 @@ It is impossible to read point coordinates from file CLIP_PLANES Clipping planes + + IS_OPENGL_CLIPPING + OpenGL clipping + MESHES_SUBMESHES_GROUPS Meshes, sub-meshes and groups @@ -6608,6 +6612,30 @@ It is impossible to read point coordinates from file NO_PLANES No planes + + ABSOLUTE + Absolute + + + RELATIVE + Relative + + + BASE_POINT + Base point + + + DIRECTION + Direction + + + RESET + Reset + + + INVERT + Invert + SMESHGUI_DuplicateNodesDlg diff --git a/src/SMESHGUI/SMESH_msg_fr.ts b/src/SMESHGUI/SMESH_msg_fr.ts index 6f409879b..63e309652 100755 --- a/src/SMESHGUI/SMESH_msg_fr.ts +++ b/src/SMESHGUI/SMESH_msg_fr.ts @@ -6486,6 +6486,10 @@ Il y a trop peu de points dans le fichier CLIP_PLANES Plans de découpe + + IS_OPENGL_CLIPPING + OpenGL découpage + MESHES_SUBMESHES_GROUPS Maillages, sous-maillages et groupes @@ -6546,6 +6550,30 @@ Il y a trop peu de points dans le fichier NO_PLANES Pas de plans + + ABSOLUTE + Absolute + + + RELATIVE + Relative + + + RESET + Réinitialiser + + + INVERT + Inverser + + + BASE_POINT + Le point fondamental + + + DIRECTION + Direction + SMESHGUI_DuplicateNodesDlg