0024837: Visualization - revise design and implementation of connected Interactive...
[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   // To be changed within dedicated patch
428   ///return Handle(PrsMgr_Presentation)();
429   return aPrsList.Last().Presentation();
430 }
431
432 // =======================================================================
433 // function : AddPresentation
434 // purpose  :
435 // =======================================================================
436 void PrsMgr_PresentationManager::AddPresentation (const Handle(PrsMgr_PresentableObject)& thePrsObj,
437                                                   const Standard_Integer                  theMode)
438 {
439   Handle(PrsMgr_Presentation) aPrs = new PrsMgr_Presentation (this, thePrsObj);
440   thePrsObj->Presentations().Append (PrsMgr_ModedPresentation (aPrs, theMode));
441   thePrsObj->Fill (this, aPrs, theMode);
442
443   // set layer index accordingly to object's presentations
444   const Standard_Integer aZLayerId = GetZLayer (thePrsObj);
445   if (aZLayerId >= 0)
446   {
447     aPrs->SetZLayer (aZLayerId);
448   }
449   aPrs->SetUpdateStatus (Standard_False);
450 }
451
452 // =======================================================================
453 // function : RemovePresentation
454 // purpose  :
455 // =======================================================================
456 void PrsMgr_PresentationManager::RemovePresentation (const Handle(PrsMgr_PresentableObject)& thePrsObj,
457                                                      const Standard_Integer                  theMode)
458 {
459   PrsMgr_Presentations& aPrsList = thePrsObj->Presentations();
460   for (Standard_Integer aPrsIter = 1; aPrsIter <= aPrsList.Length(); ++aPrsIter)
461   {
462     if (theMode == aPrsList (aPrsIter).Mode())
463     //  && this    == aPrsMgr) ??
464     {
465       aPrsList.Remove (aPrsIter);
466       break;
467     }
468   }
469 }
470
471 // =======================================================================
472 // function : SetZLayer
473 // purpose  :
474 // =======================================================================
475 void PrsMgr_PresentationManager::SetZLayer (const Handle(PrsMgr_PresentableObject)& thePrsObj,
476                                             const Standard_Integer                  theLayerId)
477 {
478   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
479   {
480     SetZLayer (anIter.Value(), theLayerId);
481   }
482   if (!thePrsObj->HasOwnPresentations())
483   {
484     return;
485   }
486   PrsMgr_Presentations& aPrsList = thePrsObj->Presentations();
487   for (Standard_Integer aPrsIter = 1; aPrsIter <= aPrsList.Length(); ++aPrsIter)
488   {
489     Handle(PrsMgr_Presentation) aPrs = aPrsList.ChangeValue (aPrsIter).Presentation();
490     if (aPrs->PresentationManager() == this)
491     {
492       aPrs->SetZLayer (theLayerId);
493     }
494   }
495 }
496
497 // =======================================================================
498 // function : GetZLayer
499 // purpose  :
500 // =======================================================================
501 Standard_Integer PrsMgr_PresentationManager::GetZLayer (const Handle(PrsMgr_PresentableObject)& thePrsObj) const
502 {
503   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
504   {
505     Standard_Integer aLayer = GetZLayer (anIter.Value());
506     if (aLayer != -1)
507     {
508       return aLayer;
509     }
510   }
511   if (!thePrsObj->HasOwnPresentations())
512   {
513     return -1;
514   }
515   const PrsMgr_Presentations& aPrsList = thePrsObj->Presentations();
516   for (Standard_Integer aPrsIter = 1; aPrsIter <= aPrsList.Length(); ++aPrsIter)
517   {
518     Handle(PrsMgr_Presentation) aPrs = aPrsList.Value (aPrsIter).Presentation();
519     if (aPrs->PresentationManager() == this)
520     {
521       return aPrs->GetZLayer();
522     }
523   }
524   return -1;
525 }
526
527 // =======================================================================
528 // function : Connect
529 // purpose  :
530 // =======================================================================
531 void PrsMgr_PresentationManager::Connect (const Handle(PrsMgr_PresentableObject)& thePrsObject,
532                                           const Handle(PrsMgr_PresentableObject)& theOtherObject,
533                                           const Standard_Integer                  theMode,
534                                           const Standard_Integer                  theOtherMode)
535 {
536   if (!HasPresentation (thePrsObject, theMode))
537   {
538     AddPresentation (thePrsObject, theMode);
539   }
540   if (!HasPresentation (theOtherObject, theOtherMode))
541   {
542     AddPresentation (theOtherObject, theOtherMode);
543   }
544   Presentation (thePrsObject, theMode)->Connect (Presentation (theOtherObject, theMode));
545 }
546
547 // =======================================================================
548 // function : Transform
549 // purpose  :
550 // =======================================================================
551 void PrsMgr_PresentationManager::Transform (const Handle(PrsMgr_PresentableObject)& thePrsObj,
552                                             const Handle(Geom_Transformation)&      theTransformation,
553                                             const Standard_Integer                  theMode)
554 {
555   Presentation (thePrsObj, theMode)->Transform (theTransformation);
556 }
557
558
559 // =======================================================================
560 // function : Color
561 // purpose  :
562 // =======================================================================
563 void PrsMgr_PresentationManager::Color (const Handle(PrsMgr_PresentableObject)& thePrsObj,
564                                         const Quantity_NameOfColor              theColor,
565                                         const Standard_Integer                  theMode)
566 {
567   for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
568   {
569     Color (anIter.Value(), theColor, theMode);
570   }
571   if (!thePrsObj->HasOwnPresentations())
572   {
573     return;
574   }
575
576   if (!HasPresentation (thePrsObj, theMode))
577   {
578     AddPresentation (thePrsObj, theMode);
579   }
580
581   if (!HasPresentation (thePrsObj, theMode)) return;
582
583   Handle(PrsMgr_Presentation) aPrs = Presentation (thePrsObj, theMode);
584   if (aPrs->MustBeUpdated())
585   {
586     Update (thePrsObj, theMode);
587   }
588
589   if (myImmediateModeOn > 0)
590   {
591     Handle(Prs3d_PresentationShadow) aShadow = new Prs3d_PresentationShadow (myStructureManager, aPrs->Presentation());
592     aShadow->Color (theColor);
593     AddToImmediateList (aShadow);
594   }
595   else
596   {
597     aPrs->Color (theColor);
598   }
599 }
600
601 // =======================================================================
602 // function : BoundBox
603 // purpose  :
604 // =======================================================================
605 void PrsMgr_PresentationManager::BoundBox (const Handle(PrsMgr_PresentableObject)& thePrsObject,
606                                            const Standard_Integer                  theMode)
607 {
608   if (!HasPresentation (thePrsObject, theMode))
609   {
610     AddPresentation (thePrsObject, theMode);
611   }
612   else if (Presentation (thePrsObject, theMode)->MustBeUpdated())
613   {
614     Update (thePrsObject, theMode);
615   }
616   Presentation (thePrsObject, theMode)->BoundBox();
617 }
618
619 // =======================================================================
620 // function : SetShadingAspect
621 // purpose  :
622 // =======================================================================
623 void PrsMgr_PresentationManager::SetShadingAspect (const Handle(PrsMgr_PresentableObject)& thePrsObject,
624                                                    const Quantity_NameOfColor              theColor,
625                                                    const Graphic3d_NameOfMaterial          theMaterial,
626                                                    const Standard_Integer                  theMode)
627 {
628   Handle(Prs3d_ShadingAspect) anAspect = new Prs3d_ShadingAspect();
629   anAspect->SetColor    (theColor);
630   anAspect->SetMaterial (theMaterial);
631   SetShadingAspect (thePrsObject, anAspect, theMode);
632 }
633
634 // =======================================================================
635 // function : SetShadingAspect
636 // purpose  :
637 // =======================================================================
638 void PrsMgr_PresentationManager::SetShadingAspect (const Handle(PrsMgr_PresentableObject)& thePrsObject,
639                                                    const Handle(Prs3d_ShadingAspect)&      theShadingAspect,
640                                                    const Standard_Integer                  theMode)
641 {
642   if (HasPresentation (thePrsObject, theMode))
643   {
644     Presentation (thePrsObject, theMode)->SetShadingAspect (theShadingAspect);
645   }
646 }