0025204: Visualization, PrsMgr_PresentationManager::Presentation() - do not return...
[occt.git] / src / PrsMgr / PrsMgr_PresentationManager.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <PrsMgr_PresentationManager.ixx>
16
17 #include <Graphic3d_GraphicDriver.hxx>
18 #include <Prs3d_PresentationShadow.hxx>
19 #include <PrsMgr_PresentableObject.hxx>
20 #include <PrsMgr_Presentation.hxx>
21 #include <PrsMgr_Presentations.hxx>
22 #include <PrsMgr_ModedPresentation.hxx>
23 #include <TColStd_ListIteratorOfListOfTransient.hxx>
24 #include <V3d_View.hxx>
25 #include <Visual3d_View.hxx>
26 #include <Visual3d_Layer.hxx>
27
28 // =======================================================================
29 // function : PrsMgr_PresentationManager
30 // purpose  :
31 // =======================================================================
32 PrsMgr_PresentationManager::PrsMgr_PresentationManager (const Handle(Graphic3d_StructureManager)& theStructureManager)
33 : myStructureManager (theStructureManager),
34   myImmediateModeOn  (0)
35 {
36   //
37 }
38
39 // =======================================================================
40 // function : Display
41 // purpose  :
42 // =======================================================================
43 void PrsMgr_PresentationManager::Display (const Handle(PrsMgr_PresentableObject)& thePrsObj,
44                                           const Standard_Integer                  theMode)
45 {
46   if (thePrsObj->HasOwnPresentations())
47   {
48     if (!HasPresentation (thePrsObj, theMode))
49     {
50       AddPresentation (thePrsObj, theMode);
51     }
52
53     Handle(PrsMgr_Presentation) aPrs = Presentation (thePrsObj, theMode);
54
55     if (aPrs.IsNull()) return;
56
57     if (aPrs->MustBeUpdated())
58     {
59       Update (thePrsObj, theMode);
60     }
61
62     if (myImmediateModeOn > 0)
63     {
64       AddToImmediateList (aPrs->Presentation());
65     }
66     else
67     {
68       aPrs->Display();
69     }
70   }
71   else
72   {
73     thePrsObj->Compute (this, Handle(Prs3d_Presentation)(), theMode);
74   }
75
76   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
77   {
78     Display (anIter.Value(), theMode);
79   }
80 }
81
82 // =======================================================================
83 // function : Erase
84 // purpose  :
85 // =======================================================================
86 void PrsMgr_PresentationManager::Erase (const Handle(PrsMgr_PresentableObject)& thePrsObj,
87                                         const Standard_Integer                  theMode)
88 {
89   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
90   {
91     Erase (anIter.Value(), theMode);
92   }
93
94   if (HasPresentation (thePrsObj, theMode))
95   {
96     Presentation (thePrsObj, theMode)->Erase();
97     RemovePresentation (thePrsObj, theMode);
98   }
99 }
100
101 // =======================================================================
102 // function : Clear
103 // purpose  :
104 // =======================================================================
105 void PrsMgr_PresentationManager::Clear (const Handle(PrsMgr_PresentableObject)& thePrsObj,
106                                         const Standard_Integer                  theMode)
107 {
108   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
109   {
110     Clear (anIter.Value(), theMode);
111   }
112
113   if (HasPresentation (thePrsObj, theMode))
114   {
115     Presentation (thePrsObj, theMode)->Clear();
116   }
117 }
118
119 // =======================================================================
120 // function : SetVisibility
121 // purpose  :
122 // =======================================================================
123 void PrsMgr_PresentationManager::SetVisibility (const Handle(PrsMgr_PresentableObject)& thePrsObj,
124                                                 const Standard_Integer theMode,
125                                                 const Standard_Boolean theValue)
126 {
127   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
128   {
129     SetVisibility (anIter.Value(), theMode, theValue);
130   }
131   if (!thePrsObj->HasOwnPresentations())
132   {
133     return;
134   }
135
136   Presentation (thePrsObj, theMode)->SetVisible (theValue);
137 }
138
139 // =======================================================================
140 // function : Highlight
141 // purpose  :
142 // =======================================================================
143 void PrsMgr_PresentationManager::Highlight (const Handle(PrsMgr_PresentableObject)& thePrsObj,
144                                             const Standard_Integer                  theMode)
145 {
146   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
147   {
148     Highlight (anIter.Value(), theMode);
149   }
150   if (!thePrsObj->HasOwnPresentations())
151   {
152     return;
153   }
154
155   if (!HasPresentation (thePrsObj, theMode))
156   {
157     AddPresentation (thePrsObj, theMode);
158   }
159
160   if (!HasPresentation (thePrsObj, theMode)) return;
161
162   Handle(PrsMgr_Presentation) aPrs = Presentation (thePrsObj, theMode);
163   if (aPrs->MustBeUpdated())
164   {
165     Update (thePrsObj, theMode);
166   }
167
168   if (myImmediateModeOn > 0)
169   {
170     Handle(Prs3d_PresentationShadow) aShadow = new Prs3d_PresentationShadow (myStructureManager, aPrs->Presentation());
171     aShadow->Highlight();
172     AddToImmediateList (aShadow);
173   }
174   else
175   {
176     aPrs->Highlight();
177   }
178 }
179
180 // =======================================================================
181 // function : Unhighlight
182 // purpose  :
183 // =======================================================================
184 void PrsMgr_PresentationManager::Unhighlight (const Handle(PrsMgr_PresentableObject)& thePrsObj,
185                                               const Standard_Integer                  theMode)
186 {
187   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
188   {
189     Unhighlight (anIter.Value(), theMode);
190   }
191
192   if (HasPresentation (thePrsObj, theMode))
193   {
194     Presentation (thePrsObj, theMode)->Unhighlight();
195   }
196 }
197
198 // =======================================================================
199 // function : SetDisplayPriority
200 // purpose  :
201 // =======================================================================
202 void PrsMgr_PresentationManager::SetDisplayPriority (const Handle(PrsMgr_PresentableObject)& thePrsObj,
203                                                      const Standard_Integer                  theMode,
204                                                      const Standard_Integer                  theNewPrior) const
205 {
206   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
207   {
208     SetDisplayPriority (anIter.Value(), theMode, theNewPrior);
209   }
210
211   if (HasPresentation (thePrsObj, theMode))
212   {
213     Presentation (thePrsObj, theMode)->SetDisplayPriority (theNewPrior);
214   }
215 }
216
217 // =======================================================================
218 // function : DisplayPriority
219 // purpose  :
220 // =======================================================================
221 Standard_Integer PrsMgr_PresentationManager::DisplayPriority (const Handle(PrsMgr_PresentableObject)& thePrsObj,
222                                                               const Standard_Integer                  theMode) const
223 {
224   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
225   {
226     Standard_Integer aPriority = DisplayPriority (anIter.Value(), theMode);
227     if (aPriority != 0)
228     {
229       return aPriority;
230     }
231   }
232
233   return HasPresentation (thePrsObj, theMode)
234        ? Presentation (thePrsObj, theMode)->DisplayPriority()
235        : 0;
236 }
237
238 // =======================================================================
239 // function : IsDisplayed
240 // purpose  :
241 // =======================================================================
242 Standard_Boolean PrsMgr_PresentationManager::IsDisplayed (const Handle(PrsMgr_PresentableObject)& thePrsObj,
243                                                           const Standard_Integer                  theMode) const
244 {
245   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
246   {
247     if (IsDisplayed (anIter.Value(), theMode))
248     {
249       return Standard_True;
250     }
251   }
252
253   return HasPresentation (thePrsObj, theMode)
254       && Presentation    (thePrsObj, theMode)->IsDisplayed();
255 }
256
257 // =======================================================================
258 // function : IsHighlighted
259 // purpose  :
260 // =======================================================================
261 Standard_Boolean PrsMgr_PresentationManager::IsHighlighted (const Handle(PrsMgr_PresentableObject)& thePrsObj,
262                                                             const Standard_Integer                  theMode) const
263 {
264   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
265   {
266     if (IsHighlighted (anIter.Value(), theMode))
267     {
268       return Standard_True;
269     }
270   }
271
272   return HasPresentation (thePrsObj, theMode)
273       && Presentation    (thePrsObj, theMode)->IsHighlighted();
274 }
275
276 // =======================================================================
277 // function : Update
278 // purpose  :
279 // =======================================================================
280 void PrsMgr_PresentationManager::Update (const Handle(PrsMgr_PresentableObject)& thePrsObj,
281                                          const Standard_Integer                  theMode) const
282 {
283   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
284   {
285     Update (anIter.Value(), theMode);
286   }
287   if (!HasPresentation(thePrsObj, theMode))
288   {
289     return;
290   }
291
292   Handle(PrsMgr_Presentation) aPrs = Presentation (thePrsObj, theMode);
293   if (!aPrs.IsNull())
294   {
295     aPrs->Clear();
296     thePrsObj->Fill (this, aPrs, theMode);
297     aPrs->SetUpdateStatus (Standard_False);
298   }
299 }
300
301 // =======================================================================
302 // function : BeginImmediateDraw
303 // purpose  :
304 // =======================================================================
305 void PrsMgr_PresentationManager::BeginImmediateDraw()
306 {
307   if (++myImmediateModeOn > 1)
308   {
309     return;
310   }
311
312   ClearImmediateDraw();
313 }
314
315 // =======================================================================
316 // function : ClearImmediateDraw
317 // purpose  :
318 // =======================================================================
319 void PrsMgr_PresentationManager::ClearImmediateDraw()
320 {
321   if (myImmediateView.IsNull())
322   {
323     myImmediateList.Clear();
324     return;
325   }
326
327   for (PrsMgr_ListOfPresentations::Iterator anIter (myImmediateList); anIter.More(); anIter.Next())
328   {
329     myImmediateView->View()->EraseImmediate (anIter.Value());
330   }
331
332   myImmediateList.Clear();
333   myImmediateView.Nullify();
334 }
335
336 // =======================================================================
337 // function : EndImmediateDraw
338 // purpose  :
339 // =======================================================================
340 void PrsMgr_PresentationManager::EndImmediateDraw (const Handle(V3d_View)& theView)
341 {
342   if (--myImmediateModeOn > 0)
343   {
344     return;
345   }
346
347   for (PrsMgr_ListOfPresentations::Iterator anIter (myImmediateList); anIter.More(); anIter.Next())
348   {
349     theView->View()->DisplayImmediate (anIter.Value(), Standard_True);
350   }
351   if (!myImmediateList.IsEmpty())
352   {
353     myImmediateView = theView;
354   }
355 }
356
357 // =======================================================================
358 // function : AddToImmediateList
359 // purpose  :
360 //=======================================================================
361 void PrsMgr_PresentationManager::AddToImmediateList (const Handle(Prs3d_Presentation)& thePrs)
362 {
363   if (myImmediateModeOn < 1)
364   {
365     return;
366   }
367
368   for (PrsMgr_ListOfPresentations::Iterator anIter (myImmediateList); anIter.More(); anIter.Next())
369   {
370     if (anIter.Value() == thePrs)
371     {
372       return;
373     }
374   }
375
376   myImmediateList.Append (thePrs);
377 }
378
379 // =======================================================================
380 // function : HasPresentation
381 // purpose  :
382 // =======================================================================
383 Standard_Boolean PrsMgr_PresentationManager::HasPresentation (const Handle(PrsMgr_PresentableObject)& thePrsObj,
384                                                               const Standard_Integer                  theMode) const
385 {
386   if (!thePrsObj->HasOwnPresentations())
387     return Standard_False;
388
389   const PrsMgr_Presentations& aPrsList = thePrsObj->Presentations();
390   for (Standard_Integer aPrsIter = 1; aPrsIter <= aPrsList.Length(); ++aPrsIter)
391   {
392     const PrsMgr_ModedPresentation&           aModedPrs = aPrsList.Value (aPrsIter);
393     const Handle(PrsMgr_PresentationManager)& aPrsMgr   = aModedPrs.Presentation()->PresentationManager();
394     if (theMode == aModedPrs.Mode()
395      && this    == aPrsMgr)
396     {
397       return Standard_True;
398     }
399   }
400   return Standard_False;
401 }
402
403 // =======================================================================
404 // function : Presentation
405 // purpose  :
406 // =======================================================================
407 Handle(PrsMgr_Presentation) PrsMgr_PresentationManager::Presentation (const Handle(PrsMgr_PresentableObject)& thePrsObj,
408                                                                       const Standard_Integer                  theMode) const
409 {
410   const PrsMgr_Presentations& aPrsList = thePrsObj->Presentations();
411   if (aPrsList.IsEmpty())
412   {
413     return Handle(PrsMgr_Presentation)();
414   }
415
416   for (Standard_Integer aPrsIter = 1; aPrsIter <= aPrsList.Length(); ++aPrsIter)
417   {
418     const PrsMgr_ModedPresentation&           aModedPrs = aPrsList.Value (aPrsIter);
419     const Handle(PrsMgr_PresentationManager)& aPrsMgr   = aModedPrs.Presentation()->PresentationManager();
420     if (theMode == aModedPrs.Mode()
421      && this    == aPrsMgr)
422     {
423       return aModedPrs.Presentation();
424     }
425   }
426
427   return Handle(PrsMgr_Presentation)();
428 }
429
430 // =======================================================================
431 // function : AddPresentation
432 // purpose  :
433 // =======================================================================
434 void PrsMgr_PresentationManager::AddPresentation (const Handle(PrsMgr_PresentableObject)& thePrsObj,
435                                                   const Standard_Integer                  theMode)
436 {
437   Handle(PrsMgr_Presentation) aPrs = new PrsMgr_Presentation (this, thePrsObj);
438   thePrsObj->Presentations().Append (PrsMgr_ModedPresentation (aPrs, theMode));
439   thePrsObj->Fill (this, aPrs, theMode);
440
441   // set layer index accordingly to object's presentations
442   const Standard_Integer aZLayerId = GetZLayer (thePrsObj);
443   if (aZLayerId >= 0)
444   {
445     aPrs->SetZLayer (aZLayerId);
446   }
447   aPrs->SetUpdateStatus (Standard_False);
448 }
449
450 // =======================================================================
451 // function : RemovePresentation
452 // purpose  :
453 // =======================================================================
454 void PrsMgr_PresentationManager::RemovePresentation (const Handle(PrsMgr_PresentableObject)& thePrsObj,
455                                                      const Standard_Integer                  theMode)
456 {
457   PrsMgr_Presentations& aPrsList = thePrsObj->Presentations();
458   for (Standard_Integer aPrsIter = 1; aPrsIter <= aPrsList.Length(); ++aPrsIter)
459   {
460     if (theMode == aPrsList (aPrsIter).Mode())
461     //  && this    == aPrsMgr) ??
462     {
463       aPrsList.Remove (aPrsIter);
464       break;
465     }
466   }
467 }
468
469 // =======================================================================
470 // function : SetZLayer
471 // purpose  :
472 // =======================================================================
473 void PrsMgr_PresentationManager::SetZLayer (const Handle(PrsMgr_PresentableObject)& thePrsObj,
474                                             const Standard_Integer                  theLayerId)
475 {
476   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
477   {
478     SetZLayer (anIter.Value(), theLayerId);
479   }
480   if (!thePrsObj->HasOwnPresentations())
481   {
482     return;
483   }
484   PrsMgr_Presentations& aPrsList = thePrsObj->Presentations();
485   for (Standard_Integer aPrsIter = 1; aPrsIter <= aPrsList.Length(); ++aPrsIter)
486   {
487     Handle(PrsMgr_Presentation) aPrs = aPrsList.ChangeValue (aPrsIter).Presentation();
488     if (aPrs->PresentationManager() == this)
489     {
490       aPrs->SetZLayer (theLayerId);
491     }
492   }
493 }
494
495 // =======================================================================
496 // function : GetZLayer
497 // purpose  :
498 // =======================================================================
499 Standard_Integer PrsMgr_PresentationManager::GetZLayer (const Handle(PrsMgr_PresentableObject)& thePrsObj) const
500 {
501   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
502   {
503     Standard_Integer aLayer = GetZLayer (anIter.Value());
504     if (aLayer != -1)
505     {
506       return aLayer;
507     }
508   }
509   if (!thePrsObj->HasOwnPresentations())
510   {
511     return -1;
512   }
513   const PrsMgr_Presentations& aPrsList = thePrsObj->Presentations();
514   for (Standard_Integer aPrsIter = 1; aPrsIter <= aPrsList.Length(); ++aPrsIter)
515   {
516     Handle(PrsMgr_Presentation) aPrs = aPrsList.Value (aPrsIter).Presentation();
517     if (aPrs->PresentationManager() == this)
518     {
519       return aPrs->GetZLayer();
520     }
521   }
522   return -1;
523 }
524
525 // =======================================================================
526 // function : Connect
527 // purpose  :
528 // =======================================================================
529 void PrsMgr_PresentationManager::Connect (const Handle(PrsMgr_PresentableObject)& thePrsObject,
530                                           const Handle(PrsMgr_PresentableObject)& theOtherObject,
531                                           const Standard_Integer                  theMode,
532                                           const Standard_Integer                  theOtherMode)
533 {
534   if (!HasPresentation (thePrsObject, theMode))
535   {
536     AddPresentation (thePrsObject, theMode);
537   }
538   if (!HasPresentation (theOtherObject, theOtherMode))
539   {
540     AddPresentation (theOtherObject, theOtherMode);
541   }
542   Presentation (thePrsObject, theMode)->Connect (Presentation (theOtherObject, theMode));
543 }
544
545 // =======================================================================
546 // function : Transform
547 // purpose  :
548 // =======================================================================
549 void PrsMgr_PresentationManager::Transform (const Handle(PrsMgr_PresentableObject)& thePrsObj,
550                                             const Handle(Geom_Transformation)&      theTransformation,
551                                             const Standard_Integer                  theMode)
552 {
553   Presentation (thePrsObj, theMode)->Transform (theTransformation);
554 }
555
556
557 // =======================================================================
558 // function : Color
559 // purpose  :
560 // =======================================================================
561 void PrsMgr_PresentationManager::Color (const Handle(PrsMgr_PresentableObject)& thePrsObj,
562                                         const Quantity_NameOfColor              theColor,
563                                         const Standard_Integer                  theMode)
564 {
565   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
566   {
567     Color (anIter.Value(), theColor, theMode);
568   }
569   if (!thePrsObj->HasOwnPresentations())
570   {
571     return;
572   }
573
574   if (!HasPresentation (thePrsObj, theMode))
575   {
576     AddPresentation (thePrsObj, theMode);
577   }
578
579   if (!HasPresentation (thePrsObj, theMode)) return;
580
581   Handle(PrsMgr_Presentation) aPrs = Presentation (thePrsObj, theMode);
582   if (aPrs->MustBeUpdated())
583   {
584     Update (thePrsObj, theMode);
585   }
586
587   if (myImmediateModeOn > 0)
588   {
589     Handle(Prs3d_PresentationShadow) aShadow = new Prs3d_PresentationShadow (myStructureManager, aPrs->Presentation());
590     aShadow->Color (theColor);
591     AddToImmediateList (aShadow);
592   }
593   else
594   {
595     aPrs->Color (theColor);
596   }
597 }
598
599 // =======================================================================
600 // function : BoundBox
601 // purpose  :
602 // =======================================================================
603 void PrsMgr_PresentationManager::BoundBox (const Handle(PrsMgr_PresentableObject)& thePrsObject,
604                                            const Standard_Integer                  theMode)
605 {
606   if (!HasPresentation (thePrsObject, theMode))
607   {
608     AddPresentation (thePrsObject, theMode);
609   }
610   else if (Presentation (thePrsObject, theMode)->MustBeUpdated())
611   {
612     Update (thePrsObject, theMode);
613   }
614   Presentation (thePrsObject, theMode)->BoundBox();
615 }
616
617 // =======================================================================
618 // function : SetShadingAspect
619 // purpose  :
620 // =======================================================================
621 void PrsMgr_PresentationManager::SetShadingAspect (const Handle(PrsMgr_PresentableObject)& thePrsObject,
622                                                    const Quantity_NameOfColor              theColor,
623                                                    const Graphic3d_NameOfMaterial          theMaterial,
624                                                    const Standard_Integer                  theMode)
625 {
626   Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
627   anAspect->SetColor    (theColor);
628   anAspect->SetMaterial (theMaterial);
629   SetShadingAspect (thePrsObject, anAspect, theMode);
630 }
631
632 // =======================================================================
633 // function : SetShadingAspect
634 // purpose  :
635 // =======================================================================
636 void PrsMgr_PresentationManager::SetShadingAspect (const Handle(PrsMgr_PresentableObject)& thePrsObject,
637                                                    const Handle(Prs3d_ShadingAspect)&      theShadingAspect,
638                                                    const Standard_Integer                  theMode)
639 {
640   if (HasPresentation (thePrsObject, theMode))
641   {
642     Presentation (thePrsObject, theMode)->SetShadingAspect (theShadingAspect);
643   }
644 }