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