Salome HOME
Refactoring. Hilight presentation on top.
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_OCCDisplayer.cxx
1 // Copyright (C) 2007-2013  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.
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_Shape.h"
29 #include "HYDROGUI_Operation.h"
30 #include "HYDROGUI_DataObject.h"
31 #include "HYDROGUI_ZLayers.h"
32
33 #include <AIS_InteractiveContext.hxx>
34 #include <AIS_ListIteratorOfListOfInteractive.hxx>
35 #include <AIS_ListOfInteractive.hxx>
36
37 #include <TColStd_SequenceOfInteger.hxx>
38
39 #include <LightApp_Application.h>
40 #include <SUIT_Study.h>
41
42 #include <OCCViewer_ViewManager.h>
43 #include <OCCViewer_ViewModel.h>
44 #include <OCCViewer_ViewWindow.h>
45
46 HYDROGUI_OCCDisplayer::HYDROGUI_OCCDisplayer( HYDROGUI_Module* theModule )
47 : HYDROGUI_AbstractDisplayer( theModule )
48 {
49 }
50
51 HYDROGUI_OCCDisplayer::~HYDROGUI_OCCDisplayer()
52 {
53 }
54
55 void HYDROGUI_OCCDisplayer::SetToUpdate( const HYDROData_SequenceOfObjects& theObjs,
56                                          const int                          theViewerId )
57 {
58   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
59   if( !aViewer )
60     return;
61
62   for ( int i = 1, n = theObjs.Length(); i <= n; i++ )
63   {
64     Handle(HYDROData_Entity) anObj = theObjs.Value( i );
65     if( anObj.IsNull() )
66       continue;
67
68     HYDROGUI_Shape* anObjShape = module()->getObjectShape( (size_t)aViewer, anObj );
69     if ( !anObjShape )
70       continue;
71     
72     anObjShape->setIsToUpdate( true );
73   }
74 }
75
76 int HYDROGUI_OCCDisplayer::AddPreviewZLayer( OCCViewer_ViewManager* theMgr )
77 {
78   int aLayer = -1;
79   OCCViewer_Viewer* aViewer = theMgr->getOCCViewer();
80   if ( !aViewer )
81     return aLayer;
82
83   aLayer = CreateTopZLayer( aViewer->getViewer3d() );
84   
85   // Hilight presentation should be on top
86   Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
87   if( !aCtx.IsNull() ) {
88     int aTopLayer = CreateTopZLayer( aViewer->getViewer3d() );
89     if ( aTopLayer > 0 ) {
90       UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, aTopLayer );
91     }
92   }
93
94   return aLayer;
95 }
96
97 void HYDROGUI_OCCDisplayer::RemoveZLayer( OCCViewer_ViewManager* theMgr,
98                                           const int theLayer )
99 {
100   if ( theLayer < 0 )
101     return;
102
103   OCCViewer_Viewer* aViewer = theMgr->getOCCViewer();
104   if ( !aViewer )
105     return;
106
107   // Get existing Z layers
108   TColStd_SequenceOfInteger anExistingZLayers;
109   aViewer->getViewer3d()->GetAllZLayers( anExistingZLayers );
110   int aNbLayers = anExistingZLayers.Length();
111   
112   if ( theLayer < aNbLayers )
113     aViewer->getViewer3d()->RemoveZLayer( theLayer );
114 }
115
116 void HYDROGUI_OCCDisplayer::EraseAll( const int theViewerId )
117 {
118   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
119   if( !aViewer )
120     return;
121
122   module()->removeViewShapes( (size_t)aViewer );
123 }
124
125 void HYDROGUI_OCCDisplayer::Erase( const HYDROData_SequenceOfObjects& theObjs,
126                                    const int                          theViewerId )
127 {
128   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
129   if( !aViewer )
130     return;
131
132   for ( int i = 1, n = theObjs.Length(); i <= n; i++ )
133   {
134     Handle(HYDROData_Entity) anObj = theObjs.Value( i );
135     if( anObj.IsNull() )
136       continue;
137
138     module()->removeObjectShape( (size_t)aViewer, anObj );
139   }
140   aViewer->update();
141 }
142
143 HYDROGUI_Shape* HYDROGUI_OCCDisplayer::createShape( const int                             theViewerId,
144                                                     const Handle(AIS_InteractiveContext)& theContext,
145                                                     const Handle(HYDROData_Entity)&       theObject )
146 {
147   HYDROGUI_Shape* aResShape = NULL;
148   if ( theContext.IsNull() || theObject.IsNull() )
149     return aResShape;
150
151   if ( !HYDROGUI_Tool::IsObjectHasPresentation( theObject, OCCViewer_Viewer::Type() ) )
152     return aResShape;
153
154   aResShape = new HYDROGUI_Shape( theContext, theObject );
155   module()->setObjectShape( theViewerId, theObject, aResShape );
156
157   return aResShape;
158 }
159
160 void HYDROGUI_OCCDisplayer::Display( const HYDROData_SequenceOfObjects& theObjs,
161                                      const int                          theViewerId,
162                                      const bool                         theIsForced,
163                                      const bool theDoFitAll )
164 {
165   // Get OCC viewer by id
166   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
167   if( !aViewer )
168     return;
169
170   // Get interactive context
171   Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
172   if( aCtx.IsNull() )
173     return;
174
175   // Get the document
176   Handle(HYDROData_Document) aDoc = HYDROData_Document::Document( module()->getStudyId() );
177   if ( !aDoc )
178     return;
179   
180   // Assign Z layer indexes to the objects
181   aDoc->Show( theObjs );
182
183   // Sort objects by display order ( needed for Z layers assignment only )
184   HYDROData_SequenceOfObjects anUnorderedToDisplay = theObjs;
185   HYDROData_SequenceOfObjects anOrderedToDisplay;
186   HYDROData_SequenceOfObjects anAllOrderedObjects = aDoc->GetObjectsLayerOrder();
187
188   HYDROData_SequenceOfObjects::Iterator anAllOrderedIter( anAllOrderedObjects );
189   for ( ; anAllOrderedIter.More(); anAllOrderedIter.Next() ) {
190     QString anOrderedEntry = 
191       HYDROGUI_DataObject::dataObjectEntry( anAllOrderedIter.Value() );
192     
193     HYDROData_SequenceOfObjects::Iterator aToDisplayIter( anUnorderedToDisplay );
194     for ( ; aToDisplayIter.More(); aToDisplayIter.Next() ) {
195       Handle(HYDROData_Entity) anObjToDisplay = aToDisplayIter.Value();
196       QString anEntry = HYDROGUI_DataObject::dataObjectEntry( anObjToDisplay );
197       if ( anEntry == anOrderedEntry ) {
198         anOrderedToDisplay.Prepend( anObjToDisplay );
199         anUnorderedToDisplay.Remove( aToDisplayIter );
200         break;
201       }
202     }
203   }
204   
205   // Get 3d viewer
206   Handle(V3d_Viewer) aViewer3d = aViewer->getViewer3d();
207
208   // Display objects:
209   HYDROGUI_ZLayersIterator aZLayersIt( aViewer->getViewer3d() );
210   if ( !aZLayersIt.More() ) {
211     aZLayersIt.Next();
212   }
213
214   // 1. Display the ordered objects:
215   HYDROData_SequenceOfObjects::Iterator anOrderedIter( anOrderedToDisplay );
216   for ( ; anOrderedIter.More(); anOrderedIter.Next() ) {
217     Handle(HYDROData_Entity) anObj = anOrderedIter.Value();
218     if ( Display( anObj, aViewer, theIsForced ) ) {
219       // set Z layer ( one Z layer for each ordered object )
220       int aZLayerId = aZLayersIt.LayerId();
221       SetZLayer( aViewer, anObj, aZLayerId );
222       SetZLayerSettings( aViewer3d, aZLayerId, true );
223       aZLayersIt.Next();
224     }
225   }
226
227   // 2. Display the unordered objects:
228   bool isDisplayed = false;
229   int anUnorderedZLayerId = aZLayersIt.LayerId();
230   HYDROData_SequenceOfObjects::Iterator anUnorderedIter( anUnorderedToDisplay );
231   for ( ; anUnorderedIter.More(); anUnorderedIter.Next() ) {
232     Handle(HYDROData_Entity) anObj = anUnorderedIter.Value();
233     if ( Display( anObj, aViewer, theIsForced) ) {
234       // set Z layer ( one Z layer for all unordered objects )
235       SetZLayer( aViewer, anObj, anUnorderedZLayerId );
236       if ( !isDisplayed ) {
237         SetZLayerSettings( aViewer3d, anUnorderedZLayerId, false );
238       }
239       isDisplayed = true;
240     }
241   }
242   
243   // 3. Update the top Z layer index
244   if ( isDisplayed ) {
245     aZLayersIt.Next();
246   }
247
248   // Update Z layer of the active operation
249   int aPreviewZLayerId = aZLayersIt.LayerId();
250
251   HYDROGUI_Module* aModule = module();
252   SUIT_Operation* anOp = aModule->activeOperation();
253   HYDROGUI_Operation* aHOp = anOp ? dynamic_cast<HYDROGUI_Operation*>( anOp ) : 0;
254   if ( aHOp && aHOp->getPreviewZLayer() >= 0 ) {
255     aHOp->updatePreviewZLayer( aPreviewZLayerId );
256     aZLayersIt.Next();
257   }
258
259   // Update Z layer of hilight presentations
260   int aHilightLayer = aZLayersIt.TopLayer();
261   UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, aHilightLayer );
262
263   // Fit all / update selection
264   if ( theDoFitAll ) {
265     OCCViewer_ViewManager* aViewManager
266       = ::qobject_cast<OCCViewer_ViewManager*>( aViewer->getViewManager() );
267     if ( aViewManager ) {
268       OCCViewer_ViewWindow* aViewWindow = 
269         ::qobject_cast<OCCViewer_ViewWindow*>( aViewManager->getActiveView() );
270       if ( aViewWindow ) {
271         aViewWindow->onFitAll();
272       }
273     }
274   } 
275   else if ( !aCtx.IsNull() ) { // TODO: determine if this code is necessary (added as a fix for issue# 359)
276     aCtx->UpdateSelected();
277   }
278 }
279
280 void HYDROGUI_OCCDisplayer::purgeObjects( const int theViewerId )
281 {
282   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
283   if( !aViewer )
284     return;
285
286   Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
287   if( aCtx.IsNull() )
288     return;
289
290   AIS_ListOfInteractive aDisplayedObjects;
291   aCtx->DisplayedObjects( aDisplayedObjects );
292
293   AIS_ListIteratorOfListOfInteractive aListIter( aDisplayedObjects );
294   for ( ; aListIter.More(); aListIter.Next() )
295   {
296     Handle(AIS_InteractiveObject) aPrsObj = aListIter.Value();
297     if ( aPrsObj.IsNull() )
298       continue;
299
300     Handle(HYDROData_Entity) anOwnerObj = 
301       Handle(HYDROData_Entity)::DownCast( aPrsObj->GetOwner() );
302     if ( !anOwnerObj.IsNull() && anOwnerObj->IsRemoved() )
303       module()->removeObjectShape( (size_t)aViewer, anOwnerObj );
304   }
305 }
306
307 QString HYDROGUI_OCCDisplayer::GetType() const
308 {
309   return OCCViewer_Viewer::Type();
310 }
311
312 bool HYDROGUI_OCCDisplayer::Display( const Handle(HYDROData_Entity)& theObject,
313                                      const OCCViewer_Viewer* theViewer,
314                                      const bool theIsForced )
315 {
316   bool aRes = false;
317
318   if ( theObject.IsNull() || theObject->IsRemoved() || !theViewer ) {
319     return aRes;
320   }
321
322   // Get interactive context
323   Handle(AIS_InteractiveContext) aCtx = theViewer->getAISContext();
324   if( aCtx.IsNull() ) {
325     return aRes;
326   }
327
328   // Viewer id
329   size_t aViewerId = (size_t)theViewer;
330
331   // Object shape 
332   HYDROGUI_Shape* anObjShape = module()->getObjectShape( aViewerId, theObject );
333   // create if needed
334   if ( !anObjShape ) {
335     anObjShape = createShape( aViewerId, aCtx, theObject );
336     if ( anObjShape ) {
337       anObjShape->setIsToUpdate( true );
338     }
339   }
340   
341   // Process the shape
342   if ( anObjShape ) {
343     // update if needed
344     if ( anObjShape->getIsToUpdate() || theIsForced ) {
345       anObjShape->update( false );
346     }
347
348     // Set visibility
349     bool anIsVisible = module()->isObjectVisible( aViewerId, theObject );
350     anObjShape->setVisible( anIsVisible, false );
351
352     aRes = true;
353   }
354
355   return aRes;
356 }
357
358 void HYDROGUI_OCCDisplayer::SetZLayer( const OCCViewer_Viewer* theViewer,
359                                        const Handle(HYDROData_Entity)& theObject, 
360                                        const int theZLayerId )
361 {
362   if ( !theViewer || ( theZLayerId < 0 ) ) {
363     return;
364   }
365   
366   // Get interactive context
367   Handle(AIS_InteractiveContext) aCtx = theViewer->getAISContext();
368   if( aCtx.IsNull() ) {
369     return;
370   }
371
372   // Get viewer id
373   size_t aViewerId = (size_t)theViewer;
374
375   // Get object shape 
376   HYDROGUI_Shape* anObjShape = module()->getObjectShape( aViewerId, theObject );
377
378   // Set Z layer
379   if ( anObjShape ) {
380     aCtx->SetZLayer( anObjShape->getAISShape(), theZLayerId );
381   }
382 }