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