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