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