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