062072ad2dd3978b966e2609785c12238c5f37c8
[occt.git] / src / Graphic3d / Graphic3d_CView.cxx
1 // Copyright (c) 2015 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <Graphic3d_CView.hxx>
15 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
16 #include <Graphic3d_StructureManager.hxx>
17
18 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CView,Graphic3d_DataStructureManager)
19
20 namespace
21 {
22   static const int THE_DEFAULT_LAYERS[] = { Graphic3d_ZLayerId_Top,
23                                             Graphic3d_ZLayerId_Topmost,
24                                             Graphic3d_ZLayerId_BotOSD,
25                                             Graphic3d_ZLayerId_TopOSD };
26
27   static const int THE_NB_DEFAULT_LAYERS = sizeof(THE_DEFAULT_LAYERS) / sizeof(*THE_DEFAULT_LAYERS);
28
29   void combineBox (Bnd_Box& aCombined, const Graphic3d_BndBox4f& theBox)
30   {
31     if (theBox.IsValid())
32     {
33       aCombined.Add (gp_Pnt (theBox.CornerMin().x(),
34                              theBox.CornerMin().y(),
35                              theBox.CornerMin().z()));
36       aCombined.Add (gp_Pnt (theBox.CornerMax().x(),
37                              theBox.CornerMax().y(),
38                              theBox.CornerMax().z()));
39     }
40   }
41 }
42
43 //=======================================================================
44 //function : Constructor
45 //purpose  :
46 //=======================================================================
47 Graphic3d_CView::Graphic3d_CView (const Handle(Graphic3d_StructureManager)& theMgr)
48 : myStructureManager       (theMgr),
49   myHiddenObjects          (new Graphic3d_NMapOfTransient()),
50   myIsInComputedMode       (Standard_False),
51   myIsActive               (Standard_False),
52   myIsRemoved              (Standard_False),
53   myVisualization          (Graphic3d_TOV_WIREFRAME)
54 {
55   myId = myStructureManager->Identification (this);
56 }
57
58 //=======================================================================
59 //function : Destructor
60 //purpose  :
61 //=======================================================================
62 Graphic3d_CView::~Graphic3d_CView()
63 {
64   if (!IsRemoved())
65   {
66     myStructureManager->UnIdentification (this);
67   }
68 }
69
70 // =======================================================================
71 // function : Activate
72 // purpose  :
73 // =======================================================================
74 void Graphic3d_CView::Activate()
75 {
76   if (!IsActive())
77   {
78     myIsActive = Standard_True;
79
80     // Activation of a new view =>
81     // Display structures that can be displayed in this new view.
82     // All structures with status
83     // Displayed in ViewManager are returned and displayed in
84     // the view directly, if the structure is not already
85     // displayed and if the view accepts it in its context.
86     Graphic3d_MapOfStructure aDisplayedStructs;
87     myStructureManager->DisplayedStructures (aDisplayedStructs);
88     for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aDisplayedStructs); aStructIter.More(); aStructIter.Next())
89     {
90       const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
91       if (IsDisplayed (aStruct))
92       {
93         continue;
94       }
95
96       // If the structure can be displayed in the new context of the view, it is displayed.
97       const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
98       if (anAnswer == Graphic3d_TOA_YES
99        || anAnswer == Graphic3d_TOA_COMPUTE)
100       {
101         Display (aStruct, Aspect_TOU_WAIT);
102       }
103     }
104   }
105
106   Update (myStructureManager->UpdateMode());
107 }
108
109 // =======================================================================
110 // function : Deactivate
111 // purpose  :
112 // =======================================================================
113 void Graphic3d_CView::Deactivate()
114 {
115   if (IsActive())
116   {
117     // Deactivation of a view =>
118     // Removal of structures displayed in this view.
119     // All structures with status
120     // Displayed in ViewManager are returned and removed from
121     // the view directly, if the structure is not already
122     // displayed and if the view accepts it in its context.
123     Graphic3d_MapOfStructure aDisplayedStructs;
124     myStructureManager->DisplayedStructures (aDisplayedStructs);
125     for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aDisplayedStructs); aStructIter.More(); aStructIter.Next())
126     {
127       const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
128       if (!IsDisplayed (aStruct))
129       {
130         continue;
131       }
132
133       const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
134       if (anAnswer == Graphic3d_TOA_YES
135        || anAnswer == Graphic3d_TOA_COMPUTE)
136       {
137         Erase (aStruct, Aspect_TOU_WAIT);
138       }
139     }
140
141     Update (myStructureManager->UpdateMode());
142     myIsActive = Standard_False;
143   }
144 }
145
146 // ========================================================================
147 // function : Remove
148 // purpose  :
149 // ========================================================================
150 void Graphic3d_CView::Remove()
151 {
152   if (IsRemoved())
153   {
154     return;
155   }
156
157   Graphic3d_MapOfStructure aDisplayedStructs (myStructsDisplayed);
158
159   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aDisplayedStructs); aStructIter.More(); aStructIter.Next())
160   {
161     Erase (aStructIter.Value(), Aspect_TOU_WAIT);
162   }
163
164   myStructsToCompute.Clear();
165   myStructsComputed .Clear();
166   myStructsDisplayed.Clear();
167
168   if (!myStructureManager.IsNull())
169   {
170     myStructureManager->UnIdentification (this);
171   }
172
173   myIsActive  = Standard_False;
174   myIsRemoved = Standard_True;
175 }
176
177 // ========================================================================
178 // function : SetComputedMode
179 // purpose  :
180 // ========================================================================
181 void Graphic3d_CView::SetComputedMode (const Standard_Boolean theMode)
182 {
183   if (( theMode &&  myIsInComputedMode)
184    || (!theMode && !myIsInComputedMode))
185   {
186     return;
187   }
188
189   myIsInComputedMode = theMode;
190   if (!myIsInComputedMode)
191   {
192     for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
193     {
194       const Handle(Graphic3d_Structure)& aStruct  = aStructIter.Key();
195       const Graphic3d_TypeOfAnswer        anAnswer = acceptDisplay (aStruct->Visual());
196       if (anAnswer != Graphic3d_TOA_COMPUTE)
197       {
198         continue;
199       }
200
201       const Standard_Integer anIndex = IsComputed (aStruct);
202       if (anIndex != 0)
203       {
204         const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (anIndex);
205         eraseStructure   (aStructComp->CStructure());
206         displayStructure (aStruct->CStructure(), aStruct->DisplayPriority());
207       }
208     }
209     return;
210   }
211
212   for (Graphic3d_MapOfStructure::Iterator aDispStructIter (myStructsDisplayed); aDispStructIter.More(); aDispStructIter.Next())
213   {
214     Handle(Graphic3d_Structure) aStruct  = aDispStructIter.Key();
215     const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
216     if (anAnswer != Graphic3d_TOA_COMPUTE)
217     {
218       continue;
219     }
220
221     const Standard_Integer anIndex = IsComputed (aStruct);
222     if (anIndex != 0)
223     {
224       eraseStructure   (aStruct->CStructure());
225       displayStructure (myStructsComputed.Value (anIndex)->CStructure(), aStruct->DisplayPriority());
226
227       Display (aStruct, Aspect_TOU_WAIT);
228       if (aStruct->IsHighlighted())
229       {
230         const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.Value (anIndex);
231         if (!aCompStruct->IsHighlighted())
232         {
233           aCompStruct->Highlight (Aspect_TOHM_COLOR, aStruct->HighlightColor(), Standard_False);
234         }
235       }
236     }
237     else
238     {
239       Handle(Graphic3d_Structure) aCompStruct = aStruct->IsTransformed() ? aStruct->Compute (this, aStruct->Transformation()) : aStruct->Compute (this);
240       aCompStruct->SetHLRValidation (Standard_True);
241
242       const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
243                                                 && aStruct->ComputeVisual() != Graphic3d_TOS_SHADING;
244       const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
245                                                 && aStruct->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
246       if (toComputeWireframe) aCompStruct->SetVisual (Graphic3d_TOS_WIREFRAME);
247       if (toComputeShading  ) aCompStruct->SetVisual (Graphic3d_TOS_SHADING);
248
249       if (aStruct->IsHighlighted())
250       {
251         aCompStruct->Highlight (Aspect_TOHM_COLOR, aStruct->HighlightColor(), Standard_False);
252       }
253
254       Standard_Boolean hasResult = Standard_False;
255       const Standard_Integer aNbToCompute = myStructsToCompute.Length();
256       const Standard_Integer aStructId    = aStruct->Identification();
257       for (Standard_Integer aToCompStructIter = 1; aToCompStructIter <= aNbToCompute; ++aToCompStructIter)
258       {
259         if (myStructsToCompute.Value (aToCompStructIter)->Identification() == aStructId)
260         {
261           hasResult = Standard_True;
262           myStructsComputed.ChangeValue (aToCompStructIter) = aCompStruct;
263           break;
264         }
265       }
266
267       if (!hasResult)
268       {
269         myStructsToCompute.Append (aStruct);
270         myStructsComputed .Append (aCompStruct);
271       }
272
273       eraseStructure   (aStruct->CStructure());
274       displayStructure (aCompStruct->CStructure(), aStruct->DisplayPriority());
275     }
276   }
277   Update (myStructureManager->UpdateMode());
278 }
279
280 // =======================================================================
281 // function : ReCompute
282 // purpose  :
283 // =======================================================================
284 void Graphic3d_CView::ReCompute (const Handle(Graphic3d_Structure)& theStruct)
285 {
286   theStruct->CalculateBoundBox();
287   if (!theStruct->IsMutable()
288    && !theStruct->CStructure()->IsForHighlight
289    && !theStruct->CStructure()->IsInfinite)
290   {
291     const Graphic3d_ZLayerId aLayerId = theStruct->GetZLayer();
292     InvalidateBVHData (aLayerId);
293   }
294
295   if (!ComputedMode()
296    || !IsActive()
297    || !theStruct->IsDisplayed())
298   {
299     return;
300   }
301
302   const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStruct->Visual());
303   if (anAnswer != Graphic3d_TOA_COMPUTE)
304   {
305     return;
306   }
307
308   const Standard_Integer anIndex = IsComputed (theStruct);
309   if (anIndex == 0)
310   {
311     return;
312   }
313
314   // compute + validation
315   Handle(Graphic3d_Structure) aCompStructOld = myStructsComputed.ChangeValue (anIndex);
316   Handle(Graphic3d_Structure) aCompStruct    = aCompStructOld;
317   aCompStruct->SetTransformation (Handle(Geom_Transformation)());
318   theStruct->IsTransformed() ? theStruct->Compute (this, theStruct->Transformation(), aCompStruct)
319                              : theStruct->Compute (this,                              aCompStruct);
320   aCompStruct->SetHLRValidation (Standard_True);
321
322   // of which type will be the computed?
323   const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
324                                            && theStruct->ComputeVisual() != Graphic3d_TOS_SHADING;
325   const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
326                                            && theStruct->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
327   if (toComputeWireframe)
328   {
329     aCompStruct->SetVisual (Graphic3d_TOS_WIREFRAME);
330   }
331   else if (toComputeShading)
332   {
333     aCompStruct->SetVisual (Graphic3d_TOS_SHADING);
334   }
335
336   if (theStruct->IsHighlighted())
337   {
338     aCompStruct->Highlight (Aspect_TOHM_COLOR, theStruct->HighlightColor(), Standard_False);
339   }
340
341   // The previous calculation is removed and the new one is displayed
342   eraseStructure   (aCompStructOld->CStructure());
343   displayStructure (aCompStruct->CStructure(), theStruct->DisplayPriority());
344
345   // why not just replace existing items?
346   //myStructsToCompute.ChangeValue (anIndex) = theStruct;
347   //myStructsComputed .ChangeValue (anIndex) = aCompStruct;
348
349   // hlhsr and the new associated compute are added
350   myStructsToCompute.Append (theStruct);
351   myStructsComputed .Append (aCompStruct);
352
353   // hlhsr and the new associated compute are removed
354   myStructsToCompute.Remove (anIndex);
355   myStructsComputed .Remove (anIndex);
356 }
357
358 // =======================================================================
359 // function : Update
360 // purpose  :
361 // =======================================================================
362 void Graphic3d_CView::Update (const Aspect_TypeOfUpdate theUpdateMode,
363                               const Graphic3d_ZLayerId  theLayerId)
364 {
365   InvalidateZLayerBoundingBox (theLayerId);
366
367   if (theUpdateMode == Aspect_TOU_ASAP)
368   {
369     Compute();
370     Redraw();
371   }
372 }
373
374 // =======================================================================
375 // function : ContainsFacet
376 // purpose  :
377 // =======================================================================
378 Standard_Boolean Graphic3d_CView::ContainsFacet() const
379 {
380   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
381   {
382     if (aStructIter.Key()->ContainsFacet())
383     {
384       return Standard_True;
385     }
386   }
387   return Standard_False;
388 }
389
390 // =======================================================================
391 // function : ContainsFacet
392 // purpose  :
393 // =======================================================================
394 Standard_Boolean Graphic3d_CView::ContainsFacet (const Graphic3d_MapOfStructure& theSet) const
395 {
396   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
397   {
398     if (aStructIter.Key()->ContainsFacet())
399     {
400       return Standard_True;
401     }
402   }
403   return Standard_False;
404 }
405
406 // =======================================================================
407 // function : DisplayedStructures
408 // purpose  :
409 // =======================================================================
410 void Graphic3d_CView::DisplayedStructures (Graphic3d_MapOfStructure& theStructures) const
411 {
412   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
413   {
414     theStructures.Add (aStructIter.Key());
415   }
416 }
417
418 // =======================================================================
419 // function : MinMaxValues
420 // purpose  :
421 // =======================================================================
422 Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIncludeAuxiliary) const
423 {
424   Bnd_Box aResult;
425
426   if (!IsDefined())
427   {
428     return aResult;
429   }
430
431   Handle(Graphic3d_Camera) aCamera = Camera();
432   Standard_Integer aWinWidth  = 0;
433   Standard_Integer aWinHeight = 0;
434
435   Window()->Size (aWinWidth, aWinHeight);
436
437   for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
438   {
439     Graphic3d_BndBox4f aBox = ZLayerBoundingBox (THE_DEFAULT_LAYERS[aLayer],
440                                                  aCamera,
441                                                  aWinWidth,
442                                                  aWinHeight,
443                                                  theToIncludeAuxiliary);
444     combineBox (aResult, aBox);
445   }
446
447   Standard_Integer aMaxZLayer = ZLayerMax();
448   for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId <= aMaxZLayer; ++aLayerId)
449   {
450     Graphic3d_BndBox4f aBox = ZLayerBoundingBox (aLayerId,
451                                                  aCamera,
452                                                  aWinWidth,
453                                                  aWinHeight,
454                                                  theToIncludeAuxiliary);
455     combineBox (aResult, aBox);
456   }
457
458   return aResult;
459 }
460
461 // =======================================================================
462 // function : ConsiderZoomPersistenceObjects
463 // purpose  :
464 // =======================================================================
465 Standard_Real Graphic3d_CView::ConsiderZoomPersistenceObjects()
466 {
467   if (!IsDefined())
468   {
469     return 1.0;
470   }
471
472   Handle(Graphic3d_Camera) aCamera = Camera();
473   Standard_Integer aWinWidth  = 0;
474   Standard_Integer aWinHeight = 0;
475
476   Window()->Size (aWinWidth, aWinHeight);
477
478   Standard_Real aMaxCoef = 1.0;
479   for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
480   {
481     aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (THE_DEFAULT_LAYERS[aLayer], aCamera, aWinWidth, aWinHeight));
482   }
483
484   for (Standard_Integer aLayer = Graphic3d_ZLayerId_Default; aLayer <= ZLayerMax(); ++aLayer)
485   {
486     aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (aLayer, aCamera, aWinWidth, aWinHeight));
487   }
488
489   return aMaxCoef;
490 }
491
492 // =======================================================================
493 // function : MinMaxValues
494 // purpose  :
495 // =======================================================================
496 Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
497                                        const Standard_Boolean theToIgnoreInfiniteFlag) const
498 {
499   Bnd_Box aResult;
500   const Standard_Integer aViewId = Identification();
501
502   Handle(Graphic3d_Camera) aCamera = Camera();
503   Standard_Integer aWinWidth  = 0;
504   Standard_Integer aWinHeight = 0;
505   if (IsDefined())
506   {
507     Window()->Size (aWinWidth, aWinHeight);
508   }
509
510   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
511   {
512     const Handle(Graphic3d_Structure)& aStructure = aStructIter.Key();
513     if (aStructure->IsEmpty()
514     || !aStructure->CStructure()->IsVisible (aViewId))
515     {
516       continue;
517     }
518
519     // "FitAll" operation ignores object with transform persistence parameter
520     if (!aStructure->TransformPersistence().IsNull())
521     {
522       // Panning and 2d persistence apply changes to projection or/and its translation components.
523       // It makes them incompatible with z-fitting algorithm. Ignored by now.
524       if (!theToIgnoreInfiniteFlag
525        || aStructure->TransformPersistence()->IsTrihedronOr2d())
526       {
527         continue;
528       }
529     }
530
531     Bnd_Box aBox = aStructure->MinMaxValues (theToIgnoreInfiniteFlag);
532
533     if (aBox.IsWhole() || aBox.IsVoid())
534     {
535       continue;
536     }
537
538     if (!aStructure->TransformPersistence().IsNull())
539     {
540       const Graphic3d_Mat4d& aProjectionMat = aCamera->ProjectionMatrix();
541       const Graphic3d_Mat4d& aWorldViewMat  = aCamera->OrientationMatrix();
542       aStructure->TransformPersistence()->Apply (aCamera, aProjectionMat, aWorldViewMat, aWinWidth, aWinHeight, aBox);
543     }
544
545     // To prevent float overflow at camera parameters calculation and further
546     // rendering, bounding boxes with at least one vertex coordinate out of
547     // float range are skipped by view fit algorithms
548     if (Abs (aBox.CornerMax().X()) >= ShortRealLast() ||
549         Abs (aBox.CornerMax().Y()) >= ShortRealLast() ||
550         Abs (aBox.CornerMax().Z()) >= ShortRealLast() ||
551         Abs (aBox.CornerMin().X()) >= ShortRealLast() ||
552         Abs (aBox.CornerMin().Y()) >= ShortRealLast() ||
553         Abs (aBox.CornerMin().Z()) >= ShortRealLast())
554     {
555       continue;
556     }
557
558     aResult.Add (aBox);
559   }
560   return aResult;
561 }
562
563 // =======================================================================
564 // function : acceptDisplay
565 // purpose  :
566 // =======================================================================
567 Graphic3d_TypeOfAnswer Graphic3d_CView::acceptDisplay (const Graphic3d_TypeOfStructure theStructType) const
568 {
569   switch (theStructType)
570   {
571     case Graphic3d_TOS_ALL:
572     {
573       return Graphic3d_TOA_YES; // The structure accepts any type of view
574     }
575     case Graphic3d_TOS_SHADING:
576     {
577       return myVisualization == Graphic3d_TOV_SHADING
578            ? Graphic3d_TOA_YES
579            : Graphic3d_TOA_NO;
580     }
581     case Graphic3d_TOS_WIREFRAME:
582     {
583       return myVisualization == Graphic3d_TOV_WIREFRAME
584            ? Graphic3d_TOA_YES
585            : Graphic3d_TOA_NO;
586     }
587     case Graphic3d_TOS_COMPUTED:
588     {
589       return (myVisualization == Graphic3d_TOV_SHADING || myVisualization == Graphic3d_TOV_WIREFRAME)
590            ?  Graphic3d_TOA_COMPUTE
591            :  Graphic3d_TOA_NO;
592     }
593   }
594   return Graphic3d_TOA_NO;
595 }
596
597 // =======================================================================
598 // function : Compute
599 // purpose  :
600 // =======================================================================
601 void Graphic3d_CView::Compute()
602 {
603   // force HLRValidation to False on all structures calculated in the view
604   const Standard_Integer aNbCompStructs = myStructsComputed.Length();
605   for (Standard_Integer aStructIter = 1; aStructIter <= aNbCompStructs; ++aStructIter)
606   {
607     myStructsComputed.Value (aStructIter)->SetHLRValidation (Standard_False);
608   }
609
610   if (!ComputedMode())
611   {
612     return;
613   }
614
615   // Change of orientation or of projection type =>
616   // Remove structures that were calculated for the previous orientation.
617   // Recalculation of new structures.
618   NCollection_Sequence<Handle(Graphic3d_Structure)> aStructsSeq;
619   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
620   {
621     const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStructIter.Key()->Visual());
622     if (anAnswer == Graphic3d_TOA_COMPUTE)
623     {
624       aStructsSeq.Append (aStructIter.Key()); // if the structure was calculated, it is recalculated
625     }
626   }
627
628   for (NCollection_Sequence<Handle(Graphic3d_Structure)>::Iterator aStructIter (aStructsSeq); aStructIter.More(); aStructIter.Next())
629   {
630     Display (aStructIter.ChangeValue(), Aspect_TOU_WAIT);
631   }
632 }
633
634 // =======================================================================
635 // function : Clear
636 // purpose  :
637 // =======================================================================
638 void Graphic3d_CView::Clear (const Handle(Graphic3d_Structure)& theStructure,
639                              const Standard_Boolean theWithDestruction)
640 {
641   const Standard_Integer anIndex = IsComputed (theStructure);
642   if (anIndex != 0)
643   {
644     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.Value (anIndex);
645     aCompStruct->GraphicClear (theWithDestruction);
646     aCompStruct->SetHLRValidation (Standard_False);
647   }
648 }
649
650 // =======================================================================
651 // function : Connect
652 // purpose  :
653 // =======================================================================
654 void Graphic3d_CView::Connect (const Handle(Graphic3d_Structure)& theMother,
655                                const Handle(Graphic3d_Structure)& theDaughter)
656 {
657   Standard_Integer anIndexM = IsComputed (theMother);
658   Standard_Integer anIndexD = IsComputed (theDaughter);
659   if (anIndexM != 0
660    && anIndexD != 0)
661   {
662     const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
663     const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
664     aStructM->GraphicConnect (aStructD);
665   }
666 }
667
668 // =======================================================================
669 // function : Disconnect
670 // purpose  :
671 // =======================================================================
672 void Graphic3d_CView::Disconnect (const Handle(Graphic3d_Structure)& theMother,
673                                   const Handle(Graphic3d_Structure)& theDaughter)
674 {
675   Standard_Integer anIndexM = IsComputed (theMother);
676   Standard_Integer anIndexD = IsComputed (theDaughter);
677   if (anIndexM != 0
678    && anIndexD != 0)
679   {
680     const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
681     const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
682     aStructM->GraphicDisconnect (aStructD);
683   }
684 }
685
686 // =======================================================================
687 // function : Display
688 // purpose  :
689 // =======================================================================
690 void Graphic3d_CView::Display (const Handle(Graphic3d_Structure)& theStructure)
691 {
692   Display (theStructure, myStructureManager->UpdateMode());
693 }
694
695 // =======================================================================
696 // function : Display
697 // purpose  :
698 // =======================================================================
699 void Graphic3d_CView::Display (const Handle(Graphic3d_Structure)& theStructure,
700                                const Aspect_TypeOfUpdate theUpdateMode)
701 {
702   if (!IsActive())
703   {
704     return;
705   }
706
707   // If Display on a structure present in the list of calculated structures while it is not
708   // or more, of calculated type =>
709   // - removes it as well as the associated old computed
710   // THis happens when hlhsr becomes again of type e non computed after SetVisual.
711   Standard_Integer anIndex = IsComputed (theStructure);
712   if (anIndex != 0
713    && theStructure->Visual() != Graphic3d_TOS_COMPUTED)
714   {
715     myStructsToCompute.Remove (anIndex);
716     myStructsComputed .Remove (anIndex);
717     anIndex = 0;
718   }
719
720   Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStructure->Visual());
721   if (anAnswer == Graphic3d_TOA_NO)
722   {
723     return;
724   }
725
726   if (!ComputedMode())
727   {
728     anAnswer = Graphic3d_TOA_YES;
729   }
730
731   if (anAnswer == Graphic3d_TOA_YES)
732   {
733     if (!myStructsDisplayed.Add (theStructure))
734     {
735       return;
736     }
737
738     theStructure->CalculateBoundBox();
739     displayStructure (theStructure->CStructure(), theStructure->DisplayPriority());
740     Update (theUpdateMode, theStructure->GetZLayer());
741     return;
742   }
743   else if (anAnswer != Graphic3d_TOA_COMPUTE)
744   {
745     return;
746   }
747
748   if (anIndex != 0)
749   {
750     // Already computed, is COMPUTED still valid?
751     const Handle(Graphic3d_Structure)& anOldStruct = myStructsComputed.Value (anIndex);
752     if (anOldStruct->HLRValidation())
753     {
754       // Case COMPUTED valid, to be displayed
755       if (!myStructsDisplayed.Add (theStructure))
756       {
757         return;
758       }
759
760       displayStructure (anOldStruct->CStructure(), theStructure->DisplayPriority());
761       Update (theUpdateMode, anOldStruct->GetZLayer());
762       return;
763     }
764     else
765     {
766       // Case COMPUTED invalid
767       // Is there another valid representation?
768       // Find in the sequence of already calculated structures
769       // 1/ Structure having the same Owner as <AStructure>
770       // 2/ That is not <AStructure>
771       // 3/ The COMPUTED which of is valid
772       const Standard_Integer aNewIndex = HaveTheSameOwner (theStructure);
773       if (aNewIndex != 0)
774       {
775         // Case of COMPUTED invalid, WITH a valid of replacement; to be displayed
776         if (!myStructsDisplayed.Add (theStructure))
777         {
778           return;
779         }
780
781         const Handle(Graphic3d_Structure)& aNewStruct = myStructsComputed.Value (aNewIndex);
782         myStructsComputed.SetValue (anIndex, aNewStruct);
783         displayStructure (aNewStruct->CStructure(), theStructure->DisplayPriority());
784         Update (theUpdateMode, aNewStruct->GetZLayer());
785         return;
786       }
787       else
788       {
789         // Case COMPUTED invalid, WITHOUT a valid of replacement
790         // COMPUTED is removed if displayed
791         if (myStructsDisplayed.Contains (theStructure))
792         {
793           eraseStructure (anOldStruct->CStructure());
794         }
795       }
796     }
797   }
798
799   // Compute + Validation
800   Handle(Graphic3d_Structure) aStruct;
801   if (anIndex != 0)
802   {
803     aStruct = myStructsComputed.Value (anIndex);
804     aStruct->SetTransformation (Handle(Geom_Transformation)());
805     if (theStructure->IsTransformed())
806     {
807       theStructure->Compute (this, theStructure->Transformation(), aStruct);
808     }
809     else
810     {
811       theStructure->Compute (this, aStruct);
812     }
813   }
814   else
815   {
816     aStruct = theStructure->IsTransformed()
817             ? theStructure->Compute (this, theStructure->Transformation())
818             : theStructure->Compute (this);
819   }
820
821   aStruct->SetHLRValidation (Standard_True);
822
823   // TOCOMPUTE and COMPUTED associated to sequences are added
824   myStructsToCompute.Append (theStructure);
825   myStructsComputed .Append (aStruct);
826
827   // The previous are removed if necessary
828   if (anIndex != 0)
829   {
830     myStructsToCompute.Remove (anIndex);
831     myStructsComputed .Remove (anIndex);
832   }
833
834   // Of which type will be the computed?
835   const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
836                                            && theStructure->ComputeVisual() != Graphic3d_TOS_SHADING;
837   const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
838                                            && theStructure->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
839   if (!toComputeShading && !toComputeWireframe)
840   {
841     anAnswer = Graphic3d_TOA_NO;
842   }
843   else
844   {
845     aStruct->SetVisual (toComputeWireframe ? Graphic3d_TOS_WIREFRAME : Graphic3d_TOS_SHADING);
846     anAnswer = acceptDisplay (aStruct->Visual());
847   }
848
849   if (theStructure->IsHighlighted())
850   {
851     aStruct->Highlight (Aspect_TOHM_COLOR, theStructure->HighlightColor(), Standard_False);
852   }
853
854   // It is displayed only if the calculated structure
855   // has a proper type corresponding to the one of the view.
856   if (anAnswer == Graphic3d_TOA_NO)
857   {
858     return;
859   }
860
861   myStructsDisplayed.Add (theStructure);
862   displayStructure (aStruct->CStructure(), theStructure->DisplayPriority());
863
864   Update (theUpdateMode, aStruct->GetZLayer());
865 }
866
867 // =======================================================================
868 // function : Erase
869 // purpose  :
870 // =======================================================================
871 void Graphic3d_CView::Erase (const Handle(Graphic3d_Structure)& theStructure)
872 {
873   Erase (theStructure, myStructureManager->UpdateMode());
874 }
875
876 // =======================================================================
877 // function : Erase
878 // purpose  :
879 // =======================================================================
880 void Graphic3d_CView::Erase (const Handle(Graphic3d_Structure)& theStructure,
881                              const Aspect_TypeOfUpdate theUpdateMode)
882 {
883   if (!IsDisplayed (theStructure))
884   {
885     return;
886   }
887
888   Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStructure->Visual());
889   if (!ComputedMode())
890   {
891     anAnswer = Graphic3d_TOA_YES;
892   }
893
894   if (anAnswer != Graphic3d_TOA_COMPUTE)
895   {
896     eraseStructure (theStructure->CStructure());
897   }
898   else if (anAnswer == Graphic3d_TOA_COMPUTE && myIsInComputedMode)
899   {
900     const Standard_Integer anIndex = IsComputed (theStructure);
901     if (anIndex != 0)
902     {
903       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
904       eraseStructure (aCompStruct->CStructure());
905     }
906   }
907   myStructsDisplayed.Remove (theStructure);
908   Update (theUpdateMode, theStructure->GetZLayer());
909 }
910
911 // =======================================================================
912 // function : Highlight
913 // purpose  :
914 // =======================================================================
915 void Graphic3d_CView::Highlight (const Handle(Graphic3d_Structure)& theStructure,
916                                  const Aspect_TypeOfHighlightMethod theMethod)
917 {
918   const Standard_Integer anIndex = IsComputed (theStructure);
919   if (anIndex != 0)
920   {
921     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
922     aCompStruct->Highlight (theMethod, theStructure->HighlightColor(), Standard_False);
923   }
924 }
925
926 // =======================================================================
927 // function : SetTransform
928 // purpose  :
929 // =======================================================================
930 void Graphic3d_CView::SetTransform (const Handle(Graphic3d_Structure)& theStructure,
931                                     const Handle(Geom_Transformation)& theTrsf)
932 {
933   const Standard_Integer anIndex = IsComputed (theStructure);
934   if (anIndex != 0)
935   {
936     // Test is somewhat light !
937     // trsf is transferred only if it is :
938     // a translation
939     // a scale
940     if (!theTrsf.IsNull()
941       && (theTrsf->Form() == gp_Translation
942        || theTrsf->Form() == gp_Scale
943        || theTrsf->Form() == gp_CompoundTrsf))
944     {
945       ReCompute (theStructure);
946     }
947     else
948     {
949       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
950       aCompStruct->GraphicTransform (theTrsf);
951     }
952   }
953
954   theStructure->CalculateBoundBox();
955   if (!theStructure->IsMutable()
956    && !theStructure->CStructure()->IsForHighlight
957    && !theStructure->CStructure()->IsInfinite)
958   {
959     const Graphic3d_ZLayerId aLayerId = theStructure->GetZLayer();
960     InvalidateBVHData (aLayerId);
961   }
962 }
963
964 // =======================================================================
965 // function : UnHighlight
966 // purpose  :
967 // =======================================================================
968 void Graphic3d_CView::UnHighlight (const Handle(Graphic3d_Structure)& theStructure)
969 {
970   Standard_Integer anIndex = IsComputed (theStructure);
971   if (anIndex != 0)
972   {
973     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
974     aCompStruct->GraphicUnHighlight();
975   }
976 }
977
978 // ========================================================================
979 // function : IsComputed
980 // purpose  :
981 // ========================================================================
982 Standard_Boolean Graphic3d_CView::IsComputed (const Standard_Integer theStructId,
983                                               Handle(Graphic3d_Structure)& theComputedStruct) const
984 {
985   theComputedStruct.Nullify();
986   if (!ComputedMode())
987     return Standard_False;
988
989   const Standard_Integer aNbStructs = myStructsToCompute.Length();
990   for (Standard_Integer aStructIter = 1; aStructIter <= aNbStructs; ++aStructIter)
991   {
992     if (myStructsToCompute.Value (aStructIter)->Identification() == theStructId)
993     {
994       theComputedStruct = myStructsComputed (aStructIter);
995       return Standard_True;
996     }
997   }
998   return Standard_False;
999 }
1000
1001 // =======================================================================
1002 // function : IsComputed
1003 // purpose  :
1004 // =======================================================================
1005 Standard_Integer Graphic3d_CView::IsComputed (const Handle(Graphic3d_Structure)& theStructure) const
1006 {
1007   const Standard_Integer aStructId  = theStructure->Identification();
1008   const Standard_Integer aNbStructs = myStructsToCompute.Length();
1009   for (Standard_Integer aStructIter = 1; aStructIter <= aNbStructs; ++aStructIter)
1010   {
1011     const Handle(Graphic3d_Structure)& aStruct = myStructsToCompute.Value (aStructIter);
1012     if (aStruct->Identification() == aStructId)
1013     {
1014       return aStructIter;
1015     }
1016   }
1017   return 0;
1018 }
1019
1020 // =======================================================================
1021 // function : IsDisplayed
1022 // purpose  :
1023 // =======================================================================
1024 Standard_Boolean Graphic3d_CView::IsDisplayed (const Handle(Graphic3d_Structure)& theStructure) const
1025 {
1026   return myStructsDisplayed.Contains (theStructure);
1027 }
1028
1029 // =======================================================================
1030 // function : ChangePriority
1031 // purpose  :
1032 // =======================================================================
1033 void Graphic3d_CView::ChangePriority (const Handle(Graphic3d_Structure)& theStructure,
1034                                       const Standard_Integer /*theOldPriority*/,
1035                                       const Standard_Integer theNewPriority)
1036 {
1037   if (!IsActive()
1038   ||  !IsDisplayed (theStructure))
1039   {
1040     return;
1041   }
1042
1043   if (!myIsInComputedMode)
1044   {
1045     changePriority (theStructure->CStructure(), theNewPriority);
1046     return;
1047   }
1048
1049   const Standard_Integer              anIndex  = IsComputed (theStructure);
1050   const Handle(Graphic3d_CStructure)& aCStruct = anIndex != 0
1051                                                ? myStructsComputed.Value (anIndex)->CStructure()
1052                                                : theStructure->CStructure();
1053
1054   changePriority (aCStruct, theNewPriority);
1055 }
1056
1057 // =======================================================================
1058 // function : ChangeZLayer
1059 // purpose  :
1060 // =======================================================================
1061 void Graphic3d_CView::ChangeZLayer (const Handle(Graphic3d_Structure)& theStructure,
1062                                     const Graphic3d_ZLayerId theLayerId)
1063 {
1064   if (!IsActive()
1065   ||  !IsDisplayed (theStructure))
1066   {
1067     return;
1068   }
1069
1070   if (!myIsInComputedMode)
1071   {
1072     changeZLayer (theStructure->CStructure(), theLayerId);
1073     return;
1074   }
1075
1076   const Standard_Integer       anIndex  = IsComputed (theStructure);
1077   Handle(Graphic3d_CStructure) aCStruct = anIndex != 0
1078                                        ? myStructsComputed.Value (anIndex)->CStructure()
1079                                        : theStructure->CStructure();
1080
1081   changeZLayer (aCStruct, theLayerId);
1082 }
1083
1084 // =======================================================================
1085 // function : HaveTheSameOwner
1086 // purpose  :
1087 // =======================================================================
1088 Standard_Integer Graphic3d_CView::HaveTheSameOwner (const Handle(Graphic3d_Structure)& theStructure) const
1089 {
1090   // Find in the sequence of already calculated structures
1091   // 1/ Structure with the same Owner as <AStructure>
1092   // 2/ Which is not <AStructure>
1093   // 3/ COMPUTED which of is valid
1094   const Standard_Integer aNbToCompStructs = myStructsToCompute.Length();
1095   for (Standard_Integer aStructIter = 1; aStructIter <= aNbToCompStructs; ++aStructIter)
1096   {
1097     const Handle(Graphic3d_Structure)& aStructToComp = myStructsToCompute.Value (aStructIter);
1098     if (aStructToComp->Owner()          == theStructure->Owner()
1099      && aStructToComp->Identification() != theStructure->Identification())
1100     {
1101       const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (aStructIter);
1102       if (aStructComp->HLRValidation())
1103       {
1104         return aStructIter;
1105       }
1106     }
1107   }
1108   return 0;
1109 }
1110
1111 // =======================================================================
1112 // function : CopySettings
1113 // purpose  :
1114 // =======================================================================
1115 void Graphic3d_CView::CopySettings (const Handle(Graphic3d_CView)& theOther)
1116 {
1117   ChangeRenderingParams() = theOther->RenderingParams();
1118   SetBackground            (theOther->Background());
1119   SetGradientBackground    (theOther->GradientBackground());
1120   SetBackgroundImage       (theOther->BackgroundImage());
1121   SetBackgroundImageStyle  (theOther->BackgroundImageStyle());
1122   SetTextureEnv            (theOther->TextureEnv());
1123   SetCullingEnabled        (theOther->IsCullingEnabled());
1124   SetShadingModel          (theOther->ShadingModel());
1125   SetBackfacingModel       (theOther->BackfacingModel());
1126   SetCamera                (new Graphic3d_Camera (theOther->Camera()));
1127   SetGLLightEnabled        (theOther->IsGLLightEnabled());
1128   SetLights                (theOther->Lights());
1129   SetClipPlanes            (theOther->ClipPlanes());
1130 }