0027860: Visualization - clean up Transformation Persistence API
[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       TColStd_Array2OfReal aTrsf (0, 3, 0, 3);
240       aStruct->Transform (aTrsf);
241       Handle(Graphic3d_Structure) aCompStruct = aStruct->IsTransformed() ? aStruct->Compute (this, aTrsf) : aStruct->Compute (this);
242       aCompStruct->SetHLRValidation (Standard_True);
243
244       const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
245                                                 && aStruct->ComputeVisual() != Graphic3d_TOS_SHADING;
246       const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
247                                                 && aStruct->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
248       if (toComputeWireframe) aCompStruct->SetVisual (Graphic3d_TOS_WIREFRAME);
249       if (toComputeShading  ) aCompStruct->SetVisual (Graphic3d_TOS_SHADING);
250
251       if (aStruct->IsHighlighted())
252       {
253         aCompStruct->Highlight (Aspect_TOHM_COLOR, aStruct->HighlightColor(), Standard_False);
254       }
255
256       Standard_Boolean hasResult = Standard_False;
257       const Standard_Integer aNbToCompute = myStructsToCompute.Length();
258       const Standard_Integer aStructId    = aStruct->Identification();
259       for (Standard_Integer aToCompStructIter = 1; aToCompStructIter <= aNbToCompute; ++aToCompStructIter)
260       {
261         if (myStructsToCompute.Value (aToCompStructIter)->Identification() == aStructId)
262         {
263           hasResult = Standard_True;
264           myStructsComputed.ChangeValue (aToCompStructIter) = aCompStruct;
265           break;
266         }
267       }
268
269       if (!hasResult)
270       {
271         myStructsToCompute.Append (aStruct);
272         myStructsComputed .Append (aCompStruct);
273       }
274
275       eraseStructure   (aStruct->CStructure());
276       displayStructure (aCompStruct->CStructure(), aStruct->DisplayPriority());
277     }
278   }
279   Update (myStructureManager->UpdateMode());
280 }
281
282 // =======================================================================
283 // function : ReCompute
284 // purpose  :
285 // =======================================================================
286 void Graphic3d_CView::ReCompute (const Handle(Graphic3d_Structure)& theStruct)
287 {
288   theStruct->CalculateBoundBox();
289   if (!theStruct->IsMutable()
290    && !theStruct->CStructure()->IsForHighlight
291    && !theStruct->CStructure()->IsInfinite)
292   {
293     const Graphic3d_ZLayerId aLayerId = theStruct->GetZLayer();
294     InvalidateBVHData (aLayerId);
295   }
296
297   if (!ComputedMode()
298    || !IsActive()
299    || !theStruct->IsDisplayed())
300   {
301     return;
302   }
303
304   const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStruct->Visual());
305   if (anAnswer != Graphic3d_TOA_COMPUTE)
306   {
307     return;
308   }
309
310   const Standard_Integer anIndex = IsComputed (theStruct);
311   if (anIndex == 0)
312   {
313     return;
314   }
315
316   // compute + validation
317   TColStd_Array2OfReal anIdent (0, 3, 0, 3);
318   for (Standard_Integer aRow = 0; aRow <= 3; ++aRow)
319   {
320     for (Standard_Integer aCol = 0; aCol <= 3; ++aCol)
321     {
322       anIdent (aRow, aCol) = (aRow == aCol ? 1.0 : 0.0);
323     }
324   }
325   TColStd_Array2OfReal aTrsf (0, 3, 0, 3);
326   theStruct->Transform (aTrsf);
327
328   Handle(Graphic3d_Structure) aCompStructOld = myStructsComputed.ChangeValue (anIndex);
329   Handle(Graphic3d_Structure) aCompStruct    = aCompStructOld;
330   aCompStruct->SetTransform (anIdent, Graphic3d_TOC_REPLACE);
331   theStruct->IsTransformed() ? theStruct->Compute (this, aTrsf, aCompStruct)
332                              : theStruct->Compute (this,        aCompStruct);
333   aCompStruct->SetHLRValidation (Standard_True);
334
335   // of which type will be the computed?
336   const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
337                                            && theStruct->ComputeVisual() != Graphic3d_TOS_SHADING;
338   const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
339                                            && theStruct->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
340   if (toComputeWireframe)
341   {
342     aCompStruct->SetVisual (Graphic3d_TOS_WIREFRAME);
343   }
344   else if (toComputeShading)
345   {
346     aCompStruct->SetVisual (Graphic3d_TOS_SHADING);
347   }
348
349   if (theStruct->IsHighlighted())
350   {
351     aCompStruct->Highlight (Aspect_TOHM_COLOR, theStruct->HighlightColor(), Standard_False);
352   }
353
354   // The previous calculation is removed and the new one is displayed
355   eraseStructure   (aCompStructOld->CStructure());
356   displayStructure (aCompStruct->CStructure(), theStruct->DisplayPriority());
357
358   // why not just replace existing items?
359   //myStructsToCompute.ChangeValue (anIndex) = theStruct;
360   //myStructsComputed .ChangeValue (anIndex) = aCompStruct;
361
362   // hlhsr and the new associated compute are added
363   myStructsToCompute.Append (theStruct);
364   myStructsComputed .Append (aCompStruct);
365
366   // hlhsr and the new associated compute are removed
367   myStructsToCompute.Remove (anIndex);
368   myStructsComputed .Remove (anIndex);
369 }
370
371 // =======================================================================
372 // function : Update
373 // purpose  :
374 // =======================================================================
375 void Graphic3d_CView::Update (const Aspect_TypeOfUpdate theUpdateMode,
376                               const Graphic3d_ZLayerId  theLayerId)
377 {
378   InvalidateZLayerBoundingBox (theLayerId);
379
380   if (theUpdateMode == Aspect_TOU_ASAP)
381   {
382     Compute();
383     Redraw();
384   }
385 }
386
387 // =======================================================================
388 // function : ContainsFacet
389 // purpose  :
390 // =======================================================================
391 Standard_Boolean Graphic3d_CView::ContainsFacet() const
392 {
393   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
394   {
395     if (aStructIter.Key()->ContainsFacet())
396     {
397       return Standard_True;
398     }
399   }
400   return Standard_False;
401 }
402
403 // =======================================================================
404 // function : ContainsFacet
405 // purpose  :
406 // =======================================================================
407 Standard_Boolean Graphic3d_CView::ContainsFacet (const Graphic3d_MapOfStructure& theSet) const
408 {
409   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
410   {
411     if (aStructIter.Key()->ContainsFacet())
412     {
413       return Standard_True;
414     }
415   }
416   return Standard_False;
417 }
418
419 // =======================================================================
420 // function : DisplayedStructures
421 // purpose  :
422 // =======================================================================
423 void Graphic3d_CView::DisplayedStructures (Graphic3d_MapOfStructure& theStructures) const
424 {
425   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
426   {
427     theStructures.Add (aStructIter.Key());
428   }
429 }
430
431 // =======================================================================
432 // function : MinMaxValues
433 // purpose  :
434 // =======================================================================
435 Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIncludeAuxiliary) const
436 {
437   Bnd_Box aResult;
438
439   if (!IsDefined())
440   {
441     return aResult;
442   }
443
444   Handle(Graphic3d_Camera) aCamera = Camera();
445   Standard_Integer aWinWidth  = 0;
446   Standard_Integer aWinHeight = 0;
447
448   Window()->Size (aWinWidth, aWinHeight);
449
450   for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
451   {
452     Graphic3d_BndBox4f aBox = ZLayerBoundingBox (THE_DEFAULT_LAYERS[aLayer],
453                                                  aCamera,
454                                                  aWinWidth,
455                                                  aWinHeight,
456                                                  theToIncludeAuxiliary);
457     combineBox (aResult, aBox);
458   }
459
460   Standard_Integer aMaxZLayer = ZLayerMax();
461   for (Standard_Integer aLayerId = Graphic3d_ZLayerId_Default; aLayerId <= aMaxZLayer; ++aLayerId)
462   {
463     Graphic3d_BndBox4f aBox = ZLayerBoundingBox (aLayerId,
464                                                  aCamera,
465                                                  aWinWidth,
466                                                  aWinHeight,
467                                                  theToIncludeAuxiliary);
468     combineBox (aResult, aBox);
469   }
470
471   return aResult;
472 }
473
474 // =======================================================================
475 // function : ConsiderZoomPersistenceObjects
476 // purpose  :
477 // =======================================================================
478 Standard_Real Graphic3d_CView::ConsiderZoomPersistenceObjects()
479 {
480   if (!IsDefined())
481   {
482     return 1.0;
483   }
484
485   Handle(Graphic3d_Camera) aCamera = Camera();
486   Standard_Integer aWinWidth  = 0;
487   Standard_Integer aWinHeight = 0;
488
489   Window()->Size (aWinWidth, aWinHeight);
490
491   Standard_Real aMaxCoef = 1.0;
492   for (Standard_Integer aLayer = 0; aLayer < THE_NB_DEFAULT_LAYERS; ++aLayer)
493   {
494     aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (THE_DEFAULT_LAYERS[aLayer], aCamera, aWinWidth, aWinHeight));
495   }
496
497   for (Standard_Integer aLayer = Graphic3d_ZLayerId_Default; aLayer <= ZLayerMax(); ++aLayer)
498   {
499     aMaxCoef = Max (aMaxCoef, considerZoomPersistenceObjects (aLayer, aCamera, aWinWidth, aWinHeight));
500   }
501
502   return aMaxCoef;
503 }
504
505 // =======================================================================
506 // function : MinMaxValues
507 // purpose  :
508 // =======================================================================
509 Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
510                                        const Standard_Boolean theToIgnoreInfiniteFlag) const
511 {
512   Bnd_Box aResult;
513   const Standard_Integer aViewId = Identification();
514
515   Handle(Graphic3d_Camera) aCamera = Camera();
516   Standard_Integer aWinWidth  = 0;
517   Standard_Integer aWinHeight = 0;
518   if (IsDefined())
519   {
520     Window()->Size (aWinWidth, aWinHeight);
521   }
522
523   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
524   {
525     const Handle(Graphic3d_Structure)& aStructure = aStructIter.Key();
526     if (aStructure->IsEmpty()
527     || !aStructure->CStructure()->IsVisible (aViewId))
528     {
529       continue;
530     }
531
532     // "FitAll" operation ignores object with transform persistence parameter
533     if (!aStructure->TransformPersistence().IsNull())
534     {
535       // Panning and 2d persistence apply changes to projection or/and its translation components.
536       // It makes them incompatible with z-fitting algorithm. Ignored by now.
537       if (!theToIgnoreInfiniteFlag
538        || aStructure->TransformPersistence()->IsTrihedronOr2d())
539       {
540         continue;
541       }
542     }
543
544     Bnd_Box aBox = aStructure->MinMaxValues (theToIgnoreInfiniteFlag);
545
546     if (aBox.IsWhole() || aBox.IsVoid())
547     {
548       continue;
549     }
550
551     if (!aStructure->TransformPersistence().IsNull())
552     {
553       const Graphic3d_Mat4d& aProjectionMat = aCamera->ProjectionMatrix();
554       const Graphic3d_Mat4d& aWorldViewMat  = aCamera->OrientationMatrix();
555       aStructure->TransformPersistence()->Apply (aCamera, aProjectionMat, aWorldViewMat, aWinWidth, aWinHeight, aBox);
556     }
557
558     // To prevent float overflow at camera parameters calculation and further
559     // rendering, bounding boxes with at least one vertex coordinate out of
560     // float range are skipped by view fit algorithms
561     if (Abs (aBox.CornerMax().X()) >= ShortRealLast() ||
562         Abs (aBox.CornerMax().Y()) >= ShortRealLast() ||
563         Abs (aBox.CornerMax().Z()) >= ShortRealLast() ||
564         Abs (aBox.CornerMin().X()) >= ShortRealLast() ||
565         Abs (aBox.CornerMin().Y()) >= ShortRealLast() ||
566         Abs (aBox.CornerMin().Z()) >= ShortRealLast())
567     {
568       continue;
569     }
570
571     aResult.Add (aBox);
572   }
573   return aResult;
574 }
575
576 // =======================================================================
577 // function : acceptDisplay
578 // purpose  :
579 // =======================================================================
580 Graphic3d_TypeOfAnswer Graphic3d_CView::acceptDisplay (const Graphic3d_TypeOfStructure theStructType) const
581 {
582   switch (theStructType)
583   {
584     case Graphic3d_TOS_ALL:
585     {
586       return Graphic3d_TOA_YES; // The structure accepts any type of view
587     }
588     case Graphic3d_TOS_SHADING:
589     {
590       return myVisualization == Graphic3d_TOV_SHADING
591            ? Graphic3d_TOA_YES
592            : Graphic3d_TOA_NO;
593     }
594     case Graphic3d_TOS_WIREFRAME:
595     {
596       return myVisualization == Graphic3d_TOV_WIREFRAME
597            ? Graphic3d_TOA_YES
598            : Graphic3d_TOA_NO;
599     }
600     case Graphic3d_TOS_COMPUTED:
601     {
602       return (myVisualization == Graphic3d_TOV_SHADING || myVisualization == Graphic3d_TOV_WIREFRAME)
603            ?  Graphic3d_TOA_COMPUTE
604            :  Graphic3d_TOA_NO;
605     }
606   }
607   return Graphic3d_TOA_NO;
608 }
609
610 // =======================================================================
611 // function : Compute
612 // purpose  :
613 // =======================================================================
614 void Graphic3d_CView::Compute()
615 {
616   // force HLRValidation to False on all structures calculated in the view
617   const Standard_Integer aNbCompStructs = myStructsComputed.Length();
618   for (Standard_Integer aStructIter = 1; aStructIter <= aNbCompStructs; ++aStructIter)
619   {
620     myStructsComputed.Value (aStructIter)->SetHLRValidation (Standard_False);
621   }
622
623   if (!ComputedMode())
624   {
625     return;
626   }
627
628   // Change of orientation or of projection type =>
629   // Remove structures that were calculated for the previous orientation.
630   // Recalculation of new structures.
631   NCollection_Sequence<Handle(Graphic3d_Structure)> aStructsSeq;
632   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
633   {
634     const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStructIter.Key()->Visual());
635     if (anAnswer == Graphic3d_TOA_COMPUTE)
636     {
637       aStructsSeq.Append (aStructIter.Key()); // if the structure was calculated, it is recalculated
638     }
639   }
640
641   for (NCollection_Sequence<Handle(Graphic3d_Structure)>::Iterator aStructIter (aStructsSeq); aStructIter.More(); aStructIter.Next())
642   {
643     Display (aStructIter.ChangeValue(), Aspect_TOU_WAIT);
644   }
645 }
646
647 // =======================================================================
648 // function : Clear
649 // purpose  :
650 // =======================================================================
651 void Graphic3d_CView::Clear (const Handle(Graphic3d_Structure)& theStructure,
652                              const Standard_Boolean theWithDestruction)
653 {
654   const Standard_Integer anIndex = IsComputed (theStructure);
655   if (anIndex != 0)
656   {
657     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.Value (anIndex);
658     aCompStruct->GraphicClear (theWithDestruction);
659     aCompStruct->SetHLRValidation (Standard_False);
660   }
661 }
662
663 // =======================================================================
664 // function : Connect
665 // purpose  :
666 // =======================================================================
667 void Graphic3d_CView::Connect (const Handle(Graphic3d_Structure)& theMother,
668                                const Handle(Graphic3d_Structure)& theDaughter)
669 {
670   Standard_Integer anIndexM = IsComputed (theMother);
671   Standard_Integer anIndexD = IsComputed (theDaughter);
672   if (anIndexM != 0
673    && anIndexD != 0)
674   {
675     const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
676     const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
677     aStructM->GraphicConnect (aStructD);
678   }
679 }
680
681 // =======================================================================
682 // function : Disconnect
683 // purpose  :
684 // =======================================================================
685 void Graphic3d_CView::Disconnect (const Handle(Graphic3d_Structure)& theMother,
686                                   const Handle(Graphic3d_Structure)& theDaughter)
687 {
688   Standard_Integer anIndexM = IsComputed (theMother);
689   Standard_Integer anIndexD = IsComputed (theDaughter);
690   if (anIndexM != 0
691    && anIndexD != 0)
692   {
693     const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
694     const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
695     aStructM->GraphicDisconnect (aStructD);
696   }
697 }
698
699 // =======================================================================
700 // function : Display
701 // purpose  :
702 // =======================================================================
703 void Graphic3d_CView::Display (const Handle(Graphic3d_Structure)& theStructure)
704 {
705   Display (theStructure, myStructureManager->UpdateMode());
706 }
707
708 // =======================================================================
709 // function : Display
710 // purpose  :
711 // =======================================================================
712 void Graphic3d_CView::Display (const Handle(Graphic3d_Structure)& theStructure,
713                                const Aspect_TypeOfUpdate theUpdateMode)
714 {
715   if (!IsActive())
716   {
717     return;
718   }
719
720   // If Display on a structure present in the list of calculated structures while it is not
721   // or more, of calculated type =>
722   // - removes it as well as the associated old computed
723   // THis happens when hlhsr becomes again of type e non computed after SetVisual.
724   Standard_Integer anIndex = IsComputed (theStructure);
725   if (anIndex != 0
726    && theStructure->Visual() != Graphic3d_TOS_COMPUTED)
727   {
728     myStructsToCompute.Remove (anIndex);
729     myStructsComputed .Remove (anIndex);
730     anIndex = 0;
731   }
732
733   Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStructure->Visual());
734   if (anAnswer == Graphic3d_TOA_NO)
735   {
736     return;
737   }
738
739   if (!ComputedMode())
740   {
741     anAnswer = Graphic3d_TOA_YES;
742   }
743
744   if (anAnswer == Graphic3d_TOA_YES)
745   {
746     if (!myStructsDisplayed.Add (theStructure))
747     {
748       return;
749     }
750
751     theStructure->CalculateBoundBox();
752     displayStructure (theStructure->CStructure(), theStructure->DisplayPriority());
753     Update (theUpdateMode, theStructure->GetZLayer());
754     return;
755   }
756   else if (anAnswer != Graphic3d_TOA_COMPUTE)
757   {
758     return;
759   }
760
761   if (anIndex != 0)
762   {
763     // Already computed, is COMPUTED still valid?
764     const Handle(Graphic3d_Structure)& anOldStruct = myStructsComputed.Value (anIndex);
765     if (anOldStruct->HLRValidation())
766     {
767       // Case COMPUTED valid, to be displayed
768       if (!myStructsDisplayed.Add (theStructure))
769       {
770         return;
771       }
772
773       displayStructure (anOldStruct->CStructure(), theStructure->DisplayPriority());
774       Update (theUpdateMode, anOldStruct->GetZLayer());
775       return;
776     }
777     else
778     {
779       // Case COMPUTED invalid
780       // Is there another valid representation?
781       // Find in the sequence of already calculated structures
782       // 1/ Structure having the same Owner as <AStructure>
783       // 2/ That is not <AStructure>
784       // 3/ The COMPUTED which of is valid
785       const Standard_Integer aNewIndex = HaveTheSameOwner (theStructure);
786       if (aNewIndex != 0)
787       {
788         // Case of COMPUTED invalid, WITH a valid of replacement; to be displayed
789         if (!myStructsDisplayed.Add (theStructure))
790         {
791           return;
792         }
793
794         const Handle(Graphic3d_Structure)& aNewStruct = myStructsComputed.Value (aNewIndex);
795         myStructsComputed.SetValue (anIndex, aNewStruct);
796         displayStructure (aNewStruct->CStructure(), theStructure->DisplayPriority());
797         Update (theUpdateMode, aNewStruct->GetZLayer());
798         return;
799       }
800       else
801       {
802         // Case COMPUTED invalid, WITHOUT a valid of replacement
803         // COMPUTED is removed if displayed
804         if (myStructsDisplayed.Contains (theStructure))
805         {
806           eraseStructure (anOldStruct->CStructure());
807         }
808       }
809     }
810   }
811
812   // Compute + Validation
813   Handle(Graphic3d_Structure) aStruct;
814   TColStd_Array2OfReal aTrsf (0, 3, 0, 3);
815   theStructure->Transform (aTrsf);
816   if (anIndex != 0)
817   {
818     TColStd_Array2OfReal anIdent (0, 3, 0, 3);
819     for (Standard_Integer ii = 0; ii <= 3; ++ii)
820     {
821       for (Standard_Integer jj = 0; jj <= 3; ++jj)
822       {
823         anIdent (ii, jj) = (ii == jj ? 1.0 : 0.0);
824       }
825     }
826
827     aStruct = myStructsComputed.Value (anIndex);
828     aStruct->SetTransform (anIdent, Graphic3d_TOC_REPLACE);
829     if (theStructure->IsTransformed())
830     {
831       theStructure->Compute (this, aTrsf, aStruct);
832     }
833     else
834     {
835       theStructure->Compute (this, aStruct);
836     }
837   }
838   else
839   {
840     aStruct = theStructure->IsTransformed()
841             ? theStructure->Compute (this, aTrsf)
842             : theStructure->Compute (this);
843   }
844
845   aStruct->SetHLRValidation (Standard_True);
846
847   // TOCOMPUTE and COMPUTED associated to sequences are added
848   myStructsToCompute.Append (theStructure);
849   myStructsComputed .Append (aStruct);
850
851   // The previous are removed if necessary
852   if (anIndex != 0)
853   {
854     myStructsToCompute.Remove (anIndex);
855     myStructsComputed .Remove (anIndex);
856   }
857
858   // Of which type will be the computed?
859   const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
860                                            && theStructure->ComputeVisual() != Graphic3d_TOS_SHADING;
861   const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
862                                            && theStructure->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
863   if (!toComputeShading && !toComputeWireframe)
864   {
865     anAnswer = Graphic3d_TOA_NO;
866   }
867   else
868   {
869     aStruct->SetVisual (toComputeWireframe ? Graphic3d_TOS_WIREFRAME : Graphic3d_TOS_SHADING);
870     anAnswer = acceptDisplay (aStruct->Visual());
871   }
872
873   if (theStructure->IsHighlighted())
874   {
875     aStruct->Highlight (Aspect_TOHM_COLOR, theStructure->HighlightColor(), Standard_False);
876   }
877
878   // It is displayed only if the calculated structure
879   // has a proper type corresponding to the one of the view.
880   if (anAnswer == Graphic3d_TOA_NO)
881   {
882     return;
883   }
884
885   myStructsDisplayed.Add (theStructure);
886   displayStructure (aStruct->CStructure(), theStructure->DisplayPriority());
887
888   Update (theUpdateMode, aStruct->GetZLayer());
889 }
890
891 // =======================================================================
892 // function : Erase
893 // purpose  :
894 // =======================================================================
895 void Graphic3d_CView::Erase (const Handle(Graphic3d_Structure)& theStructure)
896 {
897   Erase (theStructure, myStructureManager->UpdateMode());
898 }
899
900 // =======================================================================
901 // function : Erase
902 // purpose  :
903 // =======================================================================
904 void Graphic3d_CView::Erase (const Handle(Graphic3d_Structure)& theStructure,
905                              const Aspect_TypeOfUpdate theUpdateMode)
906 {
907   if (!IsDisplayed (theStructure))
908   {
909     return;
910   }
911
912   Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStructure->Visual());
913   if (!ComputedMode())
914   {
915     anAnswer = Graphic3d_TOA_YES;
916   }
917
918   if (anAnswer != Graphic3d_TOA_COMPUTE)
919   {
920     eraseStructure (theStructure->CStructure());
921   }
922   else if (anAnswer == Graphic3d_TOA_COMPUTE && myIsInComputedMode)
923   {
924     const Standard_Integer anIndex = IsComputed (theStructure);
925     if (anIndex != 0)
926     {
927       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
928       eraseStructure (aCompStruct->CStructure());
929     }
930   }
931   myStructsDisplayed.Remove (theStructure);
932   Update (theUpdateMode, theStructure->GetZLayer());
933 }
934
935 // =======================================================================
936 // function : Highlight
937 // purpose  :
938 // =======================================================================
939 void Graphic3d_CView::Highlight (const Handle(Graphic3d_Structure)& theStructure,
940                                  const Aspect_TypeOfHighlightMethod theMethod)
941 {
942   const Standard_Integer anIndex = IsComputed (theStructure);
943   if (anIndex != 0)
944   {
945     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
946     aCompStruct->Highlight (theMethod, theStructure->HighlightColor(), Standard_False);
947   }
948 }
949
950 // =======================================================================
951 // function : SetTransform
952 // purpose  :
953 // =======================================================================
954 void Graphic3d_CView::SetTransform (const Handle(Graphic3d_Structure)& theStructure,
955                                     const TColStd_Array2OfReal& theTrsf)
956 {
957   const Standard_Integer anIndex = IsComputed (theStructure);
958   if (anIndex != 0)
959   {
960     // Test is somewhat light !
961     // trsf is transferred only if it is :
962     // a translation
963     // a scale
964     if (theTrsf (0, 1) != 0.0 || theTrsf (0, 2) != 0.0
965      || theTrsf (1, 0) != 0.0 || theTrsf (1, 2) != 0.0
966      || theTrsf (2, 0) != 0.0 || theTrsf (2, 1) != 0.0)
967     {
968       ReCompute (theStructure);
969     }
970     else
971     {
972       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
973       aCompStruct->GraphicTransform (theTrsf);
974     }
975   }
976
977   theStructure->CalculateBoundBox();
978   if (!theStructure->IsMutable()
979    && !theStructure->CStructure()->IsForHighlight
980    && !theStructure->CStructure()->IsInfinite)
981   {
982     const Graphic3d_ZLayerId aLayerId = theStructure->GetZLayer();
983     InvalidateBVHData (aLayerId);
984   }
985 }
986
987 // =======================================================================
988 // function : UnHighlight
989 // purpose  :
990 // =======================================================================
991 void Graphic3d_CView::UnHighlight (const Handle(Graphic3d_Structure)& theStructure)
992 {
993   Standard_Integer anIndex = IsComputed (theStructure);
994   if (anIndex != 0)
995   {
996     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
997     aCompStruct->GraphicUnHighlight();
998   }
999 }
1000
1001 // ========================================================================
1002 // function : IsComputed
1003 // purpose  :
1004 // ========================================================================
1005 Standard_Boolean Graphic3d_CView::IsComputed (const Standard_Integer theStructId,
1006                                               Handle(Graphic3d_Structure)& theComputedStruct) const
1007 {
1008   theComputedStruct.Nullify();
1009   if (!ComputedMode())
1010     return Standard_False;
1011
1012   const Standard_Integer aNbStructs = myStructsToCompute.Length();
1013   for (Standard_Integer aStructIter = 1; aStructIter <= aNbStructs; ++aStructIter)
1014   {
1015     if (myStructsToCompute.Value (aStructIter)->Identification() == theStructId)
1016     {
1017       theComputedStruct = myStructsComputed (aStructIter);
1018       return Standard_True;
1019     }
1020   }
1021   return Standard_False;
1022 }
1023
1024 // =======================================================================
1025 // function : IsComputed
1026 // purpose  :
1027 // =======================================================================
1028 Standard_Integer Graphic3d_CView::IsComputed (const Handle(Graphic3d_Structure)& theStructure) const
1029 {
1030   const Standard_Integer aStructId  = theStructure->Identification();
1031   const Standard_Integer aNbStructs = myStructsToCompute.Length();
1032   for (Standard_Integer aStructIter = 1; aStructIter <= aNbStructs; ++aStructIter)
1033   {
1034     const Handle(Graphic3d_Structure)& aStruct = myStructsToCompute.Value (aStructIter);
1035     if (aStruct->Identification() == aStructId)
1036     {
1037       return aStructIter;
1038     }
1039   }
1040   return 0;
1041 }
1042
1043 // =======================================================================
1044 // function : IsDisplayed
1045 // purpose  :
1046 // =======================================================================
1047 Standard_Boolean Graphic3d_CView::IsDisplayed (const Handle(Graphic3d_Structure)& theStructure) const
1048 {
1049   return myStructsDisplayed.Contains (theStructure);
1050 }
1051
1052 // =======================================================================
1053 // function : ChangePriority
1054 // purpose  :
1055 // =======================================================================
1056 void Graphic3d_CView::ChangePriority (const Handle(Graphic3d_Structure)& theStructure,
1057                                       const Standard_Integer /*theOldPriority*/,
1058                                       const Standard_Integer theNewPriority)
1059 {
1060   if (!IsActive()
1061   ||  !IsDisplayed (theStructure))
1062   {
1063     return;
1064   }
1065
1066   if (!myIsInComputedMode)
1067   {
1068     changePriority (theStructure->CStructure(), theNewPriority);
1069     return;
1070   }
1071
1072   const Standard_Integer              anIndex  = IsComputed (theStructure);
1073   const Handle(Graphic3d_CStructure)& aCStruct = anIndex != 0
1074                                                ? myStructsComputed.Value (anIndex)->CStructure()
1075                                                : theStructure->CStructure();
1076
1077   changePriority (aCStruct, theNewPriority);
1078 }
1079
1080 // =======================================================================
1081 // function : ChangeZLayer
1082 // purpose  :
1083 // =======================================================================
1084 void Graphic3d_CView::ChangeZLayer (const Handle(Graphic3d_Structure)& theStructure,
1085                                     const Graphic3d_ZLayerId theLayerId)
1086 {
1087   if (!IsActive()
1088   ||  !IsDisplayed (theStructure))
1089   {
1090     return;
1091   }
1092
1093   if (!myIsInComputedMode)
1094   {
1095     changeZLayer (theStructure->CStructure(), theLayerId);
1096     return;
1097   }
1098
1099   const Standard_Integer       anIndex  = IsComputed (theStructure);
1100   Handle(Graphic3d_CStructure) aCStruct = anIndex != 0
1101                                        ? myStructsComputed.Value (anIndex)->CStructure()
1102                                        : theStructure->CStructure();
1103
1104   changeZLayer (aCStruct, theLayerId);
1105 }
1106
1107 // =======================================================================
1108 // function : HaveTheSameOwner
1109 // purpose  :
1110 // =======================================================================
1111 Standard_Integer Graphic3d_CView::HaveTheSameOwner (const Handle(Graphic3d_Structure)& theStructure) const
1112 {
1113   // Find in the sequence of already calculated structures
1114   // 1/ Structure with the same Owner as <AStructure>
1115   // 2/ Which is not <AStructure>
1116   // 3/ COMPUTED which of is valid
1117   const Standard_Integer aNbToCompStructs = myStructsToCompute.Length();
1118   for (Standard_Integer aStructIter = 1; aStructIter <= aNbToCompStructs; ++aStructIter)
1119   {
1120     const Handle(Graphic3d_Structure)& aStructToComp = myStructsToCompute.Value (aStructIter);
1121     if (aStructToComp->Owner()          == theStructure->Owner()
1122      && aStructToComp->Identification() != theStructure->Identification())
1123     {
1124       const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (aStructIter);
1125       if (aStructComp->HLRValidation())
1126       {
1127         return aStructIter;
1128       }
1129     }
1130   }
1131   return 0;
1132 }
1133
1134 // =======================================================================
1135 // function : CopySettings
1136 // purpose  :
1137 // =======================================================================
1138 void Graphic3d_CView::CopySettings (const Handle(Graphic3d_CView)& theOther)
1139 {
1140   ChangeRenderingParams() = theOther->RenderingParams();
1141   SetBackground            (theOther->Background());
1142   SetGradientBackground    (theOther->GradientBackground());
1143   SetBackgroundImage       (theOther->BackgroundImage());
1144   SetBackgroundImageStyle  (theOther->BackgroundImageStyle());
1145   SetTextureEnv            (theOther->TextureEnv());
1146   SetCullingEnabled        (theOther->IsCullingEnabled());
1147   SetShadingModel          (theOther->ShadingModel());
1148   SetBackfacingModel       (theOther->BackfacingModel());
1149   SetCamera                (new Graphic3d_Camera (theOther->Camera()));
1150   SetGLLightEnabled        (theOther->IsGLLightEnabled());
1151   SetLights                (theOther->Lights());
1152   SetClipPlanes            (theOther->ClipPlanes());
1153 }