0031458: Visualization - refine classes across Prs3d and StdPrs packages
[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;
222       aStruct->computeHLR (myCamera, aCompStruct);
223       aCompStruct->SetHLRValidation (Standard_True);
224
225       const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
226                                                 && aStruct->ComputeVisual() != Graphic3d_TOS_SHADING;
227       const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
228                                                 && aStruct->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
229       if (toComputeWireframe) aCompStruct->SetVisual (Graphic3d_TOS_WIREFRAME);
230       if (toComputeShading  ) aCompStruct->SetVisual (Graphic3d_TOS_SHADING);
231
232       if (aStruct->IsHighlighted())
233       {
234         aCompStruct->Highlight (aStruct->HighlightStyle(), Standard_False);
235       }
236
237       Standard_Boolean hasResult = Standard_False;
238       const Standard_Integer aNbToCompute = myStructsToCompute.Length();
239       const Standard_Integer aStructId    = aStruct->Identification();
240       for (Standard_Integer aToCompStructIter = 1; aToCompStructIter <= aNbToCompute; ++aToCompStructIter)
241       {
242         if (myStructsToCompute.Value (aToCompStructIter)->Identification() == aStructId)
243         {
244           hasResult = Standard_True;
245           myStructsComputed.ChangeValue (aToCompStructIter) = aCompStruct;
246           break;
247         }
248       }
249
250       if (!hasResult)
251       {
252         myStructsToCompute.Append (aStruct);
253         myStructsComputed .Append (aCompStruct);
254       }
255
256       aCompStruct->CalculateBoundBox();
257       eraseStructure   (aStruct->CStructure());
258       displayStructure (aCompStruct->CStructure(), aStruct->DisplayPriority());
259     }
260   }
261   Update();
262 }
263
264 // =======================================================================
265 // function : ReCompute
266 // purpose  :
267 // =======================================================================
268 void Graphic3d_CView::ReCompute (const Handle(Graphic3d_Structure)& theStruct)
269 {
270   theStruct->CalculateBoundBox();
271   if (!theStruct->IsMutable()
272    && !theStruct->CStructure()->IsForHighlight
273    && !theStruct->CStructure()->IsInfinite)
274   {
275     const Graphic3d_ZLayerId aLayerId = theStruct->GetZLayer();
276     InvalidateBVHData (aLayerId);
277   }
278
279   if (!ComputedMode()
280    || !IsActive()
281    || !theStruct->IsDisplayed())
282   {
283     return;
284   }
285
286   const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStruct->Visual());
287   if (anAnswer != Graphic3d_TOA_COMPUTE)
288   {
289     return;
290   }
291
292   const Standard_Integer anIndex = IsComputed (theStruct);
293   if (anIndex == 0)
294   {
295     return;
296   }
297
298   // compute + validation
299   Handle(Graphic3d_Structure) aCompStructOld = myStructsComputed.ChangeValue (anIndex);
300   Handle(Graphic3d_Structure) aCompStruct    = aCompStructOld;
301   aCompStruct->SetTransformation (Handle(TopLoc_Datum3D)());
302   theStruct->computeHLR (myCamera, 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(TopLoc_Datum3D)());
772   }
773   theStructure->computeHLR (myCamera, aStruct);
774
775   aStruct->SetHLRValidation (Standard_True);
776
777   // TOCOMPUTE and COMPUTED associated to sequences are added
778   myStructsToCompute.Append (theStructure);
779   myStructsComputed .Append (aStruct);
780
781   // The previous are removed if necessary
782   if (anIndex != 0)
783   {
784     myStructsToCompute.Remove (anIndex);
785     myStructsComputed .Remove (anIndex);
786   }
787
788   // Of which type will be the computed?
789   const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
790                                            && theStructure->ComputeVisual() != Graphic3d_TOS_SHADING;
791   const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
792                                            && theStructure->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
793   if (!toComputeShading && !toComputeWireframe)
794   {
795     anAnswer = Graphic3d_TOA_NO;
796   }
797   else
798   {
799     aStruct->SetVisual (toComputeWireframe ? Graphic3d_TOS_WIREFRAME : Graphic3d_TOS_SHADING);
800     anAnswer = acceptDisplay (aStruct->Visual());
801   }
802
803   if (theStructure->IsHighlighted())
804   {
805     aStruct->Highlight (theStructure->HighlightStyle(), Standard_False);
806   }
807
808   // It is displayed only if the calculated structure
809   // has a proper type corresponding to the one of the view.
810   if (anAnswer == Graphic3d_TOA_NO)
811   {
812     return;
813   }
814
815   myStructsDisplayed.Add (theStructure);
816   displayStructure (aStruct->CStructure(), theStructure->DisplayPriority());
817
818   Update (aStruct->GetZLayer());
819 }
820
821 // =======================================================================
822 // function : Erase
823 // purpose  :
824 // =======================================================================
825 void Graphic3d_CView::Erase (const Handle(Graphic3d_Structure)& theStructure)
826 {
827   if (!IsDisplayed (theStructure))
828   {
829     return;
830   }
831
832   const Graphic3d_TypeOfAnswer anAnswer = myIsInComputedMode ? acceptDisplay (theStructure->Visual()) : Graphic3d_TOA_YES;
833   if (anAnswer != Graphic3d_TOA_COMPUTE)
834   {
835     eraseStructure (theStructure->CStructure());
836   }
837
838   const Standard_Integer anIndex = !myStructsToCompute.IsEmpty() ? IsComputed (theStructure) : 0;
839   if (anIndex != 0)
840   {
841     if (anAnswer == Graphic3d_TOA_COMPUTE
842      && myIsInComputedMode)
843     {
844       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
845       eraseStructure (aCompStruct->CStructure());
846     }
847     myStructsComputed .Remove (anIndex);
848     myStructsToCompute.Remove (anIndex);
849   }
850
851   myStructsDisplayed.Remove (theStructure);
852   Update (theStructure->GetZLayer());
853 }
854
855 // =======================================================================
856 // function : Highlight
857 // purpose  :
858 // =======================================================================
859 void Graphic3d_CView::Highlight (const Handle(Graphic3d_Structure)& theStructure)
860 {
861   const Standard_Integer anIndex = IsComputed (theStructure);
862   if (anIndex != 0)
863   {
864     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
865     aCompStruct->Highlight (theStructure->HighlightStyle(), Standard_False);
866   }
867 }
868
869 // =======================================================================
870 // function : SetTransform
871 // purpose  :
872 // =======================================================================
873 void Graphic3d_CView::SetTransform (const Handle(Graphic3d_Structure)& theStructure,
874                                     const Handle(TopLoc_Datum3D)& theTrsf)
875 {
876   const Standard_Integer anIndex = IsComputed (theStructure);
877   if (anIndex != 0)
878   {
879     // Test is somewhat light !
880     // trsf is transferred only if it is :
881     // a translation
882     // a scale
883     if (!theTrsf.IsNull()
884       && (theTrsf->Form() == gp_Translation
885        || theTrsf->Form() == gp_Scale
886        || theTrsf->Form() == gp_CompoundTrsf))
887     {
888       ReCompute (theStructure);
889     }
890     else
891     {
892       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
893       aCompStruct->GraphicTransform (theTrsf);
894     }
895   }
896
897   theStructure->CalculateBoundBox();
898   if (!theStructure->IsMutable()
899    && !theStructure->CStructure()->IsForHighlight
900    && !theStructure->CStructure()->IsInfinite)
901   {
902     const Graphic3d_ZLayerId aLayerId = theStructure->GetZLayer();
903     InvalidateBVHData (aLayerId);
904   }
905 }
906
907 // =======================================================================
908 // function : UnHighlight
909 // purpose  :
910 // =======================================================================
911 void Graphic3d_CView::UnHighlight (const Handle(Graphic3d_Structure)& theStructure)
912 {
913   Standard_Integer anIndex = IsComputed (theStructure);
914   if (anIndex != 0)
915   {
916     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
917     aCompStruct->CStructure()->GraphicUnhighlight();
918   }
919 }
920
921 // ========================================================================
922 // function : IsComputed
923 // purpose  :
924 // ========================================================================
925 Standard_Boolean Graphic3d_CView::IsComputed (const Standard_Integer theStructId,
926                                               Handle(Graphic3d_Structure)& theComputedStruct) const
927 {
928   theComputedStruct.Nullify();
929   if (!ComputedMode())
930     return Standard_False;
931
932   const Standard_Integer aNbStructs = myStructsToCompute.Length();
933   for (Standard_Integer aStructIter = 1; aStructIter <= aNbStructs; ++aStructIter)
934   {
935     if (myStructsToCompute.Value (aStructIter)->Identification() == theStructId)
936     {
937       theComputedStruct = myStructsComputed (aStructIter);
938       return Standard_True;
939     }
940   }
941   return Standard_False;
942 }
943
944 // =======================================================================
945 // function : IsComputed
946 // purpose  :
947 // =======================================================================
948 Standard_Integer Graphic3d_CView::IsComputed (const Graphic3d_Structure* theStructure) const
949 {
950   const Standard_Integer aStructId  = theStructure->Identification();
951   Standard_Integer aStructIndex = 1;
952   for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructsToCompute); aStructIter.More(); aStructIter.Next(), ++aStructIndex)
953   {
954     const Handle(Graphic3d_Structure)& aStruct = aStructIter.Value();
955     if (aStruct->Identification() == aStructId)
956     {
957       return aStructIndex;
958     }
959   }
960   return 0;
961 }
962
963 // =======================================================================
964 // function : IsDisplayed
965 // purpose  :
966 // =======================================================================
967 Standard_Boolean Graphic3d_CView::IsDisplayed (const Handle(Graphic3d_Structure)& theStructure) const
968 {
969   return myStructsDisplayed.Contains (theStructure);
970 }
971
972 // =======================================================================
973 // function : ChangePriority
974 // purpose  :
975 // =======================================================================
976 void Graphic3d_CView::ChangePriority (const Handle(Graphic3d_Structure)& theStructure,
977                                       const Standard_Integer /*theOldPriority*/,
978                                       const Standard_Integer theNewPriority)
979 {
980   if (!IsActive()
981   ||  !IsDisplayed (theStructure))
982   {
983     return;
984   }
985
986   if (!myIsInComputedMode)
987   {
988     changePriority (theStructure->CStructure(), theNewPriority);
989     return;
990   }
991
992   const Standard_Integer              anIndex  = IsComputed (theStructure);
993   const Handle(Graphic3d_CStructure)& aCStruct = anIndex != 0
994                                                ? myStructsComputed.Value (anIndex)->CStructure()
995                                                : theStructure->CStructure();
996
997   changePriority (aCStruct, theNewPriority);
998 }
999
1000 // =======================================================================
1001 // function : ChangeZLayer
1002 // purpose  :
1003 // =======================================================================
1004 void Graphic3d_CView::ChangeZLayer (const Handle(Graphic3d_Structure)& theStructure,
1005                                     const Graphic3d_ZLayerId theLayerId)
1006 {
1007   if (!IsActive()
1008   ||  !IsDisplayed (theStructure))
1009   {
1010     return;
1011   }
1012
1013   if (!myIsInComputedMode)
1014   {
1015     changeZLayer (theStructure->CStructure(), theLayerId);
1016     return;
1017   }
1018
1019   const Standard_Integer       anIndex  = IsComputed (theStructure);
1020   Handle(Graphic3d_CStructure) aCStruct = anIndex != 0
1021                                        ? myStructsComputed.Value (anIndex)->CStructure()
1022                                        : theStructure->CStructure();
1023
1024   changeZLayer (aCStruct, theLayerId);
1025 }
1026
1027 // =======================================================================
1028 // function : HaveTheSameOwner
1029 // purpose  :
1030 // =======================================================================
1031 Standard_Integer Graphic3d_CView::HaveTheSameOwner (const Handle(Graphic3d_Structure)& theStructure) const
1032 {
1033   // Find in the sequence of already calculated structures
1034   // 1/ Structure with the same Owner as <AStructure>
1035   // 2/ Which is not <AStructure>
1036   // 3/ COMPUTED which of is valid
1037   const Standard_Integer aNbToCompStructs = myStructsToCompute.Length();
1038   for (Standard_Integer aStructIter = 1; aStructIter <= aNbToCompStructs; ++aStructIter)
1039   {
1040     const Handle(Graphic3d_Structure)& aStructToComp = myStructsToCompute.Value (aStructIter);
1041     if (aStructToComp->Owner()          == theStructure->Owner()
1042      && aStructToComp->Identification() != theStructure->Identification())
1043     {
1044       const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (aStructIter);
1045       if (aStructComp->HLRValidation())
1046       {
1047         return aStructIter;
1048       }
1049     }
1050   }
1051   return 0;
1052 }
1053
1054 // =======================================================================
1055 // function : CopySettings
1056 // purpose  :
1057 // =======================================================================
1058 void Graphic3d_CView::CopySettings (const Handle(Graphic3d_CView)& theOther)
1059 {
1060   ChangeRenderingParams() = theOther->RenderingParams();
1061   SetBackground            (theOther->Background());
1062   SetGradientBackground    (theOther->GradientBackground());
1063   SetBackgroundImage       (theOther->BackgroundImage());
1064   SetBackgroundImageStyle  (theOther->BackgroundImageStyle());
1065   SetTextureEnv            (theOther->TextureEnv());
1066   SetShadingModel          (theOther->ShadingModel());
1067   SetBackfacingModel       (theOther->BackfacingModel());
1068   SetCamera                (new Graphic3d_Camera (theOther->Camera()));
1069   SetLights                (theOther->Lights());
1070   SetClipPlanes            (theOther->ClipPlanes());
1071 }
1072
1073 // =======================================================================
1074 // function : SetShadingModel
1075 // purpose  :
1076 // =======================================================================
1077 void Graphic3d_CView::SetShadingModel (Graphic3d_TypeOfShadingModel theModel)
1078 {
1079   if (theModel == Graphic3d_TOSM_DEFAULT)
1080   {
1081     throw Standard_ProgramError ("Graphic3d_CView::SetShadingModel() - attempt to set invalid Shading Model!");
1082   }
1083
1084   myShadingModel = theModel;
1085 }