0020977: EDF 1520 SMESH: Create a clipping plane on several groups

This commit is contained in:
ouv 2010-10-25 13:43:31 +00:00
parent eddb6a7516
commit 55eae5869b
14 changed files with 1138 additions and 495 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -9,11 +9,14 @@ To start, click on the \em New button.
\image html a-clipping2.png
Now you can define the parameters of your cross-section: \b Orientation
(X-Y, X-Z or Y-Z); \b Distance between the opposite extremities of the
object, if it is set to 0.5 the object is split in two halves; and
\b Rotation (in angle degrees) <b>around X</b> (Y to Z) and <b>around Y</b> (X to
Z). If the <b>Show preview</b> button is on, you can see the clipping plane
Now you can define the parameters of your cross-section: list of
<b>meshes, sub-meshes and groups</b> the cross-section will be applied to
(<b>Select all</b> button allows to select and deselect all available
objects at once), \b Orientation (X-Y, X-Z or Y-Z); \b Distance between the
opposite extremities of the boundary box of selected objects, if it is set
to 0.5 the boundary box is split in two halves; and \b Rotation (in angle
degrees) <b>around X</b> (Y to Z) and <b>around Y</b> (X to Z).
If the <b>Show preview</b> button is on, you can see the clipping plane
in the <b>3D Viewer</b>.
\image html image79.jpg "The plane and the cut object"

View File

@ -500,6 +500,9 @@ SMESH_ActorDef::~SMESH_ActorDef()
{
if(MYDEBUG) MESSAGE("~SMESH_ActorDef - "<<this);
// caught by SMESHGUI::ProcessEvents() static method
this->InvokeEvent( SMESH::DeleteActorEvent, NULL );
myScalarBarActor->Delete();
myLookupTable->Delete();
@ -1823,92 +1826,6 @@ GetClippingPlane(vtkIdType theID)
return myCippingPlaneCont[theID].Get();
}
static void ComputeBoundsParam(vtkDataSet* theDataSet,
vtkFloatingPointType theDirection[3], vtkFloatingPointType theMinPnt[3],
vtkFloatingPointType& theMaxBoundPrj, vtkFloatingPointType& theMinBoundPrj)
{
vtkFloatingPointType aBounds[6];
theDataSet->GetBounds(aBounds);
//Enlarge bounds in order to avoid conflicts of precision
for(int i = 0; i < 6; i += 2){
static double EPS = 1.0E-3;
vtkFloatingPointType aDelta = (aBounds[i+1] - aBounds[i])*EPS;
aBounds[i] -= aDelta;
aBounds[i+1] += aDelta;
}
vtkFloatingPointType aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
{aBounds[1],aBounds[2],aBounds[4]},
{aBounds[0],aBounds[3],aBounds[4]},
{aBounds[1],aBounds[3],aBounds[4]},
{aBounds[0],aBounds[2],aBounds[5]},
{aBounds[1],aBounds[2],aBounds[5]},
{aBounds[0],aBounds[3],aBounds[5]},
{aBounds[1],aBounds[3],aBounds[5]}};
int aMaxId = 0, aMinId = aMaxId;
theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
theMinBoundPrj = theMaxBoundPrj;
for(int i = 1; i < 8; i++){
vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
if(theMaxBoundPrj < aTmp){
theMaxBoundPrj = aTmp;
aMaxId = i;
}
if(theMinBoundPrj > aTmp){
theMinBoundPrj = aTmp;
aMinId = i;
}
}
vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
theMinPnt[0] = aMinPnt[0];
theMinPnt[1] = aMinPnt[1];
theMinPnt[2] = aMinPnt[2];
}
static void DistanceToPosition(vtkDataSet* theDataSet,
vtkFloatingPointType theDirection[3], vtkFloatingPointType theDist, vtkFloatingPointType thePos[3])
{
vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
}
static void PositionToDistance(vtkDataSet* theDataSet,
vtkFloatingPointType theDirection[3], vtkFloatingPointType thePos[3], vtkFloatingPointType& theDist)
{
vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
}
void SMESH_ActorDef::SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane)
{
thePlane->SetNormal(theDir);
vtkFloatingPointType anOrigin[3];
::DistanceToPosition(GetUnstructuredGrid(),theDir,theDist,anOrigin);
thePlane->SetOrigin(anOrigin);
}
void SMESH_ActorDef::GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane)
{
thePlane->GetNormal(theDir);
vtkFloatingPointType anOrigin[3];
thePlane->GetOrigin(anOrigin);
::PositionToDistance(GetUnstructuredGrid(),theDir,anOrigin,theDist);
}
void SMESH_ActorDef::UpdateScalarBar()
{
SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();

View File

@ -31,6 +31,8 @@
#include <SALOME_Actor.h>
#include "SMESH_Object.h"
#include <vtkCommand.h>
class vtkUnstructuredGrid;
class vtkScalarBarActor;
@ -38,6 +40,11 @@ class vtkScalarBarActor;
class vtkPlane;
class vtkImplicitBoolean;
namespace SMESH
{
const vtkIdType DeleteActorEvent = vtkCommand::UserEvent + 100;
}
class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
{
static SMESH_Actor* New() { return NULL;}
@ -123,9 +130,6 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
virtual vtkScalarBarActor* GetScalarBarActor() = 0;
virtual void SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane) = 0;
virtual void GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane) = 0;
virtual void RemoveAllClippingPlanes() = 0;
virtual vtkIdType GetNumberOfClippingPlanes() = 0;
virtual vtkPlane* GetClippingPlane(vtkIdType theID) = 0;

View File

@ -189,9 +189,6 @@ class SMESH_ActorDef : public SMESH_Actor
virtual vtkScalarBarActor* GetScalarBarActor(){ return myScalarBarActor;}
virtual void SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane);
virtual void GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane);
virtual void RemoveAllClippingPlanes();
virtual vtkIdType GetNumberOfClippingPlanes();
virtual vtkPlane* GetClippingPlane(vtkIdType theID);

View File

@ -135,6 +135,7 @@
#include <vtkCamera.h>
#include <vtkRenderer.h>
#include <vtkPlane.h>
#include <vtkCallbackCommand.h>
// SALOME KERNEL includes
#include <SALOMEDS_Study.hxx>
@ -837,17 +838,21 @@
if( !aSel || !appStudy )
return;
if( theCommandID == 1134 ) { // Clipping dialog can be activated without selection
if( SMESHGUI* aModule = SMESHGUI::GetSMESHGUI() ) {
aModule->EmitSignalDeactivateDialog();
if( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aModule ) )
(new SMESHGUI_ClippingDlg( aModule, aViewWindow ))->show();
}
return;
}
_PTR(Study) aStudy = appStudy->studyDS();
aSel->selectedObjects( selected );
if(selected.Extent() >= 1){
switch(theCommandID){
case 1134:{
SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
(new SMESHGUI_ClippingDlg( SMESHGUI::GetSMESHGUI() ))->show();
return;
}
case 1133:{
SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
(new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show();
@ -1419,6 +1424,12 @@ LightApp_Module( "SMESH" )
myState = -1;
myDisplayer = 0;
myEventCallbackCommand = vtkCallbackCommand::New();
myEventCallbackCommand->Delete();
myEventCallbackCommand->SetClientData( this );
myEventCallbackCommand->SetCallback( SMESHGUI::ProcessEvents );
myPriority = 0.0;
SMESH::GetFilterManager();
SMESH::GetPattern();
@ -3682,14 +3693,6 @@ void SMESHGUI::initialize( CAM_Application* app )
popupMgr()->insert( action( 1133 ), -1, -1 );
popupMgr()->setRule( action( 1133 ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule );
//-------------------------------------------------
// Clipping
//-------------------------------------------------
popupMgr()->insert( action( 1134 ), -1, -1 );
popupMgr()->setRule( action( 1134 ), aMeshInVTK + "&& selcount=1 && isVisible", QtxPopupMgr::VisibleRule );
popupMgr()->insert( separator(), -1, -1 );
//-------------------------------------------------
// Controls
//-------------------------------------------------
@ -3815,8 +3818,19 @@ void SMESHGUI::initialize( CAM_Application* app )
popupMgr()->insert( separator(), -1, -1 );
//-------------------------------------------------
// Clipping
//-------------------------------------------------
popupMgr()->insert( action( 1134 ), -1, -1 );
popupMgr()->setRule( action( 1134 ), "client='VTKViewer'", QtxPopupMgr::VisibleRule );
popupMgr()->insert( separator(), -1, -1 );
connect( application(), SIGNAL( viewManagerActivated( SUIT_ViewManager* ) ),
this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
connect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
}
//================================================================================
@ -3973,6 +3987,49 @@ void SMESHGUI::onViewManagerActivated( SUIT_ViewManager* mgr )
SMESH::UpdateSelectionProp( this );
}
void SMESHGUI::onViewManagerRemoved( SUIT_ViewManager* theViewManager )
{
if( theViewManager && theViewManager->getType() == SVTK_Viewer::Type() )
myClippingPlaneInfoMap.erase( theViewManager );
}
void SMESHGUI::addActorAsObserver( SMESH_Actor* theActor )
{
theActor->AddObserver( SMESH::DeleteActorEvent,
myEventCallbackCommand.GetPointer(),
myPriority );
}
void SMESHGUI::ProcessEvents( vtkObject* theObject,
unsigned long theEvent,
void* theClientData,
void* theCallData )
{
if( SMESHGUI* aSMESHGUI = reinterpret_cast<SMESHGUI*>( theClientData ) ) {
if( theObject && theEvent == SMESH::DeleteActorEvent ) {
if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( theObject ) ) {
SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = aSMESHGUI->getClippingPlaneInfoMap();
SMESHGUI_ClippingPlaneInfoMap::iterator anIter1 = aClippingPlaneInfoMap.begin();
for( ; anIter1 != aClippingPlaneInfoMap.end(); anIter1++ ) {
SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second;
SMESHGUI_ClippingPlaneInfoList::iterator anIter2 = aClippingPlaneInfoList.begin();
for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) {
SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2;
std::list<vtkActor*>& anActorList = aClippingPlaneInfo.ActorList;
SMESH::TActorList::iterator anIter3 = anActorList.begin();
for ( ; anIter3 != anActorList.end(); anIter3++ ) {
if( anActor == *anIter3 ) {
anActorList.erase( anIter3 );
break;
}
}
}
}
}
}
}
}
void SMESHGUI::createPreferences()
{
// General tab ------------------------------------------------------------------------
@ -4481,12 +4538,9 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList<SALOMEDS::Color>& theReser
if( aTolerance < 1 )
break;
}
//cout << "Iteration N" << anIterations << " (tolerance=" << aTolerance << ")"<< endl;
aHue = (int)( 360.0 * rand() / RAND_MAX );
//cout << "Hue = " << aHue << endl;
//cout << "Auto colors : ";
bool ok = true;
QList<SALOMEDS::Color>::const_iterator it = theReservedColors.constBegin();
QList<SALOMEDS::Color>::const_iterator itEnd = theReservedColors.constEnd();
@ -4497,21 +4551,17 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList<SALOMEDS::Color>& theReser
int h, s, v;
aQColor.getHsv( &h, &s, &v );
//cout << h << " ";
if( abs( h - aHue ) < aTolerance )
{
ok = false;
//cout << "break (diff = " << abs( h - aHue ) << ")";
break;
}
}
//cout << endl;
if( ok )
break;
}
//cout << "Hue of the returned color = " << aHue << endl;
QColor aColor;
aColor.setHsv( aHue, 255, 255 );
@ -4599,6 +4649,37 @@ void SMESHGUI::storeVisualParameters (int savePoint)
// saving VTK actors properties
if (vType == SVTK_Viewer::Type())
{
// store the clipping planes attached to the view manager
SMESHGUI_ClippingPlaneInfoList aClippingPlaneInfoList;
SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter = myClippingPlaneInfoMap.find( vman );
if( anIter != myClippingPlaneInfoMap.end() )
aClippingPlaneInfoList = anIter->second;
if( !aClippingPlaneInfoList.empty() ) {
SMESHGUI_ClippingPlaneInfoList::const_iterator anIter = aClippingPlaneInfoList.begin();
for( int anId = 0; anIter != aClippingPlaneInfoList.end(); anIter++, anId++ )
{
const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter;
SMESH::OrientedPlane* aPlane = aClippingPlaneInfo.Plane;
QString aPropertyName( "ClippingPlane" );
aPropertyName += gSeparator;
aPropertyName += QString::number( vtkViewers );
aPropertyName += gSeparator;
aPropertyName += QString::number( anId );
QString aPropertyValue = QString::number( (int)aPlane->GetOrientation() ).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() );
}
}
QVector<SUIT_ViewWindow*> views = vman->getViews();
for (int i = 0, iEnd = vman->getViewsCount(); i < iEnd; i++)
{
@ -4724,22 +4805,25 @@ void SMESHGUI::storeVisualParameters (int savePoint)
// Clipping
param = vtkParam + "ClippingPlane";
int nPlanes = aSmeshActor->GetNumberOfClippingPlanes();
if (!nPlanes)
ip->setParameter(entry, param, "Off");
for (int ipl = 0; ipl < nPlanes; ipl++) {
//vtkPlane* plane = aSmeshActor->GetClippingPlane(ipl);
SMESH::Orientation anOrientation;
double aDistance;
vtkFloatingPointType anAngle[2];
SMESHGUI_ClippingDlg::GetPlaneParam(aSmeshActor, ipl, anOrientation, aDistance, anAngle);
std::string planeValue = QString::number((int)anOrientation).toLatin1().data();
planeValue += gDigitsSep; planeValue += QString::number(aDistance).toLatin1().data();
planeValue += gDigitsSep; planeValue += QString::number(anAngle[0]).toLatin1().data();
planeValue += gDigitsSep; planeValue += QString::number(anAngle[1]).toLatin1().data();
ip->setParameter(entry, param + QString::number(ipl+1).toLatin1().data(), planeValue);
int aPlaneId = 0;
if( !aClippingPlaneInfoList.empty() ) {
SMESHGUI_ClippingPlaneInfoList::const_iterator anIter1 = aClippingPlaneInfoList.begin();
for( int anId = 0; anIter1 != aClippingPlaneInfoList.end(); anIter1++, anId++ )
{
const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter1;
std::list<vtkActor*> anActorList = aClippingPlaneInfo.ActorList;
SMESH::TActorList::iterator anIter2 = anActorList.begin();
for ( ; anIter2 != anActorList.end(); anIter2++ ) {
if( aSmeshActor == *anIter2 ) {
ip->setParameter( entry, param + QString::number( ++aPlaneId ).toLatin1().constData(),
QString::number( anId ).toLatin1().constData() );
break;
}
}
}
}
if( aPlaneId == 0 )
ip->setParameter( entry, param, "Off" );
} // if (io->hasEntry())
} // SMESH_Actor && hasIO
} // isVisible
@ -4751,6 +4835,25 @@ void SMESHGUI::storeVisualParameters (int savePoint)
} // for (viewManagers)
}
// data structures for clipping planes processing
typedef struct {
int Id;
vtkIdType Orientation;
vtkFloatingPointType Distance;
vtkFloatingPointType Angle[2];
} TPlaneData;
typedef std::list<TPlaneData> TPlaneDataList;
typedef std::map<int, TPlaneDataList> TPlaneDataMap;
typedef std::list<vtkActor*> TActorList;
typedef struct {
int PlaneId;
TActorList ActorList;
SUIT_ViewManager* ViewManager;
} TPlaneInfo;
typedef std::list<TPlaneInfo> TPlaneInfoList;
typedef std::map<int, TPlaneInfoList> TPlaneInfoMap;
/*!
* \brief Restore visual parameters
*
@ -4775,8 +4878,9 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
savePoint);
_PTR(IParameters) ip = ClientFactory::getIParameters(ap);
// restore map of custom markers
// restore map of custom markers and map of clipping planes
VTK::MarkerMap& aMarkerMap = myMarkerMap[ studyDS->StudyId() ];
TPlaneDataMap aPlaneDataMap;
std::vector<std::string> properties = ip->getProperties();
for (std::vector<std::string>::iterator propIt = properties.begin(); propIt != properties.end(); ++propIt)
@ -4786,52 +4890,103 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
QString aPropertyValue( ip->getProperty( property ).c_str() );
QStringList aPropertyNameList = aPropertyName.split( gSeparator, QString::SkipEmptyParts );
if( aPropertyNameList.size() != 2 )
if( aPropertyNameList.isEmpty() )
continue;
int anId = 0;
bool ok = false;
if( aPropertyNameList[0] == "texture" )
anId = aPropertyNameList[1].toInt( &ok );
if( !ok || anId < 1 )
continue;
QStringList aPropertyValueList = aPropertyValue.split( gPathSep, QString::SkipEmptyParts );
if( aPropertyValueList.size() != 2 )
continue;
std::string aMarkerFileName = aPropertyValueList[0].toStdString();
QString aMarkerTextureString = aPropertyValueList[1];
QStringList aMarkerTextureStringList = aMarkerTextureString.split( gDigitsSep, QString::SkipEmptyParts );
if( aMarkerTextureStringList.size() != 3 )
continue;
ok = false;
ushort aWidth = aMarkerTextureStringList[0].toUShort( &ok );
if( !ok )
continue;
ok = false;
ushort aHeight = aMarkerTextureStringList[1].toUShort( &ok );
if( !ok )
continue;
VTK::MarkerTexture aMarkerTexture;
aMarkerTexture.push_back( aWidth );
aMarkerTexture.push_back( aHeight );
QString aMarkerTextureData = aMarkerTextureStringList[2];
for( int i = 0, n = aMarkerTextureData.length(); i < n; i++ )
QString aPropertyType = aPropertyNameList[0];
if( aPropertyType == "texture" )
{
QChar aChar = aMarkerTextureData.at( i );
if( aChar.isDigit() )
aMarkerTexture.push_back( aChar.digitValue() );
}
if( aPropertyNameList.size() != 2 )
continue;
aMarkerMap[ anId ] = VTK::MarkerData( aMarkerFileName, aMarkerTexture );
bool ok = false;
int anId = aPropertyNameList[1].toInt( &ok );
if( !ok || anId < 1 )
continue;
QStringList aPropertyValueList = aPropertyValue.split( gPathSep, QString::SkipEmptyParts );
if( aPropertyValueList.size() != 2 )
continue;
std::string aMarkerFileName = aPropertyValueList[0].toStdString();
QString aMarkerTextureString = aPropertyValueList[1];
QStringList aMarkerTextureStringList = aMarkerTextureString.split( gDigitsSep, QString::SkipEmptyParts );
if( aMarkerTextureStringList.size() != 3 )
continue;
ok = false;
ushort aWidth = aMarkerTextureStringList[0].toUShort( &ok );
if( !ok )
continue;
ok = false;
ushort aHeight = aMarkerTextureStringList[1].toUShort( &ok );
if( !ok )
continue;
VTK::MarkerTexture aMarkerTexture;
aMarkerTexture.push_back( aWidth );
aMarkerTexture.push_back( aHeight );
QString aMarkerTextureData = aMarkerTextureStringList[2];
for( int i = 0, n = aMarkerTextureData.length(); i < n; i++ )
{
QChar aChar = aMarkerTextureData.at( i );
if( aChar.isDigit() )
aMarkerTexture.push_back( aChar.digitValue() );
}
aMarkerMap[ anId ] = VTK::MarkerData( aMarkerFileName, aMarkerTexture );
}
else if( aPropertyType == "ClippingPlane" )
{
if( aPropertyNameList.size() != 3 )
continue;
bool ok = false;
int aViewId = aPropertyNameList[1].toInt( &ok );
if( !ok || aViewId < 0 )
continue;
ok = false;
int aClippingPlaneId = aPropertyNameList[2].toInt( &ok );
if( !ok || aClippingPlaneId < 0 )
continue;
QStringList aPropertyValueList = aPropertyValue.split( gDigitsSep, QString::SkipEmptyParts );
if( aPropertyValueList.size() != 4 )
continue;
TPlaneData aPlaneData;
aPlaneData.Id = aClippingPlaneId;
ok = false;
aPlaneData.Orientation = aPropertyValueList[0].toInt( &ok );
if( !ok )
continue;
ok = false;
aPlaneData.Distance = aPropertyValueList[1].toDouble( &ok );
if( !ok )
continue;
ok = false;
aPlaneData.Angle[0] = aPropertyValueList[2].toDouble( &ok );
if( !ok )
continue;
ok = false;
aPlaneData.Angle[1] = aPropertyValueList[3].toDouble( &ok );
if( !ok )
continue;
TPlaneDataList& aPlaneDataList = aPlaneDataMap[ aViewId ];
aPlaneDataList.push_back( aPlaneData );
}
}
TPlaneInfoMap aPlaneInfoMap;
std::vector<std::string> entries = ip->getEntries();
for (std::vector<std::string>::iterator entIt = entries.begin(); entIt != entries.end(); ++entIt)
@ -4878,39 +5033,40 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
if (vtkActors.IsBound(viewIndex))
aSmeshActor = vtkActors.Find(viewIndex);
QList<SUIT_ViewManager*> lst;
getApp()->viewManagers(viewerTypStr, lst);
// SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager
SUIT_ViewManager* vman = NULL;
if (viewIndex >= 0 && viewIndex < lst.count())
vman = lst.at(viewIndex);
if (paramNameStr == "Visibility")
{
if (!aSmeshActor && displayer())
if (!aSmeshActor && displayer() && vman)
{
QList<SUIT_ViewManager*> lst;
getApp()->viewManagers(viewerTypStr, lst);
SUIT_ViewModel* vmodel = vman->getViewModel();
// SVTK view model can be casted to SALOME_View
displayer()->Display(entry, true, dynamic_cast<SALOME_View*>(vmodel));
// SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager
if (viewIndex >= 0 && viewIndex < lst.count()) {
SUIT_ViewManager* vman = lst.at(viewIndex);
SUIT_ViewModel* vmodel = vman->getViewModel();
// SVTK view model can be casted to SALOME_View
displayer()->Display(entry, true, dynamic_cast<SALOME_View*>(vmodel));
// store displayed actor in a temporary map for quicker
// access later when restoring other parameters
SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
vtkRenderer* Renderer = vtkView->getRenderer();
VTK::ActorCollectionCopy aCopy(Renderer->GetActors());
vtkActorCollection* theActors = aCopy.GetActors();
theActors->InitTraversal();
bool isFound = false;
vtkActor *ac = theActors->GetNextActor();
for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) {
if (ac->IsA("SMESH_Actor")) {
SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac);
if (aGeomAc->hasIO()) {
Handle(SALOME_InteractiveObject) io =
Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO());
if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) {
isFound = true;
vtkActors.Bind(viewIndex, aGeomAc);
}
// store displayed actor in a temporary map for quicker
// access later when restoring other parameters
SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
vtkRenderer* Renderer = vtkView->getRenderer();
VTK::ActorCollectionCopy aCopy(Renderer->GetActors());
vtkActorCollection* theActors = aCopy.GetActors();
theActors->InitTraversal();
bool isFound = false;
vtkActor *ac = theActors->GetNextActor();
for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) {
if (ac->IsA("SMESH_Actor")) {
SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac);
if (aGeomAc->hasIO()) {
Handle(SALOME_InteractiveObject) io =
Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO());
if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) {
isFound = true;
vtkActors.Bind(viewIndex, aGeomAc);
}
}
}
@ -5027,14 +5183,16 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
}
// Clipping
else if (paramNameStr.startsWith("ClippingPlane")) {
cout << "$$$ ClippingPlane 1" << endl;
if (paramNameStr == "ClippingPlane1" || val == "Off")
aSmeshActor->RemoveAllClippingPlanes();
if (val != "Off") {
cout << "$$$ ClippingPlane 2" << endl;
QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts);
if (vals.count() == 4) { // format check: 4 values
cout << "$$$ ClippingPlane 3" << endl;
QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts);
// old format - val looks like "Off" or "0:0.5:0:0" (orientation, distance, two angles)
// 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" );
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();
vtkFloatingPointType anAngle[2];
@ -5047,8 +5205,43 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
if (viewIndex >= 0 && viewIndex < lst.count()) {
SUIT_ViewManager* vman = lst.at(viewIndex);
SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
SMESHGUI_ClippingDlg::AddPlane(aSmeshActor, vtkView,
anOrientation, aDistance, anAngle);
SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ vman ];
SMESH::TActorList anActorList;
anActorList.push_back( aSmeshActor );
SMESH::OrientedPlane* aPlane =
SMESHGUI_ClippingDlg::AddPlane(anActorList, vtkView, anOrientation, aDistance, anAngle);
if( aPlane ) {
SMESH::ClippingPlaneInfo aClippingPlaneInfo;
aClippingPlaneInfo.Plane = aPlane;
aClippingPlaneInfo.ActorList = anActorList;
aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
}
}
}
}
else {
bool ok = false;
int aPlaneId = val.toInt( &ok );
if( ok && aPlaneId >= 0 ) {
bool anIsDefinedPlane = false;
TPlaneInfoList& aPlaneInfoList = aPlaneInfoMap[ viewIndex ];
TPlaneInfoList::iterator anIter = aPlaneInfoList.begin();
for( ; anIter != aPlaneInfoList.end(); anIter++ ) {
TPlaneInfo& aPlaneInfo = *anIter;
if( aPlaneInfo.PlaneId == aPlaneId ) {
aPlaneInfo.ActorList.push_back( aSmeshActor );
anIsDefinedPlane = true;
break;
}
}
if( !anIsDefinedPlane ) {
TPlaneInfo aPlaneInfo;
aPlaneInfo.PlaneId = aPlaneId;
aPlaneInfo.ActorList.push_back( aSmeshActor );
aPlaneInfo.ViewManager = vman;
aPlaneInfoList.push_back( aPlaneInfo );
}
}
}
@ -5059,6 +5252,55 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
} // for names/parameters iterator
} // for entries iterator
// add clipping planes to actors according to the restored parameters
// and update the clipping plane map
TPlaneInfoMap::const_iterator anIter1 = aPlaneInfoMap.begin();
for( ; anIter1 != aPlaneInfoMap.end(); anIter1++ ) {
int aViewId = anIter1->first;
const TPlaneInfoList& aPlaneInfoList = anIter1->second;
TPlaneDataMap::const_iterator anIter2 = aPlaneDataMap.find( aViewId );
if( anIter2 == aPlaneDataMap.end() )
continue;
const TPlaneDataList& aPlaneDataList = anIter2->second;
TPlaneInfoList::const_iterator anIter3 = aPlaneInfoList.begin();
for( ; anIter3 != aPlaneInfoList.end(); anIter3++ ) {
const TPlaneInfo& aPlaneInfo = *anIter3;
int aPlaneId = aPlaneInfo.PlaneId;
const TActorList& anActorList = aPlaneInfo.ActorList;
SUIT_ViewManager* aViewManager = aPlaneInfo.ViewManager;
if( !aViewManager )
continue;
SVTK_ViewWindow* aViewWindow = dynamic_cast<SVTK_ViewWindow*>( aViewManager->getActiveView() );
if( !aViewWindow )
continue;
SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ aViewManager ];
TPlaneDataList::const_iterator anIter4 = aPlaneDataList.begin();
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 );
if( aPlane ) {
SMESH::ClippingPlaneInfo aClippingPlaneInfo;
aClippingPlaneInfo.Plane = aPlane;
aClippingPlaneInfo.ActorList = anActorList;
aClippingPlaneInfoList.push_back( aClippingPlaneInfo );
}
break;
}
}
}
}
// update all VTK views
QList<SUIT_ViewManager*> lst;
getApp()->viewManagers(lst);

View File

@ -39,6 +39,14 @@
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Gen)
// VTK includes
#include <vtkSmartPointer.h>
#include <vtkType.h>
class vtkActor;
class vtkCallbackCommand;
class vtkObject;
class QDialog;
class SUIT_Desktop;
@ -52,10 +60,24 @@ class SalomeApp_Study;
class LightApp_Selection;
class LightApp_SelectionMgr;
class SMESH_Actor;
class SMESHGUI_FilterLibraryDlg;
typedef std::map<int, VTK::MarkerMap> SMESHGUI_StudyId2MarkerMap;
namespace SMESH
{
class OrientedPlane;
struct ClippingPlaneInfo
{
OrientedPlane* Plane;
std::list<vtkActor*> ActorList;
};
}
typedef std::list<SMESH::ClippingPlaneInfo> SMESHGUI_ClippingPlaneInfoList;
typedef std::map<SUIT_ViewManager*, SMESHGUI_ClippingPlaneInfoList> SMESHGUI_ClippingPlaneInfoMap;
//=================================================================================
// class : SMESHGUI
// purpose :
@ -122,6 +144,10 @@ public :
virtual void storeVisualParameters (int savePoint);
virtual void restoreVisualParameters(int savePoint);
virtual void addActorAsObserver( SMESH_Actor* theActor );
SMESHGUI_ClippingPlaneInfoMap& getClippingPlaneInfoMap() { return myClippingPlaneInfoMap; }
public slots:
virtual bool deactivateModule( SUIT_Study* );
virtual bool activateModule( SUIT_Study* );
@ -130,6 +156,7 @@ public slots:
private slots:
void OnGUIEvent();
void onViewManagerActivated( SUIT_ViewManager* );
void onViewManagerRemoved( SUIT_ViewManager* );
void onOperationCommited( SUIT_Operation* );
void onOperationAborted( SUIT_Operation* );
void onHypothesisEdit( int result );
@ -159,6 +186,11 @@ protected:
virtual bool reusableOperation( const int id );
static void ProcessEvents( vtkObject* theObject,
unsigned long theEvent,
void* theClientData,
void* theCallData );
private:
void OnEditDelete();
int addVtkFontPref( const QString& label,
@ -175,6 +207,10 @@ private :
SMESHGUI_FilterLibraryDlg* myFilterLibraryDlg;
SMESHGUI_StudyId2MarkerMap myMarkerMap;
SMESHGUI_ClippingPlaneInfoMap myClippingPlaneInfoMap;
vtkSmartPointer<vtkCallbackCommand> myEventCallbackCommand;
vtkFloatingPointType myPriority;
};
#endif // SMESHGUI_H

File diff suppressed because it is too large Load Diff

View File

@ -35,31 +35,91 @@
// Qt includes
#include <QDialog>
#include <QPointer>
// VTK includes
#include <vtkPlane.h>
#include <vtkSmartPointer.h>
// STL includes
#include <list>
#include <map>
#include <vector>
class QLabel;
class QPushButton;
class QCheckBox;
class QComboBox;
class LightApp_SelectionMgr;
class SVTK_Selector;
class QListWidget;
class QListWidgetItem;
class SALOME_Actor;
class SMESHGUI;
class SMESH_Actor;
class OrientedPlane;
class SMESHGUI_SpinBox;
class vtkActor;
class vtkDataSetMapper;
class vtkPlaneSource;
namespace SMESH
{
typedef vtkSmartPointer<OrientedPlane> TVTKPlane;
typedef std::vector<TVTKPlane> TPlanes;
enum Orientation { XY, YZ, ZX };
};
class OrientedPlane: public vtkPlane
{
QPointer<SVTK_ViewWindow> myViewWindow;
vtkDataSetMapper* myMapper;
public:
static OrientedPlane *New();
static OrientedPlane *New(SVTK_ViewWindow* theViewWindow);
vtkTypeMacro (OrientedPlane, vtkPlane);
SMESH::Orientation myOrientation;
float myDistance;
double myAngle[2];
vtkPlaneSource* myPlaneSource;
SALOME_Actor *myActor;
void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; }
SMESH::Orientation GetOrientation() { return myOrientation; }
void SetDistance (float theDistance) { myDistance = theDistance; }
float GetDistance() { return myDistance; }
void ShallowCopy (OrientedPlane* theOrientedPlane);
protected:
OrientedPlane(SVTK_ViewWindow* theViewWindow);
OrientedPlane();
void Init();
~OrientedPlane();
private:
// Not implemented.
OrientedPlane (const OrientedPlane&);
void operator= (const OrientedPlane&);
};
typedef vtkSmartPointer<OrientedPlane> TPlane;
typedef std::list<vtkActor*> TActorList;
struct TPlaneData
{
TPlaneData( TPlane thePlane,
TActorList theActorList )
{
Plane = thePlane;
ActorList = theActorList;
}
TPlane Plane;
TActorList ActorList;
};
typedef std::vector<TPlane> TPlaneVector;
typedef std::vector<TPlaneData> TPlaneDataVector;
};
//=================================================================================
// class : SMESHGUI_ClippingDlg
@ -70,7 +130,7 @@ class SMESHGUI_EXPORT SMESHGUI_ClippingDlg : public QDialog
Q_OBJECT
public:
SMESHGUI_ClippingDlg( SMESHGUI* );
SMESHGUI_ClippingDlg( SMESHGUI*, SVTK_ViewWindow* );
~SMESHGUI_ClippingDlg();
double getDistance() const;
@ -78,35 +138,42 @@ public:
double getRotation1() const;
double getRotation2() const;
void setRotation( const double, const double );
void Sinchronize();
// used in SMESHGUI::restoreVisualParameters() to avoid
// declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx
static void AddPlane (SMESH_Actor* theActor,
SVTK_ViewWindow* theViewWindow,
SMESH::Orientation theOrientation,
double theDistance,
vtkFloatingPointType theAngle[2]);
static void GetPlaneParam (SMESH_Actor* theActor,
int thePlaneIndex,
SMESH::Orientation& theOrientation,
double& theDistance,
vtkFloatingPointType* theAngle);
static SMESH::OrientedPlane* AddPlane (SMESH::TActorList theActorList,
SVTK_ViewWindow* theViewWindow,
SMESH::Orientation theOrientation,
double theDistance,
const vtkFloatingPointType theAngle[2]);
protected:
void keyPressEvent( QKeyEvent* );
private:
LightApp_SelectionMgr* mySelectionMgr;
SVTK_Selector* mySelector;
void initializePlaneData();
void synchronize();
void updateActorList();
SMESH::TActorList getCurrentActors();
void updateActorItem( QListWidgetItem* theItem,
bool theUpdateSelectAll,
bool theUpdateClippingPlaneMap );
void dumpPlaneData() const;
private:
SMESHGUI* mySMESHGUI;
SMESH_Actor* myActor;
SMESH::TPlanes myPlanes;
SVTK_ViewWindow* myViewWindow;
SMESH::TPlaneDataVector myPlanes;
QComboBox* ComboBoxPlanes;
QPushButton* buttonNew;
QPushButton* buttonDelete;
QListWidget* ActorList;
QCheckBox* SelectAllCheckBox;
QLabel* TextLabelOrientation;
QComboBox* ComboBoxOrientation;
QLabel* TextLabelDistance;
@ -129,9 +196,10 @@ public slots:
void onSelectPlane( int );
void ClickOnNew();
void ClickOnDelete();
void onActorItemChanged( QListWidgetItem* );
void onSelectAll( int );
void onSelectOrientation( int );
void SetCurrentPlaneParam();
void onSelectionChanged();
void OnPreviewToggle( bool );
void ClickOnOk();
void ClickOnCancel();

View File

@ -65,6 +65,7 @@
#include CORBA_CLIENT_HEADER(SMESH_Group)
// VTK includes
#include <vtkMath.h>
#include <vtkRenderer.h>
#include <vtkActorCollection.h>
#include <vtkUnstructuredGrid.h>
@ -605,6 +606,9 @@ namespace SMESH
}
}
}
if( anActor )
if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
aSMESHGUI->addActorAsObserver( anActor );
return anActor;
}
@ -1167,4 +1171,108 @@ namespace SMESH
}
}
//----------------------------------------------------------------------------
// internal function
void ComputeBoundsParam( vtkFloatingPointType theBounds[6],
vtkFloatingPointType theDirection[3],
vtkFloatingPointType theMinPnt[3],
vtkFloatingPointType& theMaxBoundPrj,
vtkFloatingPointType& theMinBoundPrj )
{
//Enlarge bounds in order to avoid conflicts of precision
for(int i = 0; i < 6; i += 2){
static double EPS = 1.0E-3;
vtkFloatingPointType aDelta = (theBounds[i+1] - theBounds[i])*EPS;
theBounds[i] -= aDelta;
theBounds[i+1] += aDelta;
}
vtkFloatingPointType aBoundPoints[8][3] = { {theBounds[0],theBounds[2],theBounds[4]},
{theBounds[1],theBounds[2],theBounds[4]},
{theBounds[0],theBounds[3],theBounds[4]},
{theBounds[1],theBounds[3],theBounds[4]},
{theBounds[0],theBounds[2],theBounds[5]},
{theBounds[1],theBounds[2],theBounds[5]},
{theBounds[0],theBounds[3],theBounds[5]},
{theBounds[1],theBounds[3],theBounds[5]}};
int aMaxId = 0, aMinId = aMaxId;
theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
theMinBoundPrj = theMaxBoundPrj;
for(int i = 1; i < 8; i++){
vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
if(theMaxBoundPrj < aTmp){
theMaxBoundPrj = aTmp;
aMaxId = i;
}
if(theMinBoundPrj > aTmp){
theMinBoundPrj = aTmp;
aMinId = i;
}
}
vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
theMinPnt[0] = aMinPnt[0];
theMinPnt[1] = aMinPnt[1];
theMinPnt[2] = aMinPnt[2];
}
// internal function
void DistanceToPosition( vtkFloatingPointType theBounds[6],
vtkFloatingPointType theDirection[3],
vtkFloatingPointType theDist,
vtkFloatingPointType thePos[3] )
{
vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
}
// internal function (currently unused, left just in case)
void PositionToDistance( vtkFloatingPointType theBounds[6],
vtkFloatingPointType theDirection[3],
vtkFloatingPointType thePos[3],
vtkFloatingPointType& theDist )
{
vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
}
bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
vtkFloatingPointType theNormal[3],
vtkFloatingPointType theDist,
vtkFloatingPointType theBounds[6],
vtkFloatingPointType theOrigin[3] )
{
bool anIsOk = false;
theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX;
theBounds[1] = theBounds[3] = theBounds[5] = -VTK_DOUBLE_MAX;
std::list<vtkActor*>::iterator anIter = theActorList.begin();
for( ; anIter != theActorList.end(); anIter++ ) {
if( vtkActor* aVTKActor = *anIter ) {
if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) {
vtkFloatingPointType aBounds[6];
anActor->GetUnstructuredGrid()->GetBounds( aBounds );
theBounds[0] = std::min( theBounds[0], aBounds[0] );
theBounds[1] = std::max( theBounds[1], aBounds[1] );
theBounds[2] = std::min( theBounds[2], aBounds[2] );
theBounds[3] = std::max( theBounds[3], aBounds[3] );
theBounds[4] = std::min( theBounds[4], aBounds[4] );
theBounds[5] = std::max( theBounds[5], aBounds[5] );
anIsOk = true;
}
}
}
if( !anIsOk )
return false;
DistanceToPosition( theBounds, theNormal, theDist, theOrigin );
return true;
}
} // end of namespace SMESH

View File

@ -57,6 +57,8 @@ class SMESHGUI;
class SMESH_Actor;
class SALOME_Actor;
class vtkActor;
namespace SMESH
{
//----------------------------------------------------------------------------
@ -185,6 +187,14 @@ SMESHGUI_EXPORT
SMESHGUI_EXPORT
void SetControlsPrecision( const long );
//----------------------------------------------------------------------------
SMESHGUI_EXPORT
bool ComputeClippingPlaneParameters( std::list<vtkActor*> theActorList,
vtkFloatingPointType theNormal[3],
vtkFloatingPointType theDist,
vtkFloatingPointType theBounds[6],
vtkFloatingPointType theOrigin[3] );
};
#endif // SMESHGUI_VTKUTILS_H

View File

@ -5264,6 +5264,14 @@ It is impossible to read point coordinates from file</translation>
<source>CLIP_PLANES</source>
<translation>Clipping planes</translation>
</message>
<message>
<source>MESHES_SUBMESHES_GROUPS</source>
<translation>Meshes, sub-meshes and groups</translation>
</message>
<message>
<source>SELECT_ALL</source>
<translation>Select all</translation>
</message>
<message>
<source>ROTATION_AROUND_X_Y2Z</source>
<translation>Rotation around X (Y to Z):</translation>