Salome HOME
Merge from V6_main 01/04/2013
[modules/visu.git] / src / VISU_I / VISU_Tools.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //  File   : VISU_Tools.cxx
21 //  Author : Oleg UVAROV
22 //  Module : VISU
23 //
24 #include "VISU_Tools.h"
25
26 #include "VISU_Gen_i.hh"
27 #include "VISU_Table_i.hh"
28 #include "VISU_ViewManager_i.hh"
29
30 #include <VISU_ActorBase.h>
31
32 #include <LightApp_Displayer.h>
33
34 #include <SalomeApp_Study.h>
35 #include <SalomeApp_Application.h>
36 #include <SalomeApp_Module.h>
37
38 #include <SPlot2d_ViewModel.h>
39 #include <Plot2d_ViewFrame.h>
40 #include <Plot2d_ViewManager.h>
41
42 #include <SUIT_ResourceMgr.h>
43 #include <SUIT_Session.h>
44
45 //=============================================================================
46 namespace VISU
47 {
48   //------------------------------------------------------------
49   // Internal function used by several public functions below
50   void
51   UpdateCurve(VISU::Curve_i* theCurve,
52               Plot2d_ViewFrame* thePlot,
53               SPlot2d_Curve* plotCurve,
54               int theDisplaying)
55   {
56     if ( theDisplaying == VISU::eErase ) {
57       if ( plotCurve && thePlot )
58         thePlot->eraseCurve( plotCurve, false );
59     }
60     else if ( theDisplaying == VISU::eDisplay || theDisplaying == VISU::eDisplayOnly ) {
61       if ( plotCurve ) {
62         plotCurve->setHorTitle( theCurve->GetHorTitle().c_str() );
63         //plotCurve->setVerTitle( ( theCurve->GetVerTitle().c_str() ) );
64         plotCurve->setVerTitle( theCurve->GetName().c_str() );
65         plotCurve->setHorUnits( theCurve->GetHorUnits().c_str() );
66         plotCurve->setVerUnits( theCurve->GetVerUnits().c_str() );
67         plotCurve->setScale( theCurve->GetScale() );
68         double* xList = 0;
69         double* yList = 0;
70         QStringList zList;
71         int nbPoints = theCurve->GetData( xList, yList, zList );
72         if ( nbPoints > 0 && xList && yList ) {
73           plotCurve->setData( xList, yList, nbPoints, zList );
74         }
75         if(theCurve->isDeviationShown()){
76           double* min = 0;
77           double* max = 0;
78           QList<int> indexes;
79           int nbPoints = theCurve->GetDeviationData( min, max, indexes );
80           if ( nbPoints > 0 && min && max ) {
81             plotCurve->setDeviationData(min, max, indexes);
82             delete min;
83             delete max;
84           }
85         } else {
86             plotCurve->clearDeviationData();
87         }
88         if ( !theCurve->IsAuto() ) {
89           plotCurve->setLine( (Plot2d::LineType)theCurve->GetLine(), theCurve->GetLineWidth() );
90           plotCurve->setMarker( (Plot2d::MarkerType)theCurve->GetMarker() );
91           SALOMEDS::Color color = theCurve->GetColor();
92           plotCurve->setColor( QColor( (int)(color.R*255.), (int)(color.G*255.), (int)(color.B*255.) ) );
93         }
94         plotCurve->setAutoAssign( theCurve->IsAuto() );
95         if( thePlot )
96           thePlot->displayCurve( plotCurve, false );
97       }
98       else {
99         Plot2d_Curve* crv = theCurve->CreatePresentation();
100         if ( crv ) {
101           if( thePlot )
102             thePlot->displayCurve( crv, false );
103           theCurve->SetLine( (VISU::Curve::LineType)crv->getLine(), crv->getLineWidth() );
104           theCurve->SetMarker( (VISU::Curve::MarkerType)crv->getMarker());
105           SALOMEDS::Color newColor;
106           newColor.R = crv->getColor().red()/255.;
107           newColor.G = crv->getColor().green()/255.;
108           newColor.B = crv->getColor().blue()/255.;
109           theCurve->SetColor( newColor );
110           crv->setAutoAssign( theCurve->IsAuto() );
111         }
112       }
113     }
114   }
115
116   //------------------------------------------------------------
117   void
118   PlotTable(SalomeApp_Study* theStudy,
119             Plot2d_ViewFrame* thePlot,
120             VISU::Table_i* table,
121             int theDisplaying)
122   {
123     if ( !thePlot )
124       return;
125
126     if ( theDisplaying == VISU::eDisplayOnly )
127       thePlot->EraseAll();
128     QList<Plot2d_Curve*> clist;
129     thePlot->getCurves( clist );
130     _PTR(Study) aStudy = theStudy->studyDS();
131     _PTR(SObject) TableSO = aStudy->FindObjectID( table->GetEntry() );
132     if ( TableSO ) {
133       _PTR(ChildIterator) Iter = aStudy->NewChildIterator( TableSO );
134       for ( ; Iter->More(); Iter->Next() ) {
135         CORBA::Object_var childObject = VISU::ClientSObjectToObject( Iter->Value() );
136         if( !CORBA::is_nil( childObject ) ) {
137           CORBA::Object_ptr aCurve = VISU::Curve::_narrow( childObject );
138           if( !CORBA::is_nil( aCurve ) ) {
139             VISU::Curve_i* theCurve = dynamic_cast<VISU::Curve_i*>(VISU::GetServant(aCurve).in());
140             SPlot2d_Curve* plotCurve = 0;
141             SPlot2d_Curve* tmpCurve;
142             for ( int i = 0; i < clist.count(); i++ ) {
143               tmpCurve = dynamic_cast<SPlot2d_Curve*>( clist.at( i ) );
144               if (tmpCurve && tmpCurve->hasIO() &&
145                   theCurve->GetEntry() == tmpCurve->getIO()->getEntry()) {
146                 plotCurve = tmpCurve;
147                 break;
148               }
149             }
150
151             UpdateCurve( theCurve, thePlot, plotCurve, theDisplaying );
152             CurveVisibilityChanged(theCurve, theDisplaying, true, false, true);
153
154             if ( theDisplaying == VISU::eErase && plotCurve ) {
155               clist.removeAll(plotCurve );
156             }
157           }
158         }
159       }
160       thePlot->Repaint();
161       SetVisibilityState(table->GetEntry(),GetStateByDisplaying(theDisplaying));
162     }
163     
164   }
165
166   //------------------------------------------------------------
167   void
168   PlotCurve(Plot2d_ViewFrame* thePlot,
169             VISU::Curve_i* theCurve,
170             int theDisplaying)
171   {
172     if ( !thePlot )
173       return;
174
175 //  if ( theDisplaying == VISU::eDisplayOnly )
176 //    thePlot->EraseAll();
177     QList<Plot2d_Curve*> clist;
178     thePlot->getCurves( clist );
179     SPlot2d_Curve* plotCurve = 0;
180     SPlot2d_Curve* tmpCurve;
181     if(theDisplaying == VISU::eErase) {
182       // 23.06.2008 skl for IPAL17672
183       for (int i = 0; i < clist.count(); i++) {
184         tmpCurve = dynamic_cast<SPlot2d_Curve*>(clist.at(i));
185         if (tmpCurve && tmpCurve->hasIO() &&
186             theCurve->GetEntry() == tmpCurve->getIO()->getEntry()) {
187           plotCurve = tmpCurve;
188           thePlot->eraseCurve(clist.at(i));
189           break;
190         }
191       }
192       UpdateCurve(theCurve, thePlot, plotCurve, theDisplaying);
193     }
194     else {
195       for (int i = 0; i < clist.count(); i++) {
196         tmpCurve = dynamic_cast<SPlot2d_Curve*>(clist.at(i));
197         if (tmpCurve && tmpCurve->hasIO() &&
198             theCurve->GetEntry() == tmpCurve->getIO()->getEntry()) {
199           plotCurve = tmpCurve;
200         }
201         else if (theDisplaying == VISU::eDisplayOnly) {
202           thePlot->eraseCurve(clist.at(i));
203         }
204       }
205       UpdateCurve(theCurve, thePlot, plotCurve, theDisplaying);
206     }
207
208     thePlot->Repaint();
209
210     SetVisibilityState(theCurve->GetEntry(),GetStateByDisplaying(theDisplaying));
211     CurveVisibilityChanged(theCurve,theDisplaying,false, true, true);
212   }
213
214   //------------------------------------------------------------
215   void
216   PlotRemoveCurve(SalomeApp_Application* theApp,
217                   VISU::Curve_i* pCrv)
218   {
219     QString anEntry = pCrv->GetEntry().c_str();
220     ViewManagerList pvm_list;
221     theApp->viewManagers( SPlot2d_Viewer::Type(), pvm_list );
222     ViewManagerList::Iterator pvm_it = pvm_list.begin();
223     for( ; pvm_it != pvm_list.end(); pvm_it++ ){
224       Plot2d_ViewManager* pvm = dynamic_cast<Plot2d_ViewManager*>( *pvm_it );
225       if( pvm ){
226         SPlot2d_Viewer* aSPlot2d = dynamic_cast<SPlot2d_Viewer*>( pvm->getViewModel() );
227         if( aSPlot2d ){
228           Plot2d_ViewFrame* thePlot = aSPlot2d->getActiveViewFrame();
229           if(thePlot){
230             QList<Plot2d_Curve*> clist;
231             thePlot->getCurves( clist );
232             for (int i = 0; i < clist.count(); i++) {
233               if(SPlot2d_Curve* plotCurve = dynamic_cast<SPlot2d_Curve*>(clist[i]))
234                 if(plotCurve->hasIO() && (plotCurve->getIO()->getEntry() == anEntry))
235                   thePlot->eraseCurve(clist[i]);
236             }
237           }
238         }
239       }
240     }
241   }
242   
243   //------------------------------------------------------------
244   // Internal function used by the function below
245   SPlot2d_Curve* GetCurveByIO( const Handle(SALOME_InteractiveObject)& theIObject,
246                                Plot2d_ViewFrame* thePlot )
247   {
248     if ( !theIObject.IsNull() && thePlot ) {
249       CurveDict aCurves = thePlot->getCurves();
250       CurveDict::Iterator it = aCurves.begin();
251       for( ; it != aCurves.end(); ++it ) {
252         SPlot2d_Curve* aCurve = dynamic_cast<SPlot2d_Curve*>( it.value() );
253         if(aCurve) {
254           if ( aCurve->hasIO() && aCurve->getIO()->isSame( theIObject ) )
255             return aCurve;
256         }
257       }
258     }
259     return NULL;
260   }
261
262   //------------------------------------------------------------
263   void
264   PlotContainer(Plot2d_ViewFrame* thePlot,
265                 VISU::Container_i* container,
266                 int theDisplaying)
267   {
268     if ( !thePlot || !container)
269       return;
270
271     if ( theDisplaying == VISU::eDisplayOnly )
272       thePlot->EraseAll();
273     QList<Plot2d_Curve*> clist;
274     thePlot->getCurves( clist );
275     if ( container->GetNbCurves() > 0 ) {
276       int nbCurves = container->GetNbCurves();
277       SetVisibilityState(container->GetEntry(), GetStateByDisplaying(theDisplaying));
278       for ( int k = 1; k <= nbCurves; k++ ) {
279         VISU::Curve_i* theCurve = container->GetCurve( k );
280         if ( theCurve && theCurve->IsValid() ) {
281           SPlot2d_Curve* plotCurve = GetCurveByIO(new SALOME_InteractiveObject(theCurve->GetEntry().c_str(), "", ""), thePlot);
282
283           UpdateCurve( theCurve, thePlot, plotCurve, theDisplaying );
284
285           if ( plotCurve && theDisplaying == VISU::eErase ) {
286             clist.removeAll( plotCurve );
287           }
288           CurveVisibilityChanged(theCurve, theDisplaying, true, true, true);
289         }
290       }
291     }
292     
293     thePlot->Repaint();
294     if(GetResourceMgr()->booleanValue("VISU","automatic_fit_all",false)){
295       thePlot->fitAll();
296     }
297     
298     qApp->processEvents();
299   }
300
301   //------------------------------------------------------------
302   void
303   CreatePlot(VISU_Gen_i* theVisuGen,
304              Plot2d_ViewFrame* thePlot,
305              _PTR(SObject) theTableSO)
306   {
307     _PTR(GenericAttribute) anAttr;
308     if ( theTableSO &&
309          ( theTableSO->FindAttribute( anAttr, "AttributeTableOfInteger" ) ||
310            theTableSO->FindAttribute( anAttr, "AttributeTableOfReal" ) ) ) {
311       CORBA::Object_var aTable = VISU::ClientSObjectToObject(theTableSO);
312       CORBA::Object_var aContainer = theVisuGen->CreateContainer();
313
314       if ( !CORBA::is_nil( aTable ) && !CORBA::is_nil( aContainer ) ) {
315         VISU::Table_i*     pTable     = dynamic_cast<VISU::Table_i*>(VISU::GetServant(aTable).in());
316         VISU::Container_i* pContainer = dynamic_cast<VISU::Container_i*>(VISU::GetServant(aContainer).in());
317
318         if ( pContainer && pTable ) {
319           for ( int i = 2; i <= pTable->GetNbRows(); i++ ) {
320             CORBA::Object_var aNewCurve = theVisuGen->CreateCurve( pTable->_this(), 1, i );
321             if( !CORBA::is_nil( aNewCurve ) ) {
322               VISU::Curve_i* pCrv = dynamic_cast<VISU::Curve_i*>( VISU::GetServant(aNewCurve).in() );
323               if ( pCrv ) {
324                 pContainer->AddCurve( pCrv->_this() );
325               }
326             }
327           }
328           PlotContainer( thePlot, pContainer, VISU::eDisplay );
329
330           QString anEntry = pContainer->GetEntry().c_str();
331           _PTR(Study) aStudy = theTableSO->GetStudy();
332           _PTR(SObject) aContainerSO = aStudy->FindObjectID(anEntry.toLatin1().data());
333           _PTR(SObject) aParentSO = aContainerSO->GetFather();
334         }
335       }
336     }
337   }
338
339   //------------------------------------------------------------
340   void SetVisibilityState(std::string entry, Qtx::VisibilityState state) {
341     if(entry.empty())
342       return;
343
344     if( SUIT_Session* aSession = SUIT_Session::session() )
345       if( SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSession->activeApplication()) )
346         if( SalomeApp_Study* aStudy =  dynamic_cast<SalomeApp_Study*>(anApp->activeStudy()) )
347           aStudy->setVisibilityState(entry.c_str(), state);
348
349   }
350
351   //------------------------------------------------------------
352   void SetVisibilityState(SALOME_Actor *theActor, Qtx::VisibilityState state) {
353     if(!theActor || !theActor->hasIO() || !theActor->getIO()->hasEntry())
354       return;
355     SetVisibilityState(theActor->getIO()->getEntry(), state);
356   }
357
358   void CurveVisibilityChanged(VISU::Curve_i* theCurve, 
359                               int theDisplaying,
360                               bool updateCurve,
361                               bool updateTable,
362                               bool updateContainers) {
363     
364     SUIT_Session* aSession = SUIT_Session::session();
365     if (!aSession) return;
366     
367     SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSession->activeApplication());
368     if ( !anApp ) return;
369
370     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
371     if ( !aStudy ) return;
372
373     SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>( anApp->module( anApp->moduleTitle( "VISU" ) ) );
374     if ( !aModule ) return;
375
376     LightApp_Displayer* aDisplayer = aModule->displayer();
377
378     SUIT_ViewManager* aManager = anApp->activeViewManager();
379
380     Qtx::VisibilityState state = ( aManager && aManager->getType() == SPlot2d_Viewer::Type() ) ?
381       GetStateByDisplaying(theDisplaying) : Qtx::UnpresentableState;
382     
383     if ( updateCurve )
384       SetVisibilityState( theCurve->GetEntry(), state );
385     
386     if ( updateTable ) {
387       Table_i* aTable = theCurve->getTable();
388       if ( aTable && !(aStudy->visibilityState( aTable->GetEntry().c_str() ) == state) ) {
389         _PTR(SObject) TableSO = aStudy->studyDS()->FindObjectID( aTable->GetEntry() );
390         if ( TableSO ) {
391           bool isTableVisible = false;
392           if ( aDisplayer && state != Qtx::UnpresentableState ) {
393             _PTR(ChildIterator) Iter = aStudy->studyDS()->NewChildIterator( TableSO );
394             for ( ; Iter->More() && !isTableVisible ; Iter->Next() ) {
395               CORBA::Object_var childObject = VISU::ClientSObjectToObject( Iter->Value() );
396               if ( CORBA::is_nil( childObject ) ) continue;
397               VISU::Curve_i* aCurve = dynamic_cast<VISU::Curve_i*>( VISU::GetServant( childObject.in() ).in() );
398               isTableVisible = aCurve && aDisplayer->IsDisplayed( aCurve->GetEntry().c_str() );
399             }
400           } // if ( aDisplayer ... )
401           if ( state != Qtx::UnpresentableState )
402             SetVisibilityState( aTable->GetEntry(), ( isTableVisible ? Qtx::ShownState : Qtx::HiddenState ) );
403           else 
404             SetVisibilityState( aTable->GetEntry(), state );
405         } // if ( TableSO )
406       } // if ( aTable )
407     } // if ( updateTable )
408
409     if ( updateContainers ) {
410       ContainerSet aContainers = theCurve->getContainers();
411       ContainerSet::ConstIterator it = aContainers.begin();
412       for ( ; it != aContainers.end(); it++ ) {
413         //Check that state of container is not set already
414         if(aStudy->visibilityState(*it) == state) continue;
415         _PTR(SObject) aSObject = aStudy->studyDS()->FindObjectID( (*it).toLatin1().data() );
416         if ( !aSObject ) continue;
417         bool isContainerDisplayed = false;
418         if ( aDisplayer && state != Qtx::UnpresentableState ) {
419           CORBA::Object_var anObj = VISU::ClientSObjectToObject( aSObject );
420           if ( CORBA::is_nil( anObj ) ) continue;
421           VISU::Container_i* aContainer = dynamic_cast<VISU::Container_i*>( VISU::GetServant( anObj.in() ).in() );
422           if ( !aContainer ) continue;
423           int nbCurves = aContainer->GetNbCurves();
424           for ( int k = 1; k <= nbCurves && !isContainerDisplayed; k++ ) {
425             VISU::Curve_i* aCurve = aContainer->GetCurve( k );
426             isContainerDisplayed = aCurve && aDisplayer->IsDisplayed( aCurve->GetEntry().c_str() );
427           }
428         } // if ( aDisplayer ... )
429         if ( state != Qtx::UnpresentableState )
430           SetVisibilityState( (*it).toLatin1().constData(), ( isContainerDisplayed ? Qtx::ShownState : Qtx::HiddenState ) );
431         else {
432           SetVisibilityState( (*it).toLatin1().constData(), state );
433         }
434       } // for ( ; it != aContainers.end(); it++ )
435     } //updateContainers    
436   }
437   
438   Qtx::VisibilityState GetStateByDisplaying(int theDisplaying)
439   {
440     Qtx::VisibilityState state = Qtx::UnpresentableState;
441     if(theDisplaying == eDisplayAll || 
442        theDisplaying == eDisplay    || 
443        theDisplaying == eDisplayOnly ) {
444       state = Qtx::ShownState;
445       
446     } else if (theDisplaying == eErase || theDisplaying == eEraseAll) {
447       state = Qtx::HiddenState;
448     }
449     return state;
450   }
451
452   void updateContainerVisibility(VISU::Container_i* theContainer)
453   {
454     if ( !theContainer ) return;
455     
456     SUIT_Session* aSession = SUIT_Session::session();
457     if (!aSession) return;
458     
459     SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>(aSession->activeApplication());
460     if ( !anApp ) return;
461
462     SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
463     if ( !aStudy ) return;
464
465     SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>( anApp->module( anApp->moduleTitle( "VISU" ) ) );
466     if ( !aModule ) return;
467
468     SUIT_ViewManager* aManager = anApp->activeViewManager();
469     int nbCurves = theContainer->GetNbCurves();
470     
471     Qtx::VisibilityState state = ( aManager && aManager->getType() == SPlot2d_Viewer::Type() && nbCurves > 0 ) ?
472       Qtx::HiddenState : Qtx::UnpresentableState;
473     
474     LightApp_Displayer* aDisplayer = aModule->displayer();
475
476     if ( nbCurves > 0 && aDisplayer ) {
477       for ( int k = 1; k <= nbCurves; k++ ) {
478         VISU::Curve_i* aCurve = theContainer->GetCurve( k );
479         if ( aCurve && aDisplayer->IsDisplayed( aCurve->GetEntry().c_str() ) ) {
480           state = Qtx::ShownState;
481           break;
482         }             
483       }
484     }
485     aStudy->setVisibilityState( theContainer->GetEntry().c_str(), state );
486   }
487 }