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