]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx
Salome HOME
another z layer for hilight presentation
[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::AddTopZLayer( OCCViewer_ViewManager* theMgr )
77 {
78   int aLayer = -1;
79   OCCViewer_Viewer* aViewer = theMgr->getOCCViewer();
80   if ( !aViewer )
81     return aLayer;
82
83   Standard_Integer aNewId = -1;
84   if ( aViewer->getViewer3d()->AddZLayer( aNewId ) )
85     aLayer = aNewId;
86
87   return aLayer;
88 }
89
90 void HYDROGUI_OCCDisplayer::RemoveZLayer( OCCViewer_ViewManager* theMgr,
91                                           const int theLayer )
92 {
93   if ( theLayer < 0 )
94     return;
95
96   OCCViewer_Viewer* aViewer = theMgr->getOCCViewer();
97   if ( !aViewer )
98     return;
99
100   // Get existing Z layers
101   TColStd_SequenceOfInteger anExistingZLayers;
102   aViewer->getViewer3d()->GetAllZLayers( anExistingZLayers );
103   int aNbLayers = anExistingZLayers.Length();
104   
105   if ( theLayer < aNbLayers )
106     aViewer->getViewer3d()->RemoveZLayer( theLayer );
107 }
108
109 void HYDROGUI_OCCDisplayer::EraseAll( const int theViewerId )
110 {
111   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
112   if( !aViewer )
113     return;
114
115   module()->removeViewShapes( (size_t)aViewer );
116 }
117
118 void HYDROGUI_OCCDisplayer::Erase( const HYDROData_SequenceOfObjects& theObjs,
119                                    const int                          theViewerId )
120 {
121   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
122   if( !aViewer )
123     return;
124
125   for ( int i = 1, n = theObjs.Length(); i <= n; i++ )
126   {
127     Handle(HYDROData_Entity) anObj = theObjs.Value( i );
128     if( anObj.IsNull() )
129       continue;
130
131     module()->removeObjectShape( (size_t)aViewer, anObj );
132   }
133   aViewer->update();
134 }
135
136 HYDROGUI_Shape* HYDROGUI_OCCDisplayer::createShape( const int                             theViewerId,
137                                                     const Handle(AIS_InteractiveContext)& theContext,
138                                                     const Handle(HYDROData_Entity)&       theObject )
139 {
140   HYDROGUI_Shape* aResShape = NULL;
141   if ( theContext.IsNull() || theObject.IsNull() )
142     return aResShape;
143
144   if ( !HYDROGUI_Tool::IsObjectHasPresentation( theObject, OCCViewer_Viewer::Type() ) )
145     return aResShape;
146
147   aResShape = new HYDROGUI_Shape( theContext, theObject );
148   module()->setObjectShape( theViewerId, theObject, aResShape );
149
150   return aResShape;
151 }
152
153 void HYDROGUI_OCCDisplayer::Display( const HYDROData_SequenceOfObjects& theObjs,
154                                      const int                          theViewerId,
155                                      const bool                         theIsForced,
156                                      const bool theDoFitAll )
157 {
158   // Get OCC viewer by id
159   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
160   if( !aViewer )
161     return;
162
163   // Get interactive context
164   Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
165   if( aCtx.IsNull() )
166     return;
167
168   // Get the document
169   Handle(HYDROData_Document) aDoc = HYDROData_Document::Document( module()->getStudyId() );
170   if ( !aDoc )
171     return;
172   
173   // Assign Z layer indexes to the objects
174   aDoc->Show( theObjs );
175
176   // Sort objects by display order ( needed for Z layers assignment only )
177   HYDROData_SequenceOfObjects anUnorderedToDisplay = theObjs;
178   HYDROData_SequenceOfObjects anOrderedToDisplay;
179   HYDROData_SequenceOfObjects anAllOrderedObjects = aDoc->GetObjectsLayerOrder();
180
181   HYDROData_SequenceOfObjects::Iterator anAllOrderedIter( anAllOrderedObjects );
182   for ( ; anAllOrderedIter.More(); anAllOrderedIter.Next() ) {
183     QString anOrderedEntry = 
184       HYDROGUI_DataObject::dataObjectEntry( anAllOrderedIter.Value() );
185     
186     HYDROData_SequenceOfObjects::Iterator aToDisplayIter( anUnorderedToDisplay );
187     for ( ; aToDisplayIter.More(); aToDisplayIter.Next() ) {
188       Handle(HYDROData_Entity) anObjToDisplay = aToDisplayIter.Value();
189       QString anEntry = HYDROGUI_DataObject::dataObjectEntry( anObjToDisplay );
190       if ( anEntry == anOrderedEntry ) {
191         anOrderedToDisplay.Prepend( anObjToDisplay );
192         anUnorderedToDisplay.Remove( aToDisplayIter );
193         break;
194       }
195     }
196   }
197   
198   // Get 3d viewer
199   Handle(V3d_Viewer) aViewer3d = aViewer->getViewer3d();
200
201   // Get existing Z layers
202   TColStd_SequenceOfInteger anExistingZLayers;
203   aViewer3d->GetAllZLayers( anExistingZLayers );
204   int aNbLayers = anExistingZLayers.Length();
205
206   // Display objects
207   int aNextZLayerIndex = 2; // don't use the first default Z layer ( which index = 1 )
208
209   // 1. Display the ordered objects:
210   HYDROData_SequenceOfObjects::Iterator anOrderedIter( anOrderedToDisplay );
211   for ( ; anOrderedIter.More(); anOrderedIter.Next() ) {
212     Handle(HYDROData_Entity) anObj = anOrderedIter.Value();
213     if ( Display( anObj, aViewer, theIsForced, aNextZLayerIndex, true ) ) {
214       aNextZLayerIndex++;
215     }
216   }
217
218   // 2. Display the unordered objects:
219   bool isDisplayed = false;
220   HYDROData_SequenceOfObjects::Iterator anUnorderedIter( anUnorderedToDisplay );
221   for ( ; anUnorderedIter.More(); anUnorderedIter.Next() ) {
222     Handle(HYDROData_Entity) anObj = anUnorderedIter.Value();
223     if ( Display( anObj, aViewer, theIsForced, aNextZLayerIndex, false ) ) {
224       isDisplayed = true;
225     }
226   }
227   
228   // 3. Update the top Z layer index
229   if ( isDisplayed ) {
230     aNextZLayerIndex++;
231   }
232
233   // Update Z layer of the active operation
234   aViewer3d->GetAllZLayers( anExistingZLayers );
235
236   HYDROGUI_Module* aModule = module();
237   SUIT_Operation* anOp = aModule->activeOperation();
238   HYDROGUI_Operation* aHOp = anOp ? dynamic_cast<HYDROGUI_Operation*>( anOp ) : 0;
239   if ( aHOp && aHOp->getPreviewZLayer() >= 0 ) {
240     Standard_Integer aLayerId = -1;
241     if ( aNextZLayerIndex <= aNbLayers )
242       aLayerId = anExistingZLayers.Value( aNextZLayerIndex );
243     else {
244       Standard_Integer aNewId = -1;
245       if ( aViewer->getViewer3d()->AddZLayer( aNewId ) ) {
246         aLayerId = aNewId;
247       }
248     }
249     aHOp->updatePreviewZLayer( aLayerId );
250   }
251
252   HYDROGUI_ZLayersIterator anIt( aViewer->getViewer3d() );
253   int aMaxLayer = anIt.MaxLayer();
254   UpdateZLayersOfHilightPresentationsOfDisplayedObjects( aCtx, aMaxLayer );
255
256   if ( theDoFitAll )
257   {
258     OCCViewer_ViewManager* aViewManager
259       = ::qobject_cast<OCCViewer_ViewManager*>( aViewer->getViewManager() );
260     if ( aViewManager )
261     {
262       OCCViewer_ViewWindow* aViewWindow = 
263         ::qobject_cast<OCCViewer_ViewWindow*>( aViewManager->getActiveView() );
264       if ( aViewWindow )
265       {
266         aViewWindow->onFitAll();
267       }
268     }
269   }
270   else if ( !aCtx.IsNull() ) // TODO: determine if this code is necessary (added as a fix for issue# 359)
271   {
272     aCtx->UpdateSelected();
273   }
274 }
275
276 void HYDROGUI_OCCDisplayer::purgeObjects( const int theViewerId )
277 {
278   OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId );
279   if( !aViewer )
280     return;
281
282   Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext();
283   if( aCtx.IsNull() )
284     return;
285
286   AIS_ListOfInteractive aDisplayedObjects;
287   aCtx->DisplayedObjects( aDisplayedObjects );
288
289   AIS_ListIteratorOfListOfInteractive aListIter( aDisplayedObjects );
290   for ( ; aListIter.More(); aListIter.Next() )
291   {
292     Handle(AIS_InteractiveObject) aPrsObj = aListIter.Value();
293     if ( aPrsObj.IsNull() )
294       continue;
295
296     Handle(HYDROData_Entity) anOwnerObj = 
297       Handle(HYDROData_Entity)::DownCast( aPrsObj->GetOwner() );
298     if ( !anOwnerObj.IsNull() && anOwnerObj->IsRemoved() )
299       module()->removeObjectShape( (size_t)aViewer, anOwnerObj );
300   }
301 }
302
303 QString HYDROGUI_OCCDisplayer::GetType() const
304 {
305   return OCCViewer_Viewer::Type();
306 }
307
308 bool HYDROGUI_OCCDisplayer::Display( const Handle(HYDROData_Entity)& theObject,
309                                      const OCCViewer_Viewer* theViewer,
310                                      const bool theIsForced,
311                                      const int theZLayerIndex,
312                                      const bool theIsOrdered )
313 {
314   bool aRes = false;
315
316   if ( theObject.IsNull() || theObject->IsRemoved() || !theViewer ) {
317     return aRes;
318   }
319
320   // Get interactive context
321   Handle(AIS_InteractiveContext) aCtx = theViewer->getAISContext();
322   if( aCtx.IsNull() ) {
323     return aRes;
324   }
325
326   // Viewer id
327   size_t aViewerId = (size_t)theViewer;
328
329   // Object shape 
330   HYDROGUI_Shape* anObjShape = module()->getObjectShape( aViewerId, theObject );
331   // create if needed
332   if ( !anObjShape ) {
333     anObjShape = createShape( aViewerId, aCtx, theObject );
334     if ( anObjShape ) {
335       anObjShape->setIsToUpdate( true );
336     }
337   }
338   
339   // Process the shape
340   if ( anObjShape ) {
341     // update if needed
342     if ( anObjShape->getIsToUpdate() || theIsForced ) {
343       anObjShape->update( false );
344     }
345
346     // Set visibility
347     bool anIsVisible = module()->isObjectVisible( aViewerId, theObject );
348     anObjShape->setVisible( anIsVisible, false );
349
350     // Set Z layer
351     Handle(V3d_Viewer) aViewer3d = theViewer->getViewer3d();
352     if ( !aViewer3d.IsNull() ) {
353       // Get existing layers
354       TColStd_SequenceOfInteger anExistingZLayers;
355       aViewer3d->GetAllZLayers( anExistingZLayers );
356       int aNbLayers = anExistingZLayers.Length();
357       
358       // Get or create the appropriate layer
359       Standard_Integer aLayerId = -1;
360       if ( theZLayerIndex <= aNbLayers ) {
361         aLayerId = anExistingZLayers.Value( theZLayerIndex );
362       } else {
363         Standard_Integer aNewId = -1;
364         if ( aViewer3d->AddZLayer( aNewId ) ) {
365           aLayerId = aNewId;
366         }
367       }
368
369       if ( aLayerId >= 0 ) {
370         // set Z layer
371         aCtx->SetZLayer( anObjShape->getAISShape(), aLayerId );
372           
373         // set Z layer settings for the 3d viewer:
374         // current settings
375         Graphic3d_ZLayerSettings aSettings = aViewer3d->ZLayerSettings( aLayerId );
376         // enable depth write
377         aSettings.EnableSetting( Graphic3d_ZLayerDepthWrite );
378         // disable depth clear
379         aSettings.DisableSetting( Graphic3d_ZLayerDepthClear );
380         if ( theIsOrdered ) {
381           // disable depth test
382           aSettings.DisableSetting( Graphic3d_ZLayerDepthTest );
383           // disable depth offset
384           aSettings.DisableSetting( Graphic3d_ZLayerDepthOffset );
385         } else {
386           // enable depth test
387           aSettings.EnableSetting( Graphic3d_ZLayerDepthTest );
388           // set depth offset
389           aSettings.SetDepthOffsetPositive();
390         }
391
392         // set new settings
393         aViewer3d->SetZLayerSettings( aLayerId, aSettings );
394
395         aRes = true;
396       }
397     }
398   }
399
400   return aRes;
401 }