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