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 <Aspect_OpenVRSession.hxx>
17 #include <Graphic3d_Layer.hxx>
18 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
19 #include <Graphic3d_StructureManager.hxx>
20 
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CView,Graphic3d_DataStructureManager)21 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CView,Graphic3d_DataStructureManager)
22 
23 //=======================================================================
24 //function : Constructor
25 //purpose  :
26 //=======================================================================
27 Graphic3d_CView::Graphic3d_CView (const Handle(Graphic3d_StructureManager)& theMgr)
28 : myBgColor                (Quantity_NOC_BLACK),
29   myBackgroundType         (Graphic3d_TOB_NONE),
30   myStructureManager       (theMgr),
31   myCamera                 (new Graphic3d_Camera()),
32   myHiddenObjects          (new Graphic3d_NMapOfTransient()),
33   myIsInComputedMode       (Standard_False),
34   myIsActive               (Standard_False),
35   myIsRemoved              (Standard_False),
36   myBackfacing             (Graphic3d_TypeOfBackfacingModel_Auto),
37   myVisualization          (Graphic3d_TOV_WIREFRAME),
38   myUnitFactor             (1.0)
39 {
40   myId = myStructureManager->Identification (this);
41 }
42 
43 //=======================================================================
44 //function : Destructor
45 //purpose  :
46 //=======================================================================
~Graphic3d_CView()47 Graphic3d_CView::~Graphic3d_CView()
48 {
49   myXRSession.Nullify();
50   if (!IsRemoved())
51   {
52     myStructureManager->UnIdentification (this);
53   }
54 }
55 
56 // =======================================================================
57 // function : Activate
58 // purpose  :
59 // =======================================================================
Activate()60 void Graphic3d_CView::Activate()
61 {
62   if (!IsActive())
63   {
64     myIsActive = Standard_True;
65 
66     // Activation of a new view =>
67     // Display structures that can be displayed in this new view.
68     // All structures with status
69     // Displayed in ViewManager are returned and displayed in
70     // the view directly, if the structure is not already
71     // displayed and if the view accepts it in its context.
72     Graphic3d_MapOfStructure aDisplayedStructs;
73     myStructureManager->DisplayedStructures (aDisplayedStructs);
74     for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aDisplayedStructs); aStructIter.More(); aStructIter.Next())
75     {
76       const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
77       if (IsDisplayed (aStruct))
78       {
79         continue;
80       }
81 
82       // If the structure can be displayed in the new context of the view, it is displayed.
83       const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
84       if (anAnswer == Graphic3d_TOA_YES
85        || anAnswer == Graphic3d_TOA_COMPUTE)
86       {
87         Display (aStruct);
88       }
89     }
90   }
91 
92   Update();
93 }
94 
95 // =======================================================================
96 // function : Deactivate
97 // purpose  :
98 // =======================================================================
Deactivate()99 void Graphic3d_CView::Deactivate()
100 {
101   if (IsActive())
102   {
103     // Deactivation of a view =>
104     // Removal of structures displayed in this view.
105     // All structures with status
106     // Displayed in ViewManager are returned and removed from
107     // the view directly, if the structure is not already
108     // displayed and if the view accepts it in its context.
109     Graphic3d_MapOfStructure aDisplayedStructs;
110     myStructureManager->DisplayedStructures (aDisplayedStructs);
111     for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aDisplayedStructs); aStructIter.More(); aStructIter.Next())
112     {
113       const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
114       if (!IsDisplayed (aStruct))
115       {
116         continue;
117       }
118 
119       const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
120       if (anAnswer == Graphic3d_TOA_YES
121        || anAnswer == Graphic3d_TOA_COMPUTE)
122       {
123         Erase (aStruct);
124       }
125     }
126 
127     Update();
128     myIsActive = Standard_False;
129   }
130 }
131 
132 // ========================================================================
133 // function : Remove
134 // purpose  :
135 // ========================================================================
Remove()136 void Graphic3d_CView::Remove()
137 {
138   if (IsRemoved())
139   {
140     return;
141   }
142 
143   Graphic3d_MapOfStructure aDisplayedStructs (myStructsDisplayed);
144 
145   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aDisplayedStructs); aStructIter.More(); aStructIter.Next())
146   {
147     Erase (aStructIter.Value());
148   }
149 
150   myStructsToCompute.Clear();
151   myStructsComputed .Clear();
152   myStructsDisplayed.Clear();
153 
154   if (!myStructureManager.IsNull())
155   {
156     myStructureManager->UnIdentification (this);
157   }
158 
159   myIsActive  = Standard_False;
160   myIsRemoved = Standard_True;
161 }
162 
163 // ========================================================================
164 // function : SetComputedMode
165 // purpose  :
166 // ========================================================================
SetComputedMode(const Standard_Boolean theMode)167 void Graphic3d_CView::SetComputedMode (const Standard_Boolean theMode)
168 {
169   if (( theMode &&  myIsInComputedMode)
170    || (!theMode && !myIsInComputedMode))
171   {
172     return;
173   }
174 
175   myIsInComputedMode = theMode;
176   if (!myIsInComputedMode)
177   {
178     for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
179     {
180       const Handle(Graphic3d_Structure)& aStruct  = aStructIter.Key();
181       const Graphic3d_TypeOfAnswer        anAnswer = acceptDisplay (aStruct->Visual());
182       if (anAnswer != Graphic3d_TOA_COMPUTE)
183       {
184         continue;
185       }
186 
187       const Standard_Integer anIndex = IsComputed (aStruct);
188       if (anIndex != 0)
189       {
190         const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (anIndex);
191         eraseStructure   (aStructComp->CStructure());
192         displayStructure (aStruct->CStructure(), aStruct->DisplayPriority());
193         Update (aStruct->GetZLayer());
194       }
195     }
196     return;
197   }
198 
199   for (Graphic3d_MapOfStructure::Iterator aDispStructIter (myStructsDisplayed); aDispStructIter.More(); aDispStructIter.Next())
200   {
201     Handle(Graphic3d_Structure) aStruct  = aDispStructIter.Key();
202     const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
203     if (anAnswer != Graphic3d_TOA_COMPUTE)
204     {
205       continue;
206     }
207 
208     const Standard_Integer anIndex = IsComputed (aStruct);
209     if (anIndex != 0)
210     {
211       eraseStructure   (aStruct->CStructure());
212       displayStructure (myStructsComputed.Value (anIndex)->CStructure(), aStruct->DisplayPriority());
213 
214       Display (aStruct);
215       if (aStruct->IsHighlighted())
216       {
217         const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.Value (anIndex);
218         if (!aCompStruct->IsHighlighted())
219         {
220           aCompStruct->Highlight (aStruct->HighlightStyle(), Standard_False);
221         }
222       }
223     }
224     else
225     {
226       Handle(Graphic3d_Structure) aCompStruct;
227       aStruct->computeHLR (myCamera, aCompStruct);
228       if (aCompStruct.IsNull())
229       {
230         continue;
231       }
232       aCompStruct->SetHLRValidation (Standard_True);
233 
234       const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
235                                                 && aStruct->ComputeVisual() != Graphic3d_TOS_SHADING;
236       const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
237                                                 && aStruct->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
238       if (toComputeWireframe) aCompStruct->SetVisual (Graphic3d_TOS_WIREFRAME);
239       if (toComputeShading  ) aCompStruct->SetVisual (Graphic3d_TOS_SHADING);
240 
241       if (aStruct->IsHighlighted())
242       {
243         aCompStruct->Highlight (aStruct->HighlightStyle(), Standard_False);
244       }
245 
246       Standard_Boolean hasResult = Standard_False;
247       const Standard_Integer aNbToCompute = myStructsToCompute.Length();
248       const Standard_Integer aStructId    = aStruct->Identification();
249       for (Standard_Integer aToCompStructIter = 1; aToCompStructIter <= aNbToCompute; ++aToCompStructIter)
250       {
251         if (myStructsToCompute.Value (aToCompStructIter)->Identification() == aStructId)
252         {
253           hasResult = Standard_True;
254           myStructsComputed.ChangeValue (aToCompStructIter) = aCompStruct;
255           break;
256         }
257       }
258 
259       if (!hasResult)
260       {
261         myStructsToCompute.Append (aStruct);
262         myStructsComputed .Append (aCompStruct);
263       }
264 
265       aCompStruct->CalculateBoundBox();
266       eraseStructure   (aStruct->CStructure());
267       displayStructure (aCompStruct->CStructure(), aStruct->DisplayPriority());
268     }
269   }
270   Update();
271 }
272 
273 // =======================================================================
274 // function : ReCompute
275 // purpose  :
276 // =======================================================================
ReCompute(const Handle (Graphic3d_Structure)& theStruct)277 void Graphic3d_CView::ReCompute (const Handle(Graphic3d_Structure)& theStruct)
278 {
279   theStruct->CalculateBoundBox();
280   if (!theStruct->IsMutable()
281    && !theStruct->CStructure()->IsForHighlight
282    && !theStruct->CStructure()->IsInfinite)
283   {
284     const Graphic3d_ZLayerId aLayerId = theStruct->GetZLayer();
285     InvalidateBVHData (aLayerId);
286   }
287 
288   if (!ComputedMode()
289    || !IsActive()
290    || !theStruct->IsDisplayed())
291   {
292     return;
293   }
294 
295   const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStruct->Visual());
296   if (anAnswer != Graphic3d_TOA_COMPUTE)
297   {
298     return;
299   }
300 
301   const Standard_Integer anIndex = IsComputed (theStruct);
302   if (anIndex == 0)
303   {
304     return;
305   }
306 
307   // compute + validation
308   Handle(Graphic3d_Structure) aCompStructOld = myStructsComputed.ChangeValue (anIndex);
309   Handle(Graphic3d_Structure) aCompStruct    = aCompStructOld;
310   aCompStruct->SetTransformation (Handle(TopLoc_Datum3D)());
311   theStruct->computeHLR (myCamera, aCompStruct);
312   if (aCompStruct.IsNull())
313   {
314     return;
315   }
316 
317   aCompStruct->SetHLRValidation (Standard_True);
318   aCompStruct->CalculateBoundBox();
319 
320   // of which type will be the computed?
321   const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
322                                            && theStruct->ComputeVisual() != Graphic3d_TOS_SHADING;
323   const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
324                                            && theStruct->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
325   if (toComputeWireframe)
326   {
327     aCompStruct->SetVisual (Graphic3d_TOS_WIREFRAME);
328   }
329   else if (toComputeShading)
330   {
331     aCompStruct->SetVisual (Graphic3d_TOS_SHADING);
332   }
333 
334   if (theStruct->IsHighlighted())
335   {
336     aCompStruct->Highlight (theStruct->HighlightStyle(), Standard_False);
337   }
338 
339   // The previous calculation is removed and the new one is displayed
340   eraseStructure   (aCompStructOld->CStructure());
341   displayStructure (aCompStruct->CStructure(), theStruct->DisplayPriority());
342 
343   // why not just replace existing items?
344   //myStructsToCompute.ChangeValue (anIndex) = theStruct;
345   //myStructsComputed .ChangeValue (anIndex) = aCompStruct;
346 
347   // hlhsr and the new associated compute are added
348   myStructsToCompute.Append (theStruct);
349   myStructsComputed .Append (aCompStruct);
350 
351   // hlhsr and the new associated compute are removed
352   myStructsToCompute.Remove (anIndex);
353   myStructsComputed .Remove (anIndex);
354 }
355 
356 // =======================================================================
357 // function : Update
358 // purpose  :
359 // =======================================================================
Update(const Graphic3d_ZLayerId theLayerId)360 void Graphic3d_CView::Update (const Graphic3d_ZLayerId theLayerId)
361 {
362   InvalidateZLayerBoundingBox (theLayerId);
363 }
364 
365 // =======================================================================
366 // function : InvalidateZLayerBoundingBox
367 // purpose  :
368 // =======================================================================
InvalidateZLayerBoundingBox(const Graphic3d_ZLayerId theLayerId)369 void Graphic3d_CView::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId)
370 {
371   if (Handle(Graphic3d_Layer) aLayer = Layer (theLayerId))
372   {
373     aLayer->InvalidateBoundingBox();
374     return;
375   }
376 
377   for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (Layers()); aLayerIter.More(); aLayerIter.Next())
378   {
379     const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
380     if (aLayer->NbOfTransformPersistenceObjects() > 0)
381     {
382       aLayer->InvalidateBoundingBox();
383     }
384   }
385 }
386 
387 // =======================================================================
388 // function : ContainsFacet
389 // purpose  :
390 // =======================================================================
ContainsFacet() const391 Standard_Boolean Graphic3d_CView::ContainsFacet() const
392 {
393   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
394   {
395     if (aStructIter.Key()->ContainsFacet())
396     {
397       return Standard_True;
398     }
399   }
400   return Standard_False;
401 }
402 
403 // =======================================================================
404 // function : ContainsFacet
405 // purpose  :
406 // =======================================================================
ContainsFacet(const Graphic3d_MapOfStructure & theSet) const407 Standard_Boolean Graphic3d_CView::ContainsFacet (const Graphic3d_MapOfStructure& theSet) const
408 {
409   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
410   {
411     if (aStructIter.Key()->ContainsFacet())
412     {
413       return Standard_True;
414     }
415   }
416   return Standard_False;
417 }
418 
419 // =======================================================================
420 // function : DisplayedStructures
421 // purpose  :
422 // =======================================================================
DisplayedStructures(Graphic3d_MapOfStructure & theStructures) const423 void Graphic3d_CView::DisplayedStructures (Graphic3d_MapOfStructure& theStructures) const
424 {
425   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
426   {
427     theStructures.Add (aStructIter.Key());
428   }
429 }
430 
431 // =======================================================================
432 // function : MinMaxValues
433 // purpose  :
434 // =======================================================================
MinMaxValues(const Standard_Boolean theToIncludeAuxiliary) const435 Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIncludeAuxiliary) const
436 {
437   if (!IsDefined())
438   {
439     return Bnd_Box();
440   }
441 
442   const Handle(Graphic3d_Camera)& aCamera = Camera();
443   Graphic3d_Vec2i aWinSize;
444   Window()->Size (aWinSize.x(), aWinSize.y());
445 
446   Bnd_Box aResult;
447   for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (Layers()); aLayerIter.More(); aLayerIter.Next())
448   {
449     const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
450     Bnd_Box aBox = aLayer->BoundingBox (Identification(),
451                                         aCamera,
452                                         aWinSize.x(), aWinSize.y(),
453                                         theToIncludeAuxiliary);
454     aResult.Add (aBox);
455   }
456   return aResult;
457 }
458 
459 // =======================================================================
460 // function : ConsiderZoomPersistenceObjects
461 // purpose  :
462 // =======================================================================
ConsiderZoomPersistenceObjects()463 Standard_Real Graphic3d_CView::ConsiderZoomPersistenceObjects()
464 {
465   if (!IsDefined())
466   {
467     return 1.0;
468   }
469 
470   const Handle(Graphic3d_Camera)& aCamera = Camera();
471   Graphic3d_Vec2i aWinSize;
472   Window()->Size (aWinSize.x(), aWinSize.y());
473 
474   Standard_Real aMaxCoef = 1.0;
475   for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (Layers()); aLayerIter.More(); aLayerIter.Next())
476   {
477     const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
478     aMaxCoef = Max (aMaxCoef, aLayer->considerZoomPersistenceObjects (Identification(), aCamera, aWinSize.x(), aWinSize.y()));
479   }
480 
481   return aMaxCoef;
482 }
483 
484 // =======================================================================
485 // function : MinMaxValues
486 // purpose  :
487 // =======================================================================
MinMaxValues(const Graphic3d_MapOfStructure & theSet,const Standard_Boolean theToIgnoreInfiniteFlag) const488 Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
489                                        const Standard_Boolean theToIgnoreInfiniteFlag) const
490 {
491   Bnd_Box aResult;
492   const Standard_Integer aViewId = Identification();
493 
494   Handle(Graphic3d_Camera) aCamera = Camera();
495   Standard_Integer aWinWidth  = 0;
496   Standard_Integer aWinHeight = 0;
497   if (IsDefined())
498   {
499     Window()->Size (aWinWidth, aWinHeight);
500   }
501 
502   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
503   {
504     const Handle(Graphic3d_Structure)& aStructure = aStructIter.Key();
505     if (aStructure->IsEmpty()
506     || !aStructure->CStructure()->IsVisible (aViewId))
507     {
508       continue;
509     }
510 
511     // "FitAll" operation ignores object with transform persistence parameter
512     if (!aStructure->TransformPersistence().IsNull())
513     {
514       // Panning and 2d persistence apply changes to projection or/and its translation components.
515       // It makes them incompatible with z-fitting algorithm. Ignored by now.
516       if (!theToIgnoreInfiniteFlag
517        || aStructure->TransformPersistence()->IsTrihedronOr2d())
518       {
519         continue;
520       }
521     }
522 
523     Bnd_Box aBox = aStructure->MinMaxValues (theToIgnoreInfiniteFlag);
524 
525     if (aBox.IsWhole() || aBox.IsVoid())
526     {
527       continue;
528     }
529 
530     if (!aStructure->TransformPersistence().IsNull())
531     {
532       const Graphic3d_Mat4d& aProjectionMat = aCamera->ProjectionMatrix();
533       const Graphic3d_Mat4d& aWorldViewMat  = aCamera->OrientationMatrix();
534       aStructure->TransformPersistence()->Apply (aCamera, aProjectionMat, aWorldViewMat, aWinWidth, aWinHeight, aBox);
535     }
536 
537     // To prevent float overflow at camera parameters calculation and further
538     // rendering, bounding boxes with at least one vertex coordinate out of
539     // float range are skipped by view fit algorithms
540     if (Abs (aBox.CornerMax().X()) >= ShortRealLast() ||
541         Abs (aBox.CornerMax().Y()) >= ShortRealLast() ||
542         Abs (aBox.CornerMax().Z()) >= ShortRealLast() ||
543         Abs (aBox.CornerMin().X()) >= ShortRealLast() ||
544         Abs (aBox.CornerMin().Y()) >= ShortRealLast() ||
545         Abs (aBox.CornerMin().Z()) >= ShortRealLast())
546     {
547       continue;
548     }
549 
550     aResult.Add (aBox);
551   }
552   return aResult;
553 }
554 
555 // =======================================================================
556 // function : acceptDisplay
557 // purpose  :
558 // =======================================================================
acceptDisplay(const Graphic3d_TypeOfStructure theStructType) const559 Graphic3d_TypeOfAnswer Graphic3d_CView::acceptDisplay (const Graphic3d_TypeOfStructure theStructType) const
560 {
561   switch (theStructType)
562   {
563     case Graphic3d_TOS_ALL:
564     {
565       return Graphic3d_TOA_YES; // The structure accepts any type of view
566     }
567     case Graphic3d_TOS_SHADING:
568     {
569       return myVisualization == Graphic3d_TOV_SHADING
570            ? Graphic3d_TOA_YES
571            : Graphic3d_TOA_NO;
572     }
573     case Graphic3d_TOS_WIREFRAME:
574     {
575       return myVisualization == Graphic3d_TOV_WIREFRAME
576            ? Graphic3d_TOA_YES
577            : Graphic3d_TOA_NO;
578     }
579     case Graphic3d_TOS_COMPUTED:
580     {
581       return (myVisualization == Graphic3d_TOV_SHADING || myVisualization == Graphic3d_TOV_WIREFRAME)
582            ?  Graphic3d_TOA_COMPUTE
583            :  Graphic3d_TOA_NO;
584     }
585   }
586   return Graphic3d_TOA_NO;
587 }
588 
589 // =======================================================================
590 // function : Compute
591 // purpose  :
592 // =======================================================================
Compute()593 void Graphic3d_CView::Compute()
594 {
595   // force HLRValidation to False on all structures calculated in the view
596   for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructsComputed); aStructIter.More(); aStructIter.Next())
597   {
598     aStructIter.Value()->SetHLRValidation (Standard_False);
599   }
600 
601   if (!ComputedMode())
602   {
603     return;
604   }
605 
606   // Change of orientation or of projection type =>
607   // Remove structures that were calculated for the previous orientation.
608   // Recalculation of new structures.
609   NCollection_Sequence<Handle(Graphic3d_Structure)> aStructsSeq;
610   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
611   {
612     const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStructIter.Key()->Visual());
613     if (anAnswer == Graphic3d_TOA_COMPUTE)
614     {
615       aStructsSeq.Append (aStructIter.Key()); // if the structure was calculated, it is recalculated
616     }
617   }
618 
619   for (NCollection_Sequence<Handle(Graphic3d_Structure)>::Iterator aStructIter (aStructsSeq); aStructIter.More(); aStructIter.Next())
620   {
621     Display (aStructIter.ChangeValue());
622   }
623 }
624 
625 // =======================================================================
626 // function : Clear
627 // purpose  :
628 // =======================================================================
Clear(Graphic3d_Structure * theStructure,const Standard_Boolean theWithDestruction)629 void Graphic3d_CView::Clear (Graphic3d_Structure* theStructure,
630                              const Standard_Boolean theWithDestruction)
631 {
632   const Standard_Integer anIndex = IsComputed (theStructure);
633   if (anIndex != 0)
634   {
635     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.Value (anIndex);
636     aCompStruct->GraphicClear (theWithDestruction);
637     aCompStruct->SetHLRValidation (Standard_False);
638   }
639 }
640 
641 // =======================================================================
642 // function : Connect
643 // purpose  :
644 // =======================================================================
Connect(const Graphic3d_Structure * theMother,const Graphic3d_Structure * theDaughter)645 void Graphic3d_CView::Connect (const Graphic3d_Structure* theMother,
646                                const Graphic3d_Structure* theDaughter)
647 {
648   Standard_Integer anIndexM = IsComputed (theMother);
649   Standard_Integer anIndexD = IsComputed (theDaughter);
650   if (anIndexM != 0
651    && anIndexD != 0)
652   {
653     const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
654     const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
655     aStructM->GraphicConnect (aStructD);
656   }
657 }
658 
659 // =======================================================================
660 // function : Disconnect
661 // purpose  :
662 // =======================================================================
Disconnect(const Graphic3d_Structure * theMother,const Graphic3d_Structure * theDaughter)663 void Graphic3d_CView::Disconnect (const Graphic3d_Structure* theMother,
664                                   const Graphic3d_Structure* theDaughter)
665 {
666   Standard_Integer anIndexM = IsComputed (theMother);
667   Standard_Integer anIndexD = IsComputed (theDaughter);
668   if (anIndexM != 0
669    && anIndexD != 0)
670   {
671     const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
672     const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
673     aStructM->GraphicDisconnect (aStructD);
674   }
675 }
676 
677 // =======================================================================
678 // function : Display
679 // purpose  :
680 // =======================================================================
Display(const Handle (Graphic3d_Structure)& theStructure)681 void Graphic3d_CView::Display (const Handle(Graphic3d_Structure)& theStructure)
682 {
683   if (!IsActive())
684   {
685     return;
686   }
687 
688   // If Display on a structure present in the list of calculated structures while it is not
689   // or more, of calculated type =>
690   // - removes it as well as the associated old computed
691   // THis happens when hlhsr becomes again of type e non computed after SetVisual.
692   Standard_Integer anIndex = IsComputed (theStructure);
693   if (anIndex != 0
694    && theStructure->Visual() != Graphic3d_TOS_COMPUTED)
695   {
696     myStructsToCompute.Remove (anIndex);
697     myStructsComputed .Remove (anIndex);
698     anIndex = 0;
699   }
700 
701   Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStructure->Visual());
702   if (anAnswer == Graphic3d_TOA_NO)
703   {
704     return;
705   }
706 
707   if (!ComputedMode())
708   {
709     anAnswer = Graphic3d_TOA_YES;
710   }
711 
712   if (anAnswer == Graphic3d_TOA_YES)
713   {
714     if (!myStructsDisplayed.Add (theStructure))
715     {
716       return;
717     }
718 
719     theStructure->CalculateBoundBox();
720     displayStructure (theStructure->CStructure(), theStructure->DisplayPriority());
721     Update (theStructure->GetZLayer());
722     return;
723   }
724   else if (anAnswer != Graphic3d_TOA_COMPUTE)
725   {
726     return;
727   }
728 
729   if (anIndex != 0)
730   {
731     // Already computed, is COMPUTED still valid?
732     const Handle(Graphic3d_Structure)& anOldStruct = myStructsComputed.Value (anIndex);
733     if (anOldStruct->HLRValidation())
734     {
735       // Case COMPUTED valid, to be displayed
736       if (!myStructsDisplayed.Add (theStructure))
737       {
738         return;
739       }
740 
741       displayStructure (anOldStruct->CStructure(), theStructure->DisplayPriority());
742       Update (anOldStruct->GetZLayer());
743       return;
744     }
745     else
746     {
747       // Case COMPUTED invalid
748       // Is there another valid representation?
749       // Find in the sequence of already calculated structures
750       // 1/ Structure having the same Owner as <AStructure>
751       // 2/ That is not <AStructure>
752       // 3/ The COMPUTED which of is valid
753       const Standard_Integer aNewIndex = HaveTheSameOwner (theStructure);
754       if (aNewIndex != 0)
755       {
756         // Case of COMPUTED invalid, WITH a valid of replacement; to be displayed
757         if (!myStructsDisplayed.Add (theStructure))
758         {
759           return;
760         }
761 
762         const Handle(Graphic3d_Structure)& aNewStruct = myStructsComputed.Value (aNewIndex);
763         myStructsComputed.SetValue (anIndex, aNewStruct);
764         displayStructure (aNewStruct->CStructure(), theStructure->DisplayPriority());
765         Update (aNewStruct->GetZLayer());
766         return;
767       }
768       else
769       {
770         // Case COMPUTED invalid, WITHOUT a valid of replacement
771         // COMPUTED is removed if displayed
772         if (myStructsDisplayed.Contains (theStructure))
773         {
774           eraseStructure (anOldStruct->CStructure());
775         }
776       }
777     }
778   }
779 
780   // Compute + Validation
781   Handle(Graphic3d_Structure) aStruct;
782   if (anIndex != 0)
783   {
784     aStruct = myStructsComputed.Value (anIndex);
785     aStruct->SetTransformation (Handle(TopLoc_Datum3D)());
786   }
787   theStructure->computeHLR (myCamera, aStruct);
788   if (aStruct.IsNull())
789   {
790     return;
791   }
792   aStruct->SetHLRValidation (Standard_True);
793 
794   // TOCOMPUTE and COMPUTED associated to sequences are added
795   myStructsToCompute.Append (theStructure);
796   myStructsComputed .Append (aStruct);
797 
798   // The previous are removed if necessary
799   if (anIndex != 0)
800   {
801     myStructsToCompute.Remove (anIndex);
802     myStructsComputed .Remove (anIndex);
803   }
804 
805   // Of which type will be the computed?
806   const Standard_Boolean toComputeWireframe = myVisualization == Graphic3d_TOV_WIREFRAME
807                                            && theStructure->ComputeVisual() != Graphic3d_TOS_SHADING;
808   const Standard_Boolean toComputeShading   = myVisualization == Graphic3d_TOV_SHADING
809                                            && theStructure->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
810   if (!toComputeShading && !toComputeWireframe)
811   {
812     anAnswer = Graphic3d_TOA_NO;
813   }
814   else
815   {
816     aStruct->SetVisual (toComputeWireframe ? Graphic3d_TOS_WIREFRAME : Graphic3d_TOS_SHADING);
817     anAnswer = acceptDisplay (aStruct->Visual());
818   }
819 
820   if (theStructure->IsHighlighted())
821   {
822     aStruct->Highlight (theStructure->HighlightStyle(), Standard_False);
823   }
824 
825   // It is displayed only if the calculated structure
826   // has a proper type corresponding to the one of the view.
827   if (anAnswer == Graphic3d_TOA_NO)
828   {
829     return;
830   }
831 
832   myStructsDisplayed.Add (theStructure);
833   displayStructure (aStruct->CStructure(), theStructure->DisplayPriority());
834 
835   Update (aStruct->GetZLayer());
836 }
837 
838 // =======================================================================
839 // function : Erase
840 // purpose  :
841 // =======================================================================
Erase(const Handle (Graphic3d_Structure)& theStructure)842 void Graphic3d_CView::Erase (const Handle(Graphic3d_Structure)& theStructure)
843 {
844   if (!IsDisplayed (theStructure))
845   {
846     return;
847   }
848 
849   const Graphic3d_TypeOfAnswer anAnswer = myIsInComputedMode ? acceptDisplay (theStructure->Visual()) : Graphic3d_TOA_YES;
850   if (anAnswer != Graphic3d_TOA_COMPUTE)
851   {
852     eraseStructure (theStructure->CStructure());
853   }
854 
855   const Standard_Integer anIndex = !myStructsToCompute.IsEmpty() ? IsComputed (theStructure) : 0;
856   if (anIndex != 0)
857   {
858     if (anAnswer == Graphic3d_TOA_COMPUTE
859      && myIsInComputedMode)
860     {
861       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
862       eraseStructure (aCompStruct->CStructure());
863     }
864     myStructsComputed .Remove (anIndex);
865     myStructsToCompute.Remove (anIndex);
866   }
867 
868   myStructsDisplayed.Remove (theStructure);
869   Update (theStructure->GetZLayer());
870 }
871 
872 // =======================================================================
873 // function : Highlight
874 // purpose  :
875 // =======================================================================
Highlight(const Handle (Graphic3d_Structure)& theStructure)876 void Graphic3d_CView::Highlight (const Handle(Graphic3d_Structure)& theStructure)
877 {
878   const Standard_Integer anIndex = IsComputed (theStructure);
879   if (anIndex != 0)
880   {
881     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
882     aCompStruct->Highlight (theStructure->HighlightStyle(), Standard_False);
883   }
884 }
885 
886 // =======================================================================
887 // function : SetTransform
888 // purpose  :
889 // =======================================================================
SetTransform(const Handle (Graphic3d_Structure)& theStructure,const Handle (TopLoc_Datum3D)& theTrsf)890 void Graphic3d_CView::SetTransform (const Handle(Graphic3d_Structure)& theStructure,
891                                     const Handle(TopLoc_Datum3D)& theTrsf)
892 {
893   const Standard_Integer anIndex = IsComputed (theStructure);
894   if (anIndex != 0)
895   {
896     // Test is somewhat light !
897     // trsf is transferred only if it is :
898     // a translation
899     // a scale
900     if (!theTrsf.IsNull()
901       && (theTrsf->Form() == gp_Translation
902        || theTrsf->Form() == gp_Scale
903        || theTrsf->Form() == gp_CompoundTrsf))
904     {
905       ReCompute (theStructure);
906     }
907     else
908     {
909       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
910       aCompStruct->GraphicTransform (theTrsf);
911     }
912   }
913 
914   theStructure->CalculateBoundBox();
915   if (!theStructure->IsMutable()
916    && !theStructure->CStructure()->IsForHighlight
917    && !theStructure->CStructure()->IsInfinite)
918   {
919     const Graphic3d_ZLayerId aLayerId = theStructure->GetZLayer();
920     InvalidateBVHData (aLayerId);
921   }
922 }
923 
924 // =======================================================================
925 // function : UnHighlight
926 // purpose  :
927 // =======================================================================
UnHighlight(const Handle (Graphic3d_Structure)& theStructure)928 void Graphic3d_CView::UnHighlight (const Handle(Graphic3d_Structure)& theStructure)
929 {
930   Standard_Integer anIndex = IsComputed (theStructure);
931   if (anIndex != 0)
932   {
933     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
934     aCompStruct->CStructure()->GraphicUnhighlight();
935   }
936 }
937 
938 // ========================================================================
939 // function : IsComputed
940 // purpose  :
941 // ========================================================================
IsComputed(const Standard_Integer theStructId,Handle (Graphic3d_Structure)& theComputedStruct) const942 Standard_Boolean Graphic3d_CView::IsComputed (const Standard_Integer theStructId,
943                                               Handle(Graphic3d_Structure)& theComputedStruct) const
944 {
945   theComputedStruct.Nullify();
946   if (!ComputedMode())
947     return Standard_False;
948 
949   const Standard_Integer aNbStructs = myStructsToCompute.Length();
950   for (Standard_Integer aStructIter = 1; aStructIter <= aNbStructs; ++aStructIter)
951   {
952     if (myStructsToCompute.Value (aStructIter)->Identification() == theStructId)
953     {
954       theComputedStruct = myStructsComputed (aStructIter);
955       return Standard_True;
956     }
957   }
958   return Standard_False;
959 }
960 
961 // =======================================================================
962 // function : IsComputed
963 // purpose  :
964 // =======================================================================
IsComputed(const Graphic3d_Structure * theStructure) const965 Standard_Integer Graphic3d_CView::IsComputed (const Graphic3d_Structure* theStructure) const
966 {
967   const Standard_Integer aStructId  = theStructure->Identification();
968   Standard_Integer aStructIndex = 1;
969   for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructsToCompute); aStructIter.More(); aStructIter.Next(), ++aStructIndex)
970   {
971     const Handle(Graphic3d_Structure)& aStruct = aStructIter.Value();
972     if (aStruct->Identification() == aStructId)
973     {
974       return aStructIndex;
975     }
976   }
977   return 0;
978 }
979 
980 // =======================================================================
981 // function : IsDisplayed
982 // purpose  :
983 // =======================================================================
IsDisplayed(const Handle (Graphic3d_Structure)& theStructure) const984 Standard_Boolean Graphic3d_CView::IsDisplayed (const Handle(Graphic3d_Structure)& theStructure) const
985 {
986   return myStructsDisplayed.Contains (theStructure);
987 }
988 
989 // =======================================================================
990 // function : ChangePriority
991 // purpose  :
992 // =======================================================================
ChangePriority(const Handle (Graphic3d_Structure)& theStructure,const Standard_Integer,const Standard_Integer theNewPriority)993 void Graphic3d_CView::ChangePriority (const Handle(Graphic3d_Structure)& theStructure,
994                                       const Standard_Integer /*theOldPriority*/,
995                                       const Standard_Integer theNewPriority)
996 {
997   if (!IsActive()
998   ||  !IsDisplayed (theStructure))
999   {
1000     return;
1001   }
1002 
1003   if (!myIsInComputedMode)
1004   {
1005     changePriority (theStructure->CStructure(), theNewPriority);
1006     return;
1007   }
1008 
1009   const Standard_Integer              anIndex  = IsComputed (theStructure);
1010   const Handle(Graphic3d_CStructure)& aCStruct = anIndex != 0
1011                                                ? myStructsComputed.Value (anIndex)->CStructure()
1012                                                : theStructure->CStructure();
1013 
1014   changePriority (aCStruct, theNewPriority);
1015 }
1016 
1017 // =======================================================================
1018 // function : ChangeZLayer
1019 // purpose  :
1020 // =======================================================================
ChangeZLayer(const Handle (Graphic3d_Structure)& theStructure,const Graphic3d_ZLayerId theLayerId)1021 void Graphic3d_CView::ChangeZLayer (const Handle(Graphic3d_Structure)& theStructure,
1022                                     const Graphic3d_ZLayerId theLayerId)
1023 {
1024   if (!IsActive()
1025   ||  !IsDisplayed (theStructure))
1026   {
1027     return;
1028   }
1029 
1030   if (!myIsInComputedMode)
1031   {
1032     changeZLayer (theStructure->CStructure(), theLayerId);
1033     return;
1034   }
1035 
1036   const Standard_Integer       anIndex  = IsComputed (theStructure);
1037   Handle(Graphic3d_CStructure) aCStruct = anIndex != 0
1038                                        ? myStructsComputed.Value (anIndex)->CStructure()
1039                                        : theStructure->CStructure();
1040 
1041   changeZLayer (aCStruct, theLayerId);
1042 }
1043 
1044 // =======================================================================
1045 // function : HaveTheSameOwner
1046 // purpose  :
1047 // =======================================================================
HaveTheSameOwner(const Handle (Graphic3d_Structure)& theStructure) const1048 Standard_Integer Graphic3d_CView::HaveTheSameOwner (const Handle(Graphic3d_Structure)& theStructure) const
1049 {
1050   // Find in the sequence of already calculated structures
1051   // 1/ Structure with the same Owner as <AStructure>
1052   // 2/ Which is not <AStructure>
1053   // 3/ COMPUTED which of is valid
1054   const Standard_Integer aNbToCompStructs = myStructsToCompute.Length();
1055   for (Standard_Integer aStructIter = 1; aStructIter <= aNbToCompStructs; ++aStructIter)
1056   {
1057     const Handle(Graphic3d_Structure)& aStructToComp = myStructsToCompute.Value (aStructIter);
1058     if (aStructToComp->Owner()          == theStructure->Owner()
1059      && aStructToComp->Identification() != theStructure->Identification())
1060     {
1061       const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (aStructIter);
1062       if (aStructComp->HLRValidation())
1063       {
1064         return aStructIter;
1065       }
1066     }
1067   }
1068   return 0;
1069 }
1070 
1071 // =======================================================================
1072 // function : CopySettings
1073 // purpose  :
1074 // =======================================================================
CopySettings(const Handle (Graphic3d_CView)& theOther)1075 void Graphic3d_CView::CopySettings (const Handle(Graphic3d_CView)& theOther)
1076 {
1077   ChangeRenderingParams() = theOther->RenderingParams();
1078   SetBackground            (theOther->Background());
1079   SetGradientBackground    (theOther->GradientBackground());
1080   SetBackgroundImage       (theOther->BackgroundImage());
1081   SetBackgroundImageStyle  (theOther->BackgroundImageStyle());
1082   SetTextureEnv            (theOther->TextureEnv());
1083   SetShadingModel          (theOther->ShadingModel());
1084   SetBackfacingModel       (theOther->BackfacingModel());
1085   SetCamera                (new Graphic3d_Camera (theOther->Camera()));
1086   SetLights                (theOther->Lights());
1087   SetClipPlanes            (theOther->ClipPlanes());
1088 }
1089 
1090 // =======================================================================
1091 // function : SetShadingModel
1092 // purpose  :
1093 // =======================================================================
SetShadingModel(Graphic3d_TypeOfShadingModel theModel)1094 void Graphic3d_CView::SetShadingModel (Graphic3d_TypeOfShadingModel theModel)
1095 {
1096   if (theModel == Graphic3d_TypeOfShadingModel_DEFAULT)
1097   {
1098     throw Standard_ProgramError ("Graphic3d_CView::SetShadingModel() - attempt to set invalid Shading Model!");
1099   }
1100 
1101   myRenderParams.ShadingModel = theModel;
1102 }
1103 
1104 // =======================================================================
1105 // function : SetUnitFactor
1106 // purpose  :
1107 // =======================================================================
SetUnitFactor(Standard_Real theFactor)1108 void Graphic3d_CView::SetUnitFactor (Standard_Real theFactor)
1109 {
1110   if (theFactor <= 0.0)
1111   {
1112     throw Standard_ProgramError ("Graphic3d_CView::SetUnitFactor() - invalid unit factor");
1113   }
1114   myUnitFactor = theFactor;
1115   if (!myXRSession.IsNull())
1116   {
1117     myXRSession->SetUnitFactor (theFactor);
1118   }
1119 }
1120 
1121 // =======================================================================
1122 // function : IsActiveXR
1123 // purpose  :
1124 // =======================================================================
IsActiveXR() const1125 bool Graphic3d_CView::IsActiveXR() const
1126 {
1127   return !myXRSession.IsNull()
1128        && myXRSession->IsOpen();
1129 }
1130 
1131 // =======================================================================
1132 // function : InitXR
1133 // purpose  :
1134 // =======================================================================
InitXR()1135 bool Graphic3d_CView::InitXR()
1136 {
1137   if (myXRSession.IsNull())
1138   {
1139     myXRSession = new Aspect_OpenVRSession();
1140     myXRSession->SetUnitFactor (myUnitFactor);
1141   }
1142   if (!myXRSession->IsOpen())
1143   {
1144     myXRSession->Open();
1145     if (myBackXRCamera.IsNull())
1146     {
1147       // backup camera properties
1148       myBackXRCamera = new Graphic3d_Camera (myCamera);
1149     }
1150   }
1151   return myXRSession->IsOpen();
1152 }
1153 
1154 // =======================================================================
1155 // function : ReleaseXR
1156 // purpose  :
1157 // =======================================================================
ReleaseXR()1158 void Graphic3d_CView::ReleaseXR()
1159 {
1160   if (!myXRSession.IsNull())
1161   {
1162     if (myXRSession->IsOpen()
1163     && !myBackXRCamera.IsNull())
1164     {
1165       // restore projection properties overridden by HMD
1166       myCamera->SetFOV2d (myBackXRCamera->FOV2d());
1167       myCamera->SetFOVy  (myBackXRCamera->FOVy());
1168       myCamera->SetAspect(myBackXRCamera->Aspect());
1169       myCamera->SetIOD   (myBackXRCamera->GetIODType(), myBackXRCamera->IOD());
1170       myCamera->SetZFocus(myBackXRCamera->ZFocusType(), myBackXRCamera->ZFocus());
1171       myCamera->ResetCustomProjection();
1172       myBackXRCamera.Nullify();
1173     }
1174     myXRSession->Close();
1175   }
1176 }
1177 
1178 //=======================================================================
1179 //function : ProcessXRInput
1180 //purpose  :
1181 //=======================================================================
ProcessXRInput()1182 void Graphic3d_CView::ProcessXRInput()
1183 {
1184   if (myRenderParams.StereoMode == Graphic3d_StereoMode_OpenVR
1185    && myCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
1186   {
1187     InitXR();
1188   }
1189   else
1190   {
1191     ReleaseXR();
1192   }
1193 
1194   if (!IsActiveXR())
1195   {
1196     myBaseXRCamera.Nullify();
1197     myPosedXRCamera.Nullify();
1198     return;
1199   }
1200 
1201   myXRSession->ProcessEvents();
1202   Invalidate();
1203 
1204   myCamera->SetFOV2d (myRenderParams.HmdFov2d);
1205   myCamera->SetAspect(myXRSession->Aspect());
1206   myCamera->SetFOVy  (myXRSession->FieldOfView());
1207   myCamera->SetIOD   (Graphic3d_Camera::IODType_Absolute, myXRSession->IOD());
1208   myCamera->SetZFocus(Graphic3d_Camera::FocusType_Absolute, 1.0 * myUnitFactor);
1209 
1210   // VR APIs tend to decompose camera orientation-projection matrices into the following components:
1211   // @begincode
1212   //   Model * [View * Eye^-1] * [Projection]
1213   // @endcode
1214   // so that Eye position is encoded into Orientation matrix, and there should be 2 Orientation matrices and 2 Projection matrices to make the stereo.
1215   // Graphic3d_Camera historically follows different decomposition, with Eye position encoded into Projection matrix,
1216   // so that there is only 1 Orientation matrix (matching mono view) and 2 Projection matrices.
1217   if (myXRSession->HasProjectionFrustums())
1218   {
1219     // note that this definition does not include a small forward/backward offset from head to eye
1220     myCamera->SetCustomStereoFrustums (myXRSession->ProjectionFrustum (Aspect_Eye_Left),
1221                                        myXRSession->ProjectionFrustum (Aspect_Eye_Right));
1222   }
1223   else
1224   {
1225     const Graphic3d_Mat4d aPoseL = myXRSession->HeadToEyeTransform (Aspect_Eye_Left);
1226     const Graphic3d_Mat4d aPoseR = myXRSession->HeadToEyeTransform (Aspect_Eye_Right);
1227     const Graphic3d_Mat4d aProjL = myXRSession->ProjectionMatrix (Aspect_Eye_Left,  myCamera->ZNear(), myCamera->ZFar());
1228     const Graphic3d_Mat4d aProjR = myXRSession->ProjectionMatrix (Aspect_Eye_Right, myCamera->ZNear(), myCamera->ZFar());
1229     myCamera->SetCustomStereoProjection (aProjL, aPoseL, aProjR, aPoseR);
1230   }
1231   myBaseXRCamera = myCamera;
1232   if (myPosedXRCamera.IsNull())
1233   {
1234     myPosedXRCamera = new Graphic3d_Camera();
1235   }
1236   SynchronizeXRBaseToPosedCamera();
1237 }
1238 
1239 //=======================================================================
1240 //function : SynchronizeXRBaseToPosedCamera
1241 //purpose  :
1242 //=======================================================================
SynchronizeXRBaseToPosedCamera()1243 void Graphic3d_CView::SynchronizeXRBaseToPosedCamera()
1244 {
1245   if (!myPosedXRCamera.IsNull())
1246   {
1247     ComputeXRPosedCameraFromBase (*myPosedXRCamera, myXRSession->HeadPose());
1248   }
1249 }
1250 
1251 //=======================================================================
1252 //function : ComputeXRPosedCameraFromBase
1253 //purpose  :
1254 //=======================================================================
ComputeXRPosedCameraFromBase(Graphic3d_Camera & theCam,const gp_Trsf & theXRTrsf) const1255 void Graphic3d_CView::ComputeXRPosedCameraFromBase (Graphic3d_Camera& theCam,
1256                                                     const gp_Trsf& theXRTrsf) const
1257 {
1258   theCam.Copy (myBaseXRCamera);
1259 
1260   // convert head pose into camera transformation
1261   const gp_Ax3 anAxVr    (gp::Origin(),  gp::DZ(), gp::DX());
1262   const gp_Ax3 aCameraCS (gp::Origin(), -myBaseXRCamera->Direction(), -myBaseXRCamera->SideRight());
1263   gp_Trsf aTrsfCS;
1264   aTrsfCS.SetTransformation (aCameraCS, anAxVr);
1265   const gp_Trsf aTrsfToCamera = aTrsfCS * theXRTrsf * aTrsfCS.Inverted();
1266   gp_Trsf aTrsfToEye;
1267   aTrsfToEye.SetTranslation (myBaseXRCamera->Eye().XYZ());
1268 
1269   const gp_Trsf aTrsf = aTrsfToEye * aTrsfToCamera;
1270   const gp_Dir anUpNew  = myBaseXRCamera->Up().Transformed (aTrsf);
1271   const gp_Dir aDirNew  = myBaseXRCamera->Direction().Transformed (aTrsf);
1272   const gp_Pnt anEyeNew = gp::Origin().Translated (aTrsf.TranslationPart());
1273   theCam.SetUp (anUpNew);
1274   theCam.SetDirectionFromEye (aDirNew);
1275   theCam.MoveEyeTo (anEyeNew);
1276 }
1277 
1278 //=======================================================================
1279 //function : SynchronizeXRPosedToBaseCamera
1280 //purpose  :
1281 //=======================================================================
SynchronizeXRPosedToBaseCamera()1282 void Graphic3d_CView::SynchronizeXRPosedToBaseCamera()
1283 {
1284   if (myPosedXRCameraCopy.IsNull()
1285    || myPosedXRCamera.IsNull()
1286    || myBaseXRCamera.IsNull()
1287    || myCamera != myPosedXRCamera)
1288   {
1289     return;
1290   }
1291 
1292   if (myPosedXRCameraCopy->Eye().IsEqual (myPosedXRCamera->Eye(), gp::Resolution())
1293    && (myPosedXRCameraCopy->Distance() - myPosedXRCamera->Distance()) <= gp::Resolution()
1294    && myPosedXRCameraCopy->Direction().IsEqual (myPosedXRCamera->Direction(), gp::Resolution())
1295    && myPosedXRCameraCopy->Up().IsEqual (myPosedXRCamera->Up(), gp::Resolution()))
1296   {
1297     // avoid floating point math in case of no changes
1298     return;
1299   }
1300 
1301   // re-compute myBaseXRCamera from myPosedXRCamera by applying reversed head pose transformation
1302   ComputeXRBaseCameraFromPosed (myPosedXRCamera, myXRSession->HeadPose());
1303   myPosedXRCameraCopy->Copy (myPosedXRCamera);
1304 }
1305 
1306 //=======================================================================
1307 //function : ComputeXRBaseCameraFromPosed
1308 //purpose  :
1309 //=======================================================================
ComputeXRBaseCameraFromPosed(const Graphic3d_Camera & theCamPosed,const gp_Trsf & thePoseTrsf)1310 void Graphic3d_CView::ComputeXRBaseCameraFromPosed (const Graphic3d_Camera& theCamPosed,
1311                                                     const gp_Trsf& thePoseTrsf)
1312 {
1313   const gp_Ax3 anAxVr    (gp::Origin(),  gp::DZ(), gp::DX());
1314   const gp_Ax3 aCameraCS (gp::Origin(), -myBaseXRCamera->Direction(), -myBaseXRCamera->SideRight());
1315   gp_Trsf aTrsfCS;
1316   aTrsfCS.SetTransformation (aCameraCS, anAxVr);
1317   const gp_Trsf aTrsfToCamera  = aTrsfCS * thePoseTrsf * aTrsfCS.Inverted();
1318   const gp_Trsf aTrsfCamToHead = aTrsfToCamera.Inverted();
1319   const gp_Dir anUpNew  = theCamPosed.Up().Transformed (aTrsfCamToHead);
1320   const gp_Dir aDirNew  = theCamPosed.Direction().Transformed (aTrsfCamToHead);
1321   const gp_Pnt anEyeNew = theCamPosed.Eye().Translated (aTrsfToCamera.TranslationPart().Reversed());
1322   myBaseXRCamera->SetUp (anUpNew);
1323   myBaseXRCamera->SetDirectionFromEye (aDirNew);
1324   myBaseXRCamera->MoveEyeTo (anEyeNew);
1325 }
1326 
1327 //=======================================================================
1328 //function : TurnViewXRCamera
1329 //purpose  :
1330 //=======================================================================
TurnViewXRCamera(const gp_Trsf & theTrsfTurn)1331 void Graphic3d_CView::TurnViewXRCamera (const gp_Trsf& theTrsfTurn)
1332 {
1333   // use current eye position as an anchor
1334   const Handle(Graphic3d_Camera)& aCamBase = myBaseXRCamera;
1335   gp_Trsf aHeadTrsfLocal;
1336   aHeadTrsfLocal.SetTranslationPart (myXRSession->HeadPose().TranslationPart());
1337   const gp_Pnt anEyeAnchor = PoseXRToWorld (aHeadTrsfLocal).TranslationPart();
1338 
1339   // turn the view
1340   aCamBase->SetDirectionFromEye (aCamBase->Direction().Transformed (theTrsfTurn));
1341 
1342   // recompute new eye
1343   const gp_Ax3 anAxVr    (gp::Origin(),  gp::DZ(), gp::DX());
1344   const gp_Ax3 aCameraCS (gp::Origin(), -aCamBase->Direction(), -aCamBase->SideRight());
1345   gp_Trsf aTrsfCS;
1346   aTrsfCS.SetTransformation (aCameraCS, anAxVr);
1347   const gp_Trsf aTrsfToCamera = aTrsfCS * aHeadTrsfLocal * aTrsfCS.Inverted();
1348   const gp_Pnt anEyeNew = anEyeAnchor.Translated (aTrsfToCamera.TranslationPart().Reversed());
1349   aCamBase->MoveEyeTo (anEyeNew);
1350 
1351   SynchronizeXRBaseToPosedCamera();
1352 }
1353 
1354 //=======================================================================
1355 //function : SetupXRPosedCamera
1356 //purpose  :
1357 //=======================================================================
SetupXRPosedCamera()1358 void Graphic3d_CView::SetupXRPosedCamera()
1359 {
1360   if (!myPosedXRCamera.IsNull())
1361   {
1362     myCamera = myPosedXRCamera;
1363     if (myPosedXRCameraCopy.IsNull())
1364     {
1365       myPosedXRCameraCopy = new Graphic3d_Camera();
1366     }
1367     myPosedXRCameraCopy->Copy (myPosedXRCamera);
1368   }
1369 }
1370 
1371 //=======================================================================
1372 //function : UnsetXRPosedCamera
1373 //purpose  :
1374 //=======================================================================
UnsetXRPosedCamera()1375 void Graphic3d_CView::UnsetXRPosedCamera()
1376 {
1377   if (myCamera == myPosedXRCamera
1378   && !myBaseXRCamera.IsNull())
1379   {
1380     SynchronizeXRPosedToBaseCamera();
1381     myCamera = myBaseXRCamera;
1382   }
1383 }
1384 
1385 //=======================================================================
1386 //function : DiagnosticInformation
1387 //purpose  :
1388 //=======================================================================
DiagnosticInformation(TColStd_IndexedDataMapOfStringString & theDict,Graphic3d_DiagnosticInfo theFlags) const1389 void Graphic3d_CView::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
1390                                              Graphic3d_DiagnosticInfo theFlags) const
1391 {
1392   if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0
1393    && !myXRSession.IsNull())
1394   {
1395     TCollection_AsciiString aVendor  = myXRSession->GetString (Aspect_XRSession::InfoString_Vendor);
1396     TCollection_AsciiString aDevice  = myXRSession->GetString (Aspect_XRSession::InfoString_Device);
1397     TCollection_AsciiString aTracker = myXRSession->GetString (Aspect_XRSession::InfoString_Tracker);
1398     TCollection_AsciiString aSerial  = myXRSession->GetString (Aspect_XRSession::InfoString_SerialNumber);
1399     TCollection_AsciiString aDisplay = TCollection_AsciiString()
1400                                      + myXRSession->RecommendedViewport().x() + "x" + myXRSession->RecommendedViewport().y()
1401                                      + "@" + (int )Round (myXRSession->DisplayFrequency())
1402                                      + " [FOVy: " + (int )Round (myXRSession->FieldOfView()) + "]";
1403 
1404     theDict.ChangeFromIndex (theDict.Add ("VRvendor",  aVendor))  = aVendor;
1405     theDict.ChangeFromIndex (theDict.Add ("VRdevice",  aDevice))  = aDevice;
1406     theDict.ChangeFromIndex (theDict.Add ("VRtracker", aTracker)) = aTracker;
1407     theDict.ChangeFromIndex (theDict.Add ("VRdisplay", aDisplay)) = aDisplay;
1408     theDict.ChangeFromIndex (theDict.Add ("VRserial",  aSerial))  = aSerial;
1409   }
1410 }
1411 
1412 //=======================================================================
1413 //function : DumpJson
1414 //purpose  :
1415 //=======================================================================
DumpJson(Standard_OStream & theOStream,Standard_Integer theDepth) const1416 void Graphic3d_CView::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
1417 {
1418   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
1419 
1420   OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Graphic3d_DataStructureManager);
1421 
1422   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myId)
1423   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myRenderParams)
1424   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myBgColor)
1425   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myStructureManager)
1426   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myCamera.get())
1427 
1428   for (Graphic3d_SequenceOfStructure::Iterator anIter (myStructsToCompute); anIter.More(); anIter.Next())
1429   {
1430     const Handle(Graphic3d_Structure)& aStructToCompute = anIter.Value();
1431     OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, aStructToCompute.get())
1432   }
1433 
1434   for (Graphic3d_SequenceOfStructure::Iterator anIter (myStructsComputed); anIter.More(); anIter.Next())
1435   {
1436     const Handle(Graphic3d_Structure)& aStructComputed = anIter.Value();
1437     OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, aStructComputed.get())
1438   }
1439 
1440   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsInComputedMode)
1441   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsActive)
1442   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsRemoved)
1443 
1444   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myVisualization)
1445 
1446   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myBackXRCamera.get())
1447   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myBaseXRCamera.get())
1448   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myPosedXRCamera.get())
1449   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myPosedXRCameraCopy.get())
1450 
1451   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myUnitFactor)
1452 }
1453