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