fe40e846d1033f60c28102c6d1d4844feb598622
[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 Standard_Integer aLayerId = theStruct->DisplayPriority();
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().Flags != Graphic3d_TMF_None)
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().Flags & Graphic3d_TMF_2d) ||
539           (aStructure->TransformPersistence().Flags & Graphic3d_TMF_PanPers) ||
540           (aStructure->TransformPersistence().Flags & Graphic3d_TMF_TriedronPers))
541       {
542         continue;
543       }
544     }
545
546     Bnd_Box aBox = aStructure->MinMaxValues (theToIgnoreInfiniteFlag);
547
548     if (aBox.IsWhole() || aBox.IsVoid())
549     {
550       continue;
551     }
552
553     if (aStructure->TransformPersistence().Flags != Graphic3d_TMF_None)
554     {
555       const Graphic3d_Mat4d& aProjectionMat = aCamera->ProjectionMatrix();
556       const Graphic3d_Mat4d& aWorldViewMat  = aCamera->OrientationMatrix();
557       aStructure->TransformPersistence().Apply (aCamera, aProjectionMat, aWorldViewMat, aWinWidth, aWinHeight, aBox);
558     }
559
560     // To prevent float overflow at camera parameters calculation and further
561     // rendering, bounding boxes with at least one vertex coordinate out of
562     // float range are skipped by view fit algorithms
563     if (Abs (aBox.CornerMax().X()) >= ShortRealLast() ||
564         Abs (aBox.CornerMax().Y()) >= ShortRealLast() ||
565         Abs (aBox.CornerMax().Z()) >= ShortRealLast() ||
566         Abs (aBox.CornerMin().X()) >= ShortRealLast() ||
567         Abs (aBox.CornerMin().Y()) >= ShortRealLast() ||
568         Abs (aBox.CornerMin().Z()) >= ShortRealLast())
569     {
570       continue;
571     }
572
573     aResult.Add (aBox);
574   }
575   return aResult;
576 }
577
578 // =======================================================================
579 // function : acceptDisplay
580 // purpose  :
581 // =======================================================================
582 Graphic3d_TypeOfAnswer Graphic3d_CView::acceptDisplay (const Graphic3d_TypeOfStructure theStructType) const
583 {
584   switch (theStructType)
585   {
586     case Graphic3d_TOS_ALL:
587     {
588       return Graphic3d_TOA_YES; // The structure accepts any type of view
589     }
590     case Graphic3d_TOS_SHADING:
591     {
592       return myVisualization == Graphic3d_TOV_SHADING
593            ? Graphic3d_TOA_YES
594            : Graphic3d_TOA_NO;
595     }
596     case Graphic3d_TOS_WIREFRAME:
597     {
598       return myVisualization == Graphic3d_TOV_WIREFRAME
599            ? Graphic3d_TOA_YES
600            : Graphic3d_TOA_NO;
601     }
602     case Graphic3d_TOS_COMPUTED:
603     {
604       return (myVisualization == Graphic3d_TOV_SHADING || myVisualization == Graphic3d_TOV_WIREFRAME)
605            ?  Graphic3d_TOA_COMPUTE
606            :  Graphic3d_TOA_NO;
607     }
608   }
609   return Graphic3d_TOA_NO;
610 }
611
612 // =======================================================================
613 // function : Compute
614 // purpose  :
615 // =======================================================================
616 void Graphic3d_CView::Compute()
617 {
618   // force HLRValidation to False on all structures calculated in the view
619   const Standard_Integer aNbCompStructs = myStructsComputed.Length();
620   for (Standard_Integer aStructIter = 1; aStructIter <= aNbCompStructs; ++aStructIter)
621   {
622     myStructsComputed.Value (aStructIter)->SetHLRValidation (Standard_False);
623   }
624
625   if (!ComputedMode())
626   {
627     return;
628   }
629
630   // Change of orientation or of projection type =>
631   // Remove structures that were calculated for the previous orientation.
632   // Recalculation of new structures.
633   NCollection_Sequence<Handle(Graphic3d_Structure)> aStructsSeq;
634   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
635   {
636     const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStructIter.Key()->Visual());
637     if (anAnswer == Graphic3d_TOA_COMPUTE)
638     {
639       aStructsSeq.Append (aStructIter.Key()); // if the structure was calculated, it is recalculated
640     }
641   }
642
643   for (NCollection_Sequence<Handle(Graphic3d_Structure)>::Iterator aStructIter (aStructsSeq); aStructIter.More(); aStructIter.Next())
644   {
645     Display (aStructIter.ChangeValue(), Aspect_TOU_WAIT);
646   }
647 }
648
649 // =======================================================================
650 // function : Clear
651 // purpose  :
652 // =======================================================================
653 void Graphic3d_CView::Clear (const Handle(Graphic3d_Structure)& theStructure,
654                              const Standard_Boolean theWithDestruction)
655 {
656   const Standard_Integer anIndex = IsComputed (theStructure);
657   if (anIndex != 0)
658   {
659     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.Value (anIndex);
660     aCompStruct->GraphicClear (theWithDestruction);
661     aCompStruct->SetHLRValidation (Standard_False);
662   }
663 }
664
665 // =======================================================================
666 // function : Connect
667 // purpose  :
668 // =======================================================================
669 void Graphic3d_CView::Connect (const Handle(Graphic3d_Structure)& theMother,
670                                const Handle(Graphic3d_Structure)& theDaughter)
671 {
672   Standard_Integer anIndexM = IsComputed (theMother);
673   Standard_Integer anIndexD = IsComputed (theDaughter);
674   if (anIndexM != 0
675    && anIndexD != 0)
676   {
677     const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
678     const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
679     aStructM->GraphicConnect (aStructD);
680   }
681 }
682
683 // =======================================================================
684 // function : Disconnect
685 // purpose  :
686 // =======================================================================
687 void Graphic3d_CView::Disconnect (const Handle(Graphic3d_Structure)& theMother,
688                                   const Handle(Graphic3d_Structure)& theDaughter)
689 {
690   Standard_Integer anIndexM = IsComputed (theMother);
691   Standard_Integer anIndexD = IsComputed (theDaughter);
692   if (anIndexM != 0
693    && anIndexD != 0)
694   {
695     const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
696     const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
697     aStructM->GraphicDisconnect (aStructD);
698   }
699 }
700
701 // =======================================================================
702 // function : Display
703 // purpose  :
704 // =======================================================================
705 void Graphic3d_CView::Display (const Handle(Graphic3d_Structure)& theStructure)
706 {
707   Display (theStructure, myStructureManager->UpdateMode());
708 }
709
710 // =======================================================================
711 // function : Display
712 // purpose  :
713 // =======================================================================
714 void Graphic3d_CView::Display (const Handle(Graphic3d_Structure)& theStructure,
715                                const Aspect_TypeOfUpdate theUpdateMode)
716 {
717   if (!IsActive())
718   {
719     return;
720   }
721
722   // If Display on a structure present in the list of calculated structures while it is not
723   // or more, of calculated type =>
724   // - removes it as well as the associated old computed
725   // THis happens when hlhsr becomes again of type e non computed after SetVisual.
726   Standard_Integer anIndex = IsComputed (theStructure);
727   if (anIndex != 0
728    && theStructure->Visual() != Graphic3d_TOS_COMPUTED)
729   {
730     myStructsToCompute.Remove (anIndex);
731     myStructsComputed .Remove (anIndex);
732     anIndex = 0;
733   }
734
735   Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStructure->Visual());
736   if (anAnswer == Graphic3d_TOA_NO)
737   {
738     return;
739   }
740
741   if (!ComputedMode())
742   {
743     anAnswer = Graphic3d_TOA_YES;
744   }
745
746   if (anAnswer == Graphic3d_TOA_YES)
747   {
748     if (!myStructsDisplayed.Add (theStructure))
749     {
750       return;
751     }
752
753     theStructure->CalculateBoundBox();
754     displayStructure (theStructure->CStructure(), theStructure->DisplayPriority());
755     Update (theUpdateMode, theStructure->GetZLayer());
756     return;
757   }
758   else if (anAnswer != Graphic3d_TOA_COMPUTE)
759   {
760     return;
761   }
762
763   if (anIndex != 0)
764   {
765     // Already computed, is COMPUTED still valid?
766     const Handle(Graphic3d_Structure)& anOldStruct = myStructsComputed.Value (anIndex);
767     if (anOldStruct->HLRValidation())
768     {
769       // Case COMPUTED valid, to be displayed
770       if (!myStructsDisplayed.Add (theStructure))
771       {
772         return;
773       }
774
775       displayStructure (anOldStruct->CStructure(), theStructure->DisplayPriority());
776       Update (theUpdateMode, anOldStruct->GetZLayer());
777       return;
778     }
779     else
780     {
781       // Case COMPUTED invalid
782       // Is there another valid representation?
783       // Find in the sequence of already calculated structures
784       // 1/ Structure having the same Owner as <AStructure>
785       // 2/ That is not <AStructure>
786       // 3/ The COMPUTED which of is valid
787       const Standard_Integer aNewIndex = HaveTheSameOwner (theStructure);
788       if (aNewIndex != 0)
789       {
790         // Case of COMPUTED invalid, WITH a valid of replacement; to be displayed
791         if (!myStructsDisplayed.Add (theStructure))
792         {
793           return;
794         }
795
796         const Handle(Graphic3d_Structure)& aNewStruct = myStructsComputed.Value (aNewIndex);
797         myStructsComputed.SetValue (anIndex, aNewStruct);
798         displayStructure (aNewStruct->CStructure(), theStructure->DisplayPriority());
799         Update (theUpdateMode, aNewStruct->GetZLayer());
800         return;
801       }
802       else
803       {
804         // Case COMPUTED invalid, WITHOUT a valid of replacement
805         // COMPUTED is removed if displayed
806         if (myStructsDisplayed.Contains (theStructure))
807         {
808           eraseStructure (anOldStruct->CStructure());
809         }
810       }
811     }
812   }
813
814   // Compute + Validation
815   Handle(Graphic3d_Structure) aStruct;
816   TColStd_Array2OfReal aTrsf (0, 3, 0, 3);
817   theStructure->Transform (aTrsf);
818   if (anIndex != 0)
819   {
820     TColStd_Array2OfReal anIdent (0, 3, 0, 3);
821     for (Standard_Integer ii = 0; ii <= 3; ++ii)
822     {
823       for (Standard_Integer jj = 0; jj <= 3; ++jj)
824       {
825         anIdent (ii, jj) = (ii == jj ? 1.0 : 0.0);
826       }
827     }
828
829     aStruct = myStructsComputed.Value (anIndex);
830     aStruct->SetTransform (anIdent, Graphic3d_TOC_REPLACE);
831     if (theStructure->IsTransformed())
832     {
833       theStructure->Compute (this, aTrsf, aStruct);
834     }
835     else
836     {
837       theStructure->Compute (this, aStruct);
838     }
839   }
840   else
841   {
842     aStruct = theStructure->IsTransformed()
843             ? theStructure->Compute (this, aTrsf)
844             : theStructure->Compute (this);
845   }
846
847   aStruct->SetHLRValidation (Standard_True);
848
849   // TOCOMPUTE and COMPUTED associated to sequences are added
850   myStructsToCompute.Append (theStructure);
851   myStructsComputed .Append (aStruct);
852
853   // The previous are removed if necessary
854   if (anIndex != 0)
855   {
856     myStructsToCompute.Remove (anIndex);
857     myStructsComputed .Remove (anIndex);
858   }
859
860   // Of which type will be the computed?
861   const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
862                                            && theStructure->ComputeVisual() != Graphic3d_TOS_SHADING;
863   const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
864                                            && theStructure->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
865   if (!toComputeShading && !toComputeWireframe)
866   {
867     anAnswer = Graphic3d_TOA_NO;
868   }
869   else
870   {
871     aStruct->SetVisual (toComputeWireframe ? Graphic3d_TOS_WIREFRAME : Graphic3d_TOS_SHADING);
872     anAnswer = acceptDisplay (aStruct->Visual());
873   }
874
875   if (theStructure->IsHighlighted())
876   {
877     aStruct->Highlight (Aspect_TOHM_COLOR, theStructure->HighlightColor(), Standard_False);
878   }
879
880   // It is displayed only if the calculated structure
881   // has a proper type corresponding to the one of the view.
882   if (anAnswer == Graphic3d_TOA_NO)
883   {
884     return;
885   }
886
887   myStructsDisplayed.Add (theStructure);
888   displayStructure (aStruct->CStructure(), theStructure->DisplayPriority());
889
890   Update (theUpdateMode, aStruct->GetZLayer());
891 }
892
893 // =======================================================================
894 // function : Erase
895 // purpose  :
896 // =======================================================================
897 void Graphic3d_CView::Erase (const Handle(Graphic3d_Structure)& theStructure)
898 {
899   Erase (theStructure, myStructureManager->UpdateMode());
900 }
901
902 // =======================================================================
903 // function : Erase
904 // purpose  :
905 // =======================================================================
906 void Graphic3d_CView::Erase (const Handle(Graphic3d_Structure)& theStructure,
907                              const Aspect_TypeOfUpdate theUpdateMode)
908 {
909   if (!IsDisplayed (theStructure))
910   {
911     return;
912   }
913
914   Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStructure->Visual());
915   if (!ComputedMode())
916   {
917     anAnswer = Graphic3d_TOA_YES;
918   }
919
920   if (anAnswer != Graphic3d_TOA_COMPUTE)
921   {
922     eraseStructure (theStructure->CStructure());
923   }
924   else if (anAnswer == Graphic3d_TOA_COMPUTE && myIsInComputedMode)
925   {
926     const Standard_Integer anIndex = IsComputed (theStructure);
927     if (anIndex != 0)
928     {
929       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
930       eraseStructure (aCompStruct->CStructure());
931     }
932   }
933   myStructsDisplayed.Remove (theStructure);
934   Update (theUpdateMode, theStructure->GetZLayer());
935 }
936
937 // =======================================================================
938 // function : Highlight
939 // purpose  :
940 // =======================================================================
941 void Graphic3d_CView::Highlight (const Handle(Graphic3d_Structure)& theStructure,
942                                  const Aspect_TypeOfHighlightMethod theMethod)
943 {
944   const Standard_Integer anIndex = IsComputed (theStructure);
945   if (anIndex != 0)
946   {
947     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
948     aCompStruct->Highlight (theMethod, theStructure->HighlightColor(), Standard_False);
949   }
950 }
951
952 // =======================================================================
953 // function : SetTransform
954 // purpose  :
955 // =======================================================================
956 void Graphic3d_CView::SetTransform (const Handle(Graphic3d_Structure)& theStructure,
957                                     const TColStd_Array2OfReal& theTrsf)
958 {
959   const Standard_Integer anIndex = IsComputed (theStructure);
960   if (anIndex != 0)
961   {
962     // Test is somewhat light !
963     // trsf is transferred only if it is :
964     // a translation
965     // a scale
966     if (theTrsf (0, 1) != 0.0 || theTrsf (0, 2) != 0.0
967      || theTrsf (1, 0) != 0.0 || theTrsf (1, 2) != 0.0
968      || theTrsf (2, 0) != 0.0 || theTrsf (2, 1) != 0.0)
969     {
970       ReCompute (theStructure);
971     }
972     else
973     {
974       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
975       aCompStruct->GraphicTransform (theTrsf);
976     }
977   }
978
979   theStructure->CalculateBoundBox();
980   if (!theStructure->IsMutable()
981    && !theStructure->CStructure()->IsForHighlight
982    && !theStructure->CStructure()->IsInfinite)
983   {
984     const Graphic3d_ZLayerId aLayerId = theStructure->GetZLayer();
985     InvalidateBVHData (aLayerId);
986   }
987 }
988
989 // =======================================================================
990 // function : UnHighlight
991 // purpose  :
992 // =======================================================================
993 void Graphic3d_CView::UnHighlight (const Handle(Graphic3d_Structure)& theStructure)
994 {
995   Standard_Integer anIndex = IsComputed (theStructure);
996   if (anIndex != 0)
997   {
998     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
999     aCompStruct->GraphicUnHighlight();
1000   }
1001 }
1002
1003 // ========================================================================
1004 // function : IsComputed
1005 // purpose  :
1006 // ========================================================================
1007 Standard_Boolean Graphic3d_CView::IsComputed (const Standard_Integer theStructId,
1008                                               Handle(Graphic3d_Structure)& theComputedStruct) const
1009 {
1010   theComputedStruct.Nullify();
1011   if (!ComputedMode())
1012     return Standard_False;
1013
1014   const Standard_Integer aNbStructs = myStructsToCompute.Length();
1015   for (Standard_Integer aStructIter = 1; aStructIter <= aNbStructs; ++aStructIter)
1016   {
1017     if (myStructsToCompute.Value (aStructIter)->Identification() == theStructId)
1018     {
1019       theComputedStruct = myStructsComputed (aStructIter);
1020       return Standard_True;
1021     }
1022   }
1023   return Standard_False;
1024 }
1025
1026 // =======================================================================
1027 // function : IsComputed
1028 // purpose  :
1029 // =======================================================================
1030 Standard_Integer Graphic3d_CView::IsComputed (const Handle(Graphic3d_Structure)& theStructure) const
1031 {
1032   const Standard_Integer aStructId  = theStructure->Identification();
1033   const Standard_Integer aNbStructs = myStructsToCompute.Length();
1034   for (Standard_Integer aStructIter = 1; aStructIter <= aNbStructs; ++aStructIter)
1035   {
1036     const Handle(Graphic3d_Structure)& aStruct = myStructsToCompute.Value (aStructIter);
1037     if (aStruct->Identification() == aStructId)
1038     {
1039       return aStructIter;
1040     }
1041   }
1042   return 0;
1043 }
1044
1045 // =======================================================================
1046 // function : IsDisplayed
1047 // purpose  :
1048 // =======================================================================
1049 Standard_Boolean Graphic3d_CView::IsDisplayed (const Handle(Graphic3d_Structure)& theStructure) const
1050 {
1051   return myStructsDisplayed.Contains (theStructure);
1052 }
1053
1054 // =======================================================================
1055 // function : ChangePriority
1056 // purpose  :
1057 // =======================================================================
1058 void Graphic3d_CView::ChangePriority (const Handle(Graphic3d_Structure)& theStructure,
1059                                       const Standard_Integer /*theOldPriority*/,
1060                                       const Standard_Integer theNewPriority)
1061 {
1062   if (!IsActive()
1063   ||  !IsDisplayed (theStructure))
1064   {
1065     return;
1066   }
1067
1068   if (!myIsInComputedMode)
1069   {
1070     changePriority (theStructure->CStructure(), theNewPriority);
1071     return;
1072   }
1073
1074   const Standard_Integer              anIndex  = IsComputed (theStructure);
1075   const Handle(Graphic3d_CStructure)& aCStruct = anIndex != 0
1076                                                ? myStructsComputed.Value (anIndex)->CStructure()
1077                                                : theStructure->CStructure();
1078
1079   changePriority (aCStruct, theNewPriority);
1080 }
1081
1082 // =======================================================================
1083 // function : ChangeZLayer
1084 // purpose  :
1085 // =======================================================================
1086 void Graphic3d_CView::ChangeZLayer (const Handle(Graphic3d_Structure)& theStructure,
1087                                     const Graphic3d_ZLayerId theLayerId)
1088 {
1089   if (!IsActive()
1090   ||  !IsDisplayed (theStructure))
1091   {
1092     return;
1093   }
1094
1095   if (!myIsInComputedMode)
1096   {
1097     changeZLayer (theStructure->CStructure(), theLayerId);
1098     return;
1099   }
1100
1101   const Standard_Integer       anIndex  = IsComputed (theStructure);
1102   Handle(Graphic3d_CStructure) aCStruct = anIndex != 0
1103                                        ? myStructsComputed.Value (anIndex)->CStructure()
1104                                        : theStructure->CStructure();
1105
1106   changeZLayer (aCStruct, theLayerId);
1107 }
1108
1109 // =======================================================================
1110 // function : HaveTheSameOwner
1111 // purpose  :
1112 // =======================================================================
1113 Standard_Integer Graphic3d_CView::HaveTheSameOwner (const Handle(Graphic3d_Structure)& theStructure) const
1114 {
1115   // Find in the sequence of already calculated structures
1116   // 1/ Structure with the same Owner as <AStructure>
1117   // 2/ Which is not <AStructure>
1118   // 3/ COMPUTED which of is valid
1119   const Standard_Integer aNbToCompStructs = myStructsToCompute.Length();
1120   for (Standard_Integer aStructIter = 1; aStructIter <= aNbToCompStructs; ++aStructIter)
1121   {
1122     const Handle(Graphic3d_Structure)& aStructToComp = myStructsToCompute.Value (aStructIter);
1123     if (aStructToComp->Owner()          == theStructure->Owner()
1124      && aStructToComp->Identification() != theStructure->Identification())
1125     {
1126       const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (aStructIter);
1127       if (aStructComp->HLRValidation())
1128       {
1129         return aStructIter;
1130       }
1131     }
1132   }
1133   return 0;
1134 }
1135
1136 // =======================================================================
1137 // function : CopySettings
1138 // purpose  :
1139 // =======================================================================
1140 void Graphic3d_CView::CopySettings (const Handle(Graphic3d_CView)& theOther)
1141 {
1142   ChangeRenderingParams() = theOther->RenderingParams();
1143   SetBackground            (theOther->Background());
1144   SetGradientBackground    (theOther->GradientBackground());
1145   SetBackgroundImage       (theOther->BackgroundImage());
1146   SetBackgroundImageStyle  (theOther->BackgroundImageStyle());
1147   SetTextureEnv            (theOther->TextureEnv());
1148   SetCullingEnabled        (theOther->IsCullingEnabled());
1149   SetShadingModel          (theOther->ShadingModel());
1150   SetBackfacingModel       (theOther->BackfacingModel());
1151   SetCamera                (new Graphic3d_Camera (theOther->Camera()));
1152   SetGLLightEnabled        (theOther->IsGLLightEnabled());
1153   SetLights                (theOther->Lights());
1154   SetClipPlanes            (theOther->ClipPlanes());
1155 }