#include "LightApp_SelectionMgr.h"
#include "LightApp_VTKSelector.h"
#include "LightApp_Preferences.h"
+#include "LightApp_Displayer.h"
+
+#include "SALOMEDS_IParameters.hxx"
#include "VVTK_ViewManager.h"
#include "VVTK_ViewWindow.h"
#include "VISU_CutLines_i.hh"
#include "VISU_Actor.h"
+#include "VISU_ScalarMapAct.h"
#include "VisuGUI_Tools.h"
#include "VisuGUI_ActionsDef.h"
#include <vtkRenderer.h>
#include <vtkCamera.h>
#include <vtkTimerLog.h>
+#include <vtkPlane.h>
#include <sstream>
}
return aRet;
}
+
+
+const char gSeparator = '_'; // character used to separate parameter names
+const char gDigitsSep = ':'; // character used to separate numeric parameter values (color = r:g:b)
+/*!
+ * \brief Virtual public
+ *
+ * This method is called just before the study document is saved, so the module has a possibility
+ * to store visual parameters in AttributeParameter attribue(s)
+ */
+void VisuGUI_Module::storeVisualParameters(int savePoint)
+{
+ SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
+ if( !study || !study->studyDS() )
+ return;
+ _PTR(Study) studyDS = study->studyDS();
+ _PTR(AttributeParameter) ap = studyDS->GetModuleParameters("Interface Applicative", moduleName().latin1(), savePoint);
+ SALOMEDS_IParameters ip(ap);
+
+ // viewers counters are used for storing view_numbers in IParameters
+ int svtkViewers( 0 ), vvtkViewers( 0 ), plotViewers( 0 );
+
+ // componentName is used for encoding of entries when storing them in IParameters
+ _PTR(SComponent) visuEng = ClientFindOrCreateVisuComponent( studyDS );
+ std::string componentName = visuEng->ComponentDataType();
+
+ QPtrList<SUIT_ViewManager> lst;
+
+ // saving VVTK viewer parameters. VVTK (Gauss Viewers) are NOT created by SalomeApp since
+ // VVTK is declared in VISU, so here we store VVTK view window parameters.
+ // VisuGUI_Module::restoreVisualParameters() creates VVTK_Views and restores its parameters.
+ ip.setProperty( "ActiveGaussViewer", "-1" );
+ getApp()->viewManagers( VVTK_Viewer::Type(), lst );
+ for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it ) {
+ SUIT_ViewManager* vman = it.current();
+ if ( SUIT_ViewWindow* vwin = vman->getActiveView() ) {
+ // using predefined string "GaussViewer" as "entry".. it's a hardcoded "workaround".
+ // gauss viewer parameters are retrieved using this "entry" string.
+ // name of parameter = caption of gauss ViewWindow
+ // value of parameter = ViewWindow's visual parameters
+ ip.setParameter( "GaussViewer", vwin->caption().latin1(), vwin->getVisualParameters().latin1() );
+
+ if ( application()->desktop()->activeWindow() == vwin )
+ ip.setProperty( "ActiveGaussViewer", QString::number( vvtkViewers ).latin1() );
+ vvtkViewers++;
+ }
+ }
+
+ // VISU module opens one SVTK viewer in activateModule(). This causes a bug in save-restore visual
+ // parameters: it no SVTK view was saved, we need NOT any SVTK on restore. Here we store if any is open..
+ /*
+ lst.clear();
+ getApp()->viewManagers( SVTK_Viewer::Type(), lst );
+ ip.setProperty( "VtkViewersCount", QString::number( lst.count() ).latin1() );
+ */
+
+ // main cycle to store parameters of displayed objects
+ lst.clear();
+ getApp()->viewManagers( lst );
+ vvtkViewers = svtkViewers = plotViewers = 0;
+ for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it ) {
+ SUIT_ViewManager* vman = it.current();
+ QString vType = vman->getType();
+ int* viewsCounter = vType == SVTK_Viewer::Type() ? &svtkViewers :
+ vType == VVTK_Viewer::Type() ? &vvtkViewers :
+ vType == SPlot2d_Viewer::Type() ? &plotViewers : 0;
+
+ // saving VTK actors' properties
+ if ( vType == SVTK_Viewer::Type() || // processing SVTK and VVTK viewers in the same
+ vType == VVTK_Viewer::Type() ) { // way (VVTK_ViewWindow inherits SVTK_ViewWindow)
+
+ QPtrVector<SUIT_ViewWindow> views = vman->getViews();
+ for ( int i = 0, iEnd = vman->getViewsCount(); i < iEnd; i++ ) {
+ if ( SVTK_ViewWindow* vtkView = dynamic_cast<SVTK_ViewWindow*>( views[i] ) ) {
+ vtkActorCollection* allActors = vtkView->getRenderer()->GetActors();
+ allActors->InitTraversal();
+ while ( vtkActor* actor = allActors->GetNextActor() ) {
+ if ( actor->GetVisibility() ) { // store only visible actors
+ if ( VISU_Actor* vActor = VISU_Actor::SafeDownCast( actor ) ) {
+ if ( vActor->hasIO() ) { // actor corresponds to existing obj
+
+ Handle(SALOME_InteractiveObject) io = vActor->getIO();
+ // entry is "ecoded" = it does NOT contain component adress, since it is a
+ // subject to change on next component loading
+ std::string entry = ip.encodeEntry( io->getEntry(), componentName );
+
+ std::string param, vtkParam = vType.latin1(); vtkParam += gSeparator;
+ vtkParam += QString::number( *viewsCounter ).latin1(); vtkParam += gSeparator;
+
+ param = vtkParam + "Visibility";
+ ip.setParameter( entry, param, "On" );
+ param = vtkParam + "Name";
+ ip.setParameter( entry, param, vActor->getName() );
+ param = vtkParam + "RepresentationMode";
+ ip.setParameter( entry, param, QString::number( vActor->GetRepresentation() ).latin1() );
+ param = vtkParam + "Opacity";
+ ip.setParameter( entry, param, QString::number( vActor->GetOpacity() ).latin1() );
+ float r, g, b;
+ vActor->GetColor(r, g, b);
+ QString colorStr = QString::number( r ); colorStr += gDigitsSep;
+ colorStr += QString::number( g ); colorStr += gDigitsSep;
+ colorStr += QString::number( b );
+ param = vtkParam + "Color";
+ ip.setParameter( entry, param, colorStr.latin1() );
+ param = vtkParam + "LineWidth";
+ ip.setParameter( entry, param, QString::number( vActor->GetLineWidth() ).latin1() );
+ if ( vActor->IsShrunkable() && vActor->IsShrunk() ) {
+ param = vtkParam + "ShrinkMode";
+ ip.setParameter( entry, param, "On" );
+ param = vtkParam + "ShrinkFactor";
+ ip.setParameter( entry, param, QString::number( vActor->GetShrinkFactor() ).latin1() );
+ }
+ VISU_ScalarMapAct* scalarMapActor = dynamic_cast<VISU_ScalarMapAct*>( vActor );
+ if ( scalarMapActor && scalarMapActor->IsShading() ) {
+ param = vtkParam + "Shading";
+ ip.setParameter( entry, param, "On" );
+ }
+ if ( const VISU::Prs3d_i* vPrs = vActor->GetPrs3d() ) {
+ param = vtkParam + "ClippingPlane_";
+ for ( int p = 0, nPlanes = vPrs->GetNumberOfClippingPlanes(); p < nPlanes; p++ ) {
+ vtkPlane* plane = vPrs->GetClippingPlane( p );
+ float normal[3], origin[3];
+ plane->GetNormal( normal );
+ plane->GetOrigin( origin );
+ std::string planeValue = QString::number( normal[0] ).latin1(); planeValue += gDigitsSep;
+ planeValue += QString::number( normal[1] ).latin1(); planeValue += gDigitsSep;
+ planeValue += QString::number( normal[2] ).latin1(); planeValue += gDigitsSep;
+ planeValue += QString::number( origin[0] ).latin1(); planeValue += gDigitsSep;
+ planeValue += QString::number( origin[1] ).latin1(); planeValue += gDigitsSep;
+ planeValue += QString::number( origin[2] ).latin1();
+ param += QString::number( p+1 ).latin1();
+ ip.setParameter( entry, param, planeValue );
+ }
+ }
+
+ } // hasIO
+ } // salome_actor successfull downcast
+ } // isVisible
+ } // end of ..while.. actors traversal
+ } // if ( vtkView )
+ } // for ( views )
+ (*viewsCounter)++;
+ } // if ( SVTK view model )
+ else if ( vType == SPlot2d_Viewer::Type() ) { // processing Plot2d viewers
+ QPtrVector<SUIT_ViewWindow> views = vman->getViews();
+ for ( int i = 0, iEnd = vman->getViewsCount(); i < iEnd; i++ ) {
+ if ( Plot2d_ViewWindow* plotView = dynamic_cast<Plot2d_ViewWindow*>( views[i] ) ) {
+ Plot2d_ViewFrame* plotVF = plotView->getViewFrame();
+ QPtrList<Plot2d_Curve> curves;
+ plotVF->getCurves( curves );
+
+ Plot2d_Curve* curve;
+ for ( curve = curves.first(); curve; curve = curves.next() ) {
+ if ( SPlot2d_Curve* sCurve = dynamic_cast<SPlot2d_Curve*>( curve ) ) {
+ if ( sCurve->hasIO() ) {
+
+ Handle(SALOME_InteractiveObject) io = sCurve->getIO();
+ // entry is "ecoded" = it does NOT contain component adress, since it is a
+ // subject to change on next component loading
+ std::string entry = ip.encodeEntry( io->getEntry(), componentName );
+
+ std::string param, plotParam = vType.latin1(); plotParam += gSeparator;
+ plotParam += QString::number( *viewsCounter ).latin1(); plotParam += gSeparator;
+
+ param = plotParam + "Visibility";
+ ip.setParameter( entry, param, "On" );
+ }
+ }
+ } // for curves
+ } // if ( plotView )
+ } // for ( views )
+ (*viewsCounter)++;
+ } // if ( SPlot2d view model )
+ }
+}
+
+// returns VISU_Actor with IO with given entry
+VISU_Actor* getActor( const QString& entry, SVTK_ViewWindow* vtkView )
+{
+ if ( vtkView && !entry.isEmpty() ) {
+ vtkActorCollection* allActors = vtkView->getRenderer()->GetActors();
+ allActors->InitTraversal();
+ while ( vtkActor* actor = allActors->GetNextActor() ) {
+ if ( VISU_Actor* vActor = VISU_Actor::SafeDownCast( actor ) ) {
+ if ( vActor->hasIO() ) { // actor corresponds to existing obj
+ Handle(SALOME_InteractiveObject) io = vActor->getIO();
+ if ( entry == io->getEntry() )
+ return vActor;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+const int ViewerType = 0;
+const int ViewIndex = 1;
+const int ParamName = 2;
+// visual parameters are stored in strings as follows:
+// ViewerType_ViewNumber_ParamName. '_' is used as separator and should not be used in
+// viewer type or parameter names
+
+// return viewer type substring from parameter name
+std::string getParam( const std::string& paramName, const int index )
+{
+ QStringList lst = QStringList::split( gSeparator, QString( paramName.c_str() ) );
+ if ( !lst.isEmpty() && index < lst.size() )
+ return lst[index];
+ return "";
+}
+
+
+/*!
+ * \brief Virtual public
+ *
+ * This method is called after the study document is opened, so the module has a possibility to restore
+ * visual parameters
+ */
+void VisuGUI_Module::restoreVisualParameters(int savePoint)
+{
+ SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
+ if( !study || !study->studyDS() )
+ return;
+ _PTR(Study) studyDS = study->studyDS();
+ _PTR(AttributeParameter) ap = studyDS->GetModuleParameters("Interface Applicative", moduleName().latin1(), savePoint);
+ SALOMEDS_IParameters ip(ap);
+
+ // actors are stored in a map after displaying of them for quicker access in future
+ QMap<QString, QMap<QString, VISU_Actor*> > vtkActors; // map: entry to map: ViewType_<ID> to actor (SVTK/VVTK)
+
+ std::vector<std::string> entries = ip.getEntries();
+
+ for ( std::vector<std::string>::iterator entIt = entries.begin(); entIt != entries.end(); ++entIt ) {
+
+ std::vector<std::string> paramNames = ip.getAllParameterNames( *entIt );
+ std::vector<std::string> paramValues = ip.getAllParameterValues( *entIt );
+ std::vector<std::string>::iterator namesIt = paramNames.begin();
+ std::vector<std::string>::iterator valuesIt = paramValues.begin();
+
+ if ( *entIt == "GaussViewer" ) {
+ // parameter names are view window's captions, values - visual parameters.
+ for ( ; namesIt != paramNames.end(); ++namesIt, ++valuesIt ) {
+ SUIT_ViewManager* vman = onCreateViewManager();
+ SUIT_ViewWindow* vwin = vman->getActiveView();
+ vwin->setCaption( (*namesIt).c_str() );
+
+ // wait untill the window is really shown. This step fixes MANY bugs..
+ while ( !vwin->isVisible() )
+ qApp->processEvents();
+
+ vwin->setVisualParameters( (*valuesIt).c_str() );
+ }
+ continue; // skip to next entry
+ }
+
+ // entry is a normal entry - it should be "decoded" (setting base adress of component)
+ QString entry( ip.decodeEntry( *entIt ).c_str() );
+
+ for ( ; namesIt != paramNames.end(); ++namesIt, ++valuesIt ) {
+ std::string viewerType = ::getParam( *namesIt, ViewerType );
+
+ std::string paramName = ::getParam( *namesIt, ParamName );
+ bool ok;
+ std::string viewIndexStr = ::getParam( *namesIt, ViewIndex );
+ int viewIndex = QString( viewIndexStr.c_str() ).toUInt( &ok );
+ if ( !ok ) // bad conversion of view index to integer
+ continue;
+
+ // cout << " -- " << viewerType << ": entry = " << entry.latin1() << ", paramName = " << paramName << endl;
+
+ if ( viewerType == SVTK_Viewer::Type().latin1() ||
+ viewerType == VVTK_Viewer::Type().latin1() ) {
+
+ // used as inner map key for locating the actor.
+ QString viewerTypeIndex = viewerType + QString::number( viewIndex );
+
+ if ( paramName == "Visibility" && displayer() ) {
+ // if VVTK, then we must create viewer first, because
+
+ QPtrList<SUIT_ViewManager> lst;
+ getApp()->viewManagers( viewerType, lst );
+
+ // SVTK/VVTK 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 and VVTK view models can be casted to SALOME_View
+ displayer()->Display( entry, true, dynamic_cast<SALOME_View*>( vmodel ) );
+ SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
+ // vtkView->getRenderer()->ResetCameraClippingRange();
+ // vtkView->Repaint();
+
+ // store displayed actor so setting of color, opacity, etc. will be much faster
+ QMap<QString, VISU_Actor*> viewActorMap;
+ if ( vtkActors.contains( entry ) )
+ viewActorMap = vtkActors[ entry ];
+ viewActorMap[ viewerTypeIndex ] = getActor( entry, vtkView );
+ vtkActors[ entry ] = viewActorMap;
+ }
+ }
+ else { // the rest properties "work" with VISU_Actor, so we initialize it at first
+ VISU_Actor* vActor = 0;
+ if ( vtkActors.contains( entry ) ) {
+ QMap<QString, VISU_Actor*> viewActorMap = vtkActors[ entry ];
+ if ( viewActorMap.contains( viewerTypeIndex ) )
+ vActor = viewActorMap[ viewerTypeIndex ];
+ }
+ if ( !vActor )
+ continue;
+
+ QString val( (*valuesIt).c_str() );
+
+ if ( paramName == "Name" )
+ vActor->setName( val.latin1() );
+
+ else if ( paramName == "RepresentationMode" )
+ vActor->SetRepresentation( val.toInt() );
+
+ else if ( paramName == "Opacity" )
+ vActor->SetOpacity( val.toFloat() );
+
+ else if ( paramName == "Color" ) {
+ QStringList colors = QStringList::split( gDigitsSep, val );
+ if ( colors.count() == 3 )
+ vActor->SetColor( colors[0].toFloat(), colors[1].toFloat(), colors[2].toFloat() );
+ }
+
+ else if ( paramName == "LineWidth" )
+ vActor->SetLineWidth( val.toFloat() );
+
+ else if ( paramName == "ShrinkMode" ) {
+ vActor->SetShrinkable( true );
+ vActor->SetShrink();
+ }
+
+ else if ( paramName == "ShrunkFactor" )
+ vActor->SetShrinkFactor( val.toFloat() );
+
+ else if ( paramName == "Shading" ) {
+ if ( VISU_ScalarMapAct* scalarMapActor = dynamic_cast<VISU_ScalarMapAct*>( vActor ) )
+ scalarMapActor->SetShading();
+ }
+
+ else if ( paramName.find( "ClippingPlane" ) != std::string::npos ) {
+ QStringList vals = QStringList::split( gDigitsSep, val );
+ if ( vals.count() == 6 && vActor->GetPrs3d() ) {
+ float normal[3], origin[3];
+ for (int x = 0; x < 3; x++ ) {
+ normal[x] = vals[x].toFloat();
+ origin[x] = vals[x+3].toFloat();
+ }
+ vtkPlane* plane = vtkPlane::New();
+ plane->SetNormal( normal );
+ plane->SetOrigin( origin );
+ vActor->GetPrs3d()->AddClippingPlane( plane );
+ }
+ }
+ } // else ..
+ } // if SVTK
+
+ else if ( viewerType == SPlot2d_Viewer::Type().latin1() ) {
+
+ if ( paramName == "Visibility" && displayer() ) {
+ QPtrList<SUIT_ViewManager> lst;
+ getApp()->viewManagers( viewerType, lst );
+
+ if ( viewIndex >= 0 && viewIndex < lst.count() ) {
+ SUIT_ViewManager* vman = lst.at( viewIndex );
+ SUIT_ViewModel* vmodel = vman->getViewModel();
+ // SVTK and VVTK view models can be casted to SALOME_View
+ displayer()->Display( entry, true, dynamic_cast<SALOME_View*>( vmodel ) );
+ }
+ }
+
+ } // if SPlot2d
+
+ } // for names/parameters iterator
+ } // for entries iterator
+
+ // [ update all SVTK/VVTK views
+ QPtrList<SUIT_ViewManager> lst;
+ getApp()->viewManagers( lst );
+ for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it ) {
+ SUIT_ViewManager* vman = it.current();
+ SUIT_ViewModel* vmodel = vman->getViewModel();
+ if ( !vmodel )
+ continue;
+ if ( vmodel->getType() == SVTK_Viewer::Type() || // processing SVTK and VVTK viewers
+ vmodel->getType() == VVTK_Viewer::Type() ) { // in the same way
+ SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView();
+ vtkView->getRenderer()->ResetCameraClippingRange();
+ vtkView->Repaint();
+ }
+ else if ( vmodel->getType() == SPlot2d_Viewer::Type().latin1() ) {
+ Plot2d_ViewWindow* plotView = (Plot2d_ViewWindow*) vman->getActiveView();
+ plotView->getViewFrame()->Repaint();
+ }
+ } // ] end of update views
+
+ // VISU module opens one SVTK viewer in activateModule(). This causes a bug in save-restore visual
+ // parameters: it no SVTK view was saved, we need NOT any SVTK on restore. Here we close one
+ // default SVTK if needed.
+ /*
+ QString openedSvtkViewerStr = ip.getProperty( "VtkViewersCount" ).c_str();
+ int openedSvtkViewer = openedSvtkViewerStr.toInt( &ok );
+ if ( ok && openedSvtkViewer == 0 ) {
+ lst.clear();
+ getApp()->viewManagers( SVTK_Viewer::Type(), lst );
+ if ( lst.count() )
+ lst.at( 0 )->closeAllViews();
+ }
+ */
+
+ // if active Gauss Viewer is set ( != -1) then raise the gauss view window.
+ bool ok;
+ QString activeGaussViewerStr = ip.getProperty( "ActiveGaussViewer" ).c_str();
+ int activeGaussViewer = activeGaussViewerStr.toInt( &ok );
+ if ( ok && activeGaussViewer != -1 ) {
+ lst.clear();
+ getApp()->viewManagers( VVTK_Viewer::Type(), lst );
+ if ( activeGaussViewer >= 0 && activeGaussViewer < lst.count() ) {
+ SUIT_ViewWindow* activeView = lst.at( activeGaussViewer )->getActiveView();
+ if ( activeView ) {
+ activeView->setActiveWindow();
+ activeView->setFocus();
+ }
+ }
+ }
+}
+