Salome HOME
57d33b38a1e7a17178479d7fc181a2aca7731614
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_OCCDisplayer.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_OCCDisplayer.h"
24
25 #include "HYDROGUI_DataModel.h"
26 #include "HYDROGUI_Module.h"
27 #include "HYDROGUI_Tool.h"
28 #include <HYDROGUI_ShapeImage.h>
29 #include <HYDROGUI_ShapeBathymetry.h>
30 #include "HYDROGUI_Operation.h"
31 #include "HYDROGUI_DataObject.h"
32 #include "HYDROGUI_ZLayers.h"
33 #include <HYDROData_Bathymetry.h>
34
35 #include <AIS_InteractiveContext.hxx>
36 #include <AIS_ListIteratorOfListOfInteractive.hxx>
37 #include <AIS_ListOfInteractive.hxx>
38
39 #include <Aspect_ColorScale.hxx>
40
41 #include <TColStd_SequenceOfInteger.hxx>
42
43 #include <LightApp_Application.h>
44 #include <SUIT_Study.h>
45
46 #include <OCCViewer_ViewManager.h>
47 #include <OCCViewer_ViewModel.h>
48 #include <OCCViewer_ViewWindow.h>
49 #include <OCCViewer_ViewPort3d.h>
50
51 HYDROGUI_OCCDisplayer::HYDROGUI_OCCDisplayer( HYDROGUI_Module* theModule )
52 : HYDROGUI_AbstractDisplayer( theModule )
53 {
54   myToUpdateColorScale = false;
55 }
56
57 HYDROGUI_OCCDisplayer::~HYDROGUI_OCCDisplayer()
58 {
59 }
60
61 void HYDROGUI_OCCDisplayer::SetToUpdate( const HYDROData_SequenceOfObjects& theObjs,
62                                          const int                          theViewerId )
63 {
64   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
65   if( !aViewer )
66     return;
67
68   for ( int i = 1, n = theObjs.Length(); i <= n; i++ )
69   {
70     Handle(HYDROData_Entity) anObj = theObjs.Value( i );
71     if( anObj.IsNull() )
72       continue;
73
74     HYDROGUI_Shape* anObjShape = module()->getObjectShape( (size_t)aViewer, anObj );
75     if ( !anObjShape )
76       continue;
77     
78     anObjShape->setIsToUpdate( true );
79   }
80 }
81
82 int HYDROGUI_OCCDisplayer::AddPreviewZLayer( OCCViewer_ViewManager* theMgr )
83 {
84   int aLayer = -1;
85   OCCViewer_Viewer* aViewer = theMgr->getOCCViewer();
86   if ( !aViewer )
87     return aLayer;
88
89   aLayer = CreateTopZLayer( aViewer->getViewer3d() );
90   
91   // Hilight presentation should be on top
92   Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
93   if( !aCtx.IsNull() ) {
94     int aTopLayer = CreateTopZLayer( aViewer->getViewer3d() );
95     if ( aTopLayer > 0 ) {
96       UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, aTopLayer );
97     }
98   }
99
100   return aLayer;
101 }
102
103 void HYDROGUI_OCCDisplayer::RemoveZLayer( OCCViewer_ViewManager* theMgr,
104                                           const int theLayer )
105 {
106   if ( theLayer < 0 )
107     return;
108
109   OCCViewer_Viewer* aViewer = theMgr->getOCCViewer();
110   if ( !aViewer )
111     return;
112
113   // Get existing Z layers
114   TColStd_SequenceOfInteger anExistingZLayers;
115   aViewer->getViewer3d()->GetAllZLayers( anExistingZLayers );
116   int aNbLayers = anExistingZLayers.Length();
117   
118   if ( theLayer < aNbLayers )
119     aViewer->getViewer3d()->RemoveZLayer( theLayer );
120 }
121
122 void HYDROGUI_OCCDisplayer::EraseAll( const int theViewerId )
123 {
124   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
125   if( !aViewer )
126     return;
127
128   module()->removeViewShapes( (size_t)aViewer );
129   UpdateColorScale( aViewer );
130 }
131
132 void HYDROGUI_OCCDisplayer::Erase( const HYDROData_SequenceOfObjects& theObjs,
133                                    const int                          theViewerId )
134 {
135   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
136   if( !aViewer )
137     return;
138
139   for ( int i = 1, n = theObjs.Length(); i <= n; i++ )
140   {
141     Handle(HYDROData_Entity) anObj = theObjs.Value( i );
142     if( anObj.IsNull() )
143       continue;
144
145     module()->removeObjectShape( (size_t)aViewer, anObj );
146   }
147   aViewer->update();
148   UpdateColorScale( aViewer );
149 }
150
151 HYDROGUI_Shape* HYDROGUI_OCCDisplayer::createShape( const int                             theViewerId,
152                                                     const Handle(AIS_InteractiveContext)& theContext,
153                                                     const Handle(HYDROData_Entity)&       theObject )
154 {
155   HYDROGUI_Shape* aResShape = NULL;
156   if ( theContext.IsNull() || theObject.IsNull() )
157     return aResShape;
158
159   if ( !HYDROGUI_Tool::IsObjectHasPresentation( theObject, OCCViewer_Viewer::Type() ) )
160     return aResShape;
161
162   if( theObject->IsKind( STANDARD_TYPE( HYDROData_Image ) ) )
163     aResShape = new HYDROGUI_ShapeImage( theContext, Handle_HYDROData_Image::DownCast( theObject ) );
164   else if( theObject->IsKind( STANDARD_TYPE( HYDROData_Bathymetry ) ) )
165     aResShape = new HYDROGUI_ShapeBathymetry( this, theContext, Handle_HYDROData_Bathymetry::DownCast( theObject ) );
166   else
167     aResShape = new HYDROGUI_Shape( theContext, theObject );
168
169   module()->setObjectShape( theViewerId, theObject, aResShape );
170
171   return aResShape;
172 }
173
174 void HYDROGUI_OCCDisplayer::Display( const HYDROData_SequenceOfObjects& theObjs,
175                                      const int                          theViewerId,
176                                      const bool                         theIsForced,
177                                      const bool theDoFitAll )
178 {
179   // Get OCC viewer by id
180   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
181   if( !aViewer )
182     return;
183
184   // Get interactive context
185   Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
186   if( aCtx.IsNull() )
187     return;
188
189   // Get the document
190   Handle(HYDROData_Document) aDoc = HYDROData_Document::Document( module()->getStudyId() );
191   if ( !aDoc )
192     return;
193   
194   // Assign Z layer indexes to the objects
195   aDoc->Show( theObjs );
196
197   // Sort objects by display order ( needed for Z layers assignment only )
198   HYDROData_SequenceOfObjects anUnorderedToDisplay = theObjs;
199   HYDROData_SequenceOfObjects anOrderedToDisplay;
200   HYDROData_SequenceOfObjects anAllOrderedObjects = aDoc->GetObjectsLayerOrder();
201
202   HYDROData_SequenceOfObjects::Iterator anAllOrderedIter( anAllOrderedObjects );
203   for ( ; anAllOrderedIter.More(); anAllOrderedIter.Next() ) {
204     QString anOrderedEntry = 
205       HYDROGUI_DataObject::dataObjectEntry( anAllOrderedIter.Value() );
206     
207     HYDROData_SequenceOfObjects::Iterator aToDisplayIter( anUnorderedToDisplay );
208     for ( ; aToDisplayIter.More(); aToDisplayIter.Next() ) {
209       Handle(HYDROData_Entity) anObjToDisplay = aToDisplayIter.Value();
210       QString anEntry = HYDROGUI_DataObject::dataObjectEntry( anObjToDisplay );
211       if ( anEntry == anOrderedEntry ) {
212         anOrderedToDisplay.Prepend( anObjToDisplay );
213         anUnorderedToDisplay.Remove( aToDisplayIter );
214         break;
215       }
216     }
217   }
218   
219   // Get 3d viewer
220   Handle(V3d_Viewer) aViewer3d = aViewer->getViewer3d();
221
222   // Display objects:
223   HYDROGUI_ZLayersIterator aZLayersIt( aViewer->getViewer3d() );
224   if ( !aZLayersIt.More() ) {
225     aZLayersIt.Next();
226   }
227
228   // 1. Display the ordered objects:
229   HYDROData_SequenceOfObjects::Iterator anOrderedIter( anOrderedToDisplay );
230   for ( ; anOrderedIter.More(); anOrderedIter.Next() ) {
231     Handle(HYDROData_Entity) anObj = anOrderedIter.Value();
232     if ( Display( anObj, aViewer, theIsForced ) ) {
233       // set Z layer ( one Z layer for each ordered object )
234       int aZLayerId = aZLayersIt.LayerId();
235       SetZLayer( aViewer, anObj, aZLayerId );
236       SetZLayerSettings( aViewer3d, aZLayerId, true );
237       aZLayersIt.Next();
238     }
239   }
240
241   // 2. Display the unordered objects:
242   bool isDisplayed = false;
243   int anUnorderedZLayerId = aZLayersIt.LayerId();
244   HYDROData_SequenceOfObjects::Iterator anUnorderedIter( anUnorderedToDisplay );
245   for ( ; anUnorderedIter.More(); anUnorderedIter.Next() ) {
246     Handle(HYDROData_Entity) anObj = anUnorderedIter.Value();
247     if ( Display( anObj, aViewer, theIsForced) ) {
248       // set Z layer ( one Z layer for all unordered objects )
249       SetZLayer( aViewer, anObj, anUnorderedZLayerId );
250       if ( !isDisplayed ) {
251         SetZLayerSettings( aViewer3d, anUnorderedZLayerId, false );
252       }
253       isDisplayed = true;
254     }
255   }
256   
257   // 3. Update the top Z layer index
258   if ( isDisplayed ) {
259     aZLayersIt.Next();
260   }
261
262   // Update Z layer of the active operation
263   int aPreviewZLayerId = aZLayersIt.LayerId();
264
265   HYDROGUI_Module* aModule = module();
266   SUIT_Operation* anOp = aModule->activeOperation();
267   HYDROGUI_Operation* aHOp = anOp ? dynamic_cast<HYDROGUI_Operation*>( anOp ) : 0;
268   if ( aHOp && aHOp->getPreviewZLayer() >= 0 ) {
269     aHOp->updatePreviewZLayer( aPreviewZLayerId );
270     aZLayersIt.Next();
271   }
272
273   // Update Z layer of hilight presentations
274   int aHilightLayer = aZLayersIt.TopLayer();
275   UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, aHilightLayer );
276
277   // Fit all / update selection
278   if ( theDoFitAll ) {
279     OCCViewer_ViewManager* aViewManager
280       = ::qobject_cast<OCCViewer_ViewManager*>( aViewer->getViewManager() );
281     if ( aViewManager ) {
282       OCCViewer_ViewWindow* aViewWindow = 
283         ::qobject_cast<OCCViewer_ViewWindow*>( aViewManager->getActiveView() );
284       if ( aViewWindow ) {
285         aViewWindow->onFitAll();
286       }
287     }
288   } 
289   else if ( !aCtx.IsNull() ) { // TODO: determine if this code is necessary (added as a fix for issue# 359)
290     aCtx->UpdateSelected();
291   }
292
293   UpdateColorScale( aViewer );
294 }
295
296 void HYDROGUI_OCCDisplayer::purgeObjects( const int theViewerId )
297 {
298   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
299   if( !aViewer )
300     return;
301
302   Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
303   if( aCtx.IsNull() )
304     return;
305
306   AIS_ListOfInteractive aDisplayedObjects;
307   aCtx->DisplayedObjects( aDisplayedObjects );
308
309   AIS_ListIteratorOfListOfInteractive aListIter( aDisplayedObjects );
310   for ( ; aListIter.More(); aListIter.Next() )
311   {
312     Handle(AIS_InteractiveObject) aPrsObj = aListIter.Value();
313     if ( aPrsObj.IsNull() )
314       continue;
315
316     Handle(HYDROData_Entity) anOwnerObj = 
317       Handle(HYDROData_Entity)::DownCast( aPrsObj->GetOwner() );
318     if ( !anOwnerObj.IsNull() && anOwnerObj->IsRemoved() )
319       module()->removeObjectShape( (size_t)aViewer, anOwnerObj );
320   }
321 }
322
323 QString HYDROGUI_OCCDisplayer::GetType() const
324 {
325   return OCCViewer_Viewer::Type();
326 }
327
328 bool HYDROGUI_OCCDisplayer::Display( const Handle(HYDROData_Entity)& theObject,
329                                      const OCCViewer_Viewer* theViewer,
330                                      const bool theIsForced )
331 {
332   bool aRes = false;
333
334   if ( theObject.IsNull() || theObject->IsRemoved() || !theViewer ) {
335     return aRes;
336   }
337
338   // Get interactive context
339   Handle(AIS_InteractiveContext) aCtx = theViewer->getAISContext();
340   if( aCtx.IsNull() ) {
341     return aRes;
342   }
343
344   // Viewer id
345   size_t aViewerId = (size_t)theViewer;
346
347   // Object shape 
348   HYDROGUI_Shape* anObjShape = module()->getObjectShape( aViewerId, theObject );
349   // create if needed
350   if ( !anObjShape ) {
351     anObjShape = createShape( aViewerId, aCtx, theObject );
352     if ( anObjShape ) {
353       anObjShape->setIsToUpdate( true );
354     }
355   }
356   
357   // Process the shape
358   if ( anObjShape ) {
359     // update if needed
360     if ( anObjShape->getIsToUpdate() || theIsForced ) {
361       anObjShape->update( false, false );
362     }
363
364     // Set visibility
365     bool anIsVisible = module()->isObjectVisible( aViewerId, theObject );
366     anObjShape->setVisible( anIsVisible, false );
367
368     aRes = true;
369   }
370
371   return aRes;
372 }
373
374 void HYDROGUI_OCCDisplayer::SetZLayer( const OCCViewer_Viewer* theViewer,
375                                        const Handle(HYDROData_Entity)& theObject, 
376                                        const int theZLayerId )
377 {
378   if ( !theViewer || ( theZLayerId < 0 ) ) {
379     return;
380   }
381   
382   // Get interactive context
383   Handle(AIS_InteractiveContext) aCtx = theViewer->getAISContext();
384   if( aCtx.IsNull() ) {
385     return;
386   }
387
388   // Get viewer id
389   size_t aViewerId = (size_t)theViewer;
390
391   // Get object shape 
392   HYDROGUI_Shape* anObjShape = module()->getObjectShape( aViewerId, theObject );
393
394   // Set Z layer
395   if ( anObjShape ) {
396     aCtx->SetZLayer( anObjShape->getAISObject(), theZLayerId );
397   }
398 }
399
400 void HYDROGUI_OCCDisplayer::SetToUpdateColorScale()
401 {
402   myToUpdateColorScale = true;
403 }
404
405 void HYDROGUI_OCCDisplayer::UpdateColorScale( const OCCViewer_Viewer* theViewer )
406 {
407   if( !myToUpdateColorScale )
408     return;
409
410   OCCViewer_ViewWindow* aWnd = dynamic_cast<OCCViewer_ViewWindow*>( theViewer->getViewManager()->getActiveView() );
411   Handle(V3d_View) aView = aWnd->getViewPort()->getView();
412
413   int aViewerId = (size_t)theViewer;//TODO: check if viewer id is correct
414   QList<HYDROGUI_Shape*> aShapes = module()->getObjectShapes( aViewerId, KIND_BATHYMETRY );
415
416   bool isDisplayColorScale = !aShapes.empty();
417   Standard_Real anXPos = 0.05; //TODO
418   Standard_Real anYPos = 0.1; //TODO
419   Standard_Real aWidth = 0.2; //TODO
420   Standard_Real aHeight = 0.5; //TODO
421   Standard_Integer aTextHeight = 14; //TODO
422   Standard_Integer aNbIntervals = 20; //TODO
423   TCollection_ExtendedString aColorScaleTitle = "";//TODO
424
425   Standard_Real aColorScaleMin = 0, aColorScaleMax = 1, aMin, aMax;
426   bool isFirst = true;
427   foreach( HYDROGUI_Shape* aShape, aShapes )
428   {
429     HYDROGUI_ShapeBathymetry* aBathShape = dynamic_cast<HYDROGUI_ShapeBathymetry*>( aShape );
430     if( !aBathShape || !aBathShape->isVisible() )
431       continue;
432
433     aBathShape->GetRange( aMin, aMax );
434
435     if( isFirst || aMin < aColorScaleMin )
436       aColorScaleMin = aMin;
437     if( isFirst || aMax > aColorScaleMax )
438       aColorScaleMax = aMax;
439
440     isFirst = false;
441   }
442
443   if( isDisplayColorScale )
444   {
445     Handle(Aspect_ColorScale) aColorScale = aView->ColorScale();
446     if( !aColorScale.IsNull() )
447     {
448       aColorScale->SetXPosition( anXPos );
449       aColorScale->SetYPosition( anYPos );
450       aColorScale->SetWidth( aWidth );
451       aColorScale->SetHeight( aHeight );
452
453       aColorScale->SetTextHeight( aTextHeight );
454       aColorScale->SetNumberOfIntervals( aNbIntervals );
455
456       aColorScale->SetTitle( aColorScaleTitle );
457       aColorScale->SetRange( aColorScaleMin, aColorScaleMax );
458
459       foreach( HYDROGUI_Shape* aShape, aShapes )
460       {
461         HYDROGUI_ShapeBathymetry* aBathShape = dynamic_cast<HYDROGUI_ShapeBathymetry*>( aShape );
462         if( !aBathShape || !aBathShape->isVisible() )
463           continue;
464
465         aBathShape->UpdateWithColorScale( aColorScale );
466       }
467     }
468     if( !aView->ColorScaleIsDisplayed() )
469       aView->ColorScaleDisplay();
470   }
471   else
472   {
473     if( aView->ColorScaleIsDisplayed() )
474       aView->ColorScaleErase();
475   }
476
477   myToUpdateColorScale = false;
478 }