1 // Copyright (c) 2015 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <Graphic3d_CView.hxx>
16 #include <Aspect_OpenVRSession.hxx>
17 #include <Graphic3d_Layer.hxx>
18 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
19 #include <Graphic3d_StructureManager.hxx>
21 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CView,Graphic3d_DataStructureManager)
23 //=======================================================================
24 //function : Constructor
26 //=======================================================================
27 Graphic3d_CView::Graphic3d_CView (const Handle(Graphic3d_StructureManager)& theMgr)
28 : myBgColor (Quantity_NOC_BLACK),
29 myStructureManager (theMgr),
30 myCamera (new Graphic3d_Camera()),
31 myHiddenObjects (new Graphic3d_NMapOfTransient()),
32 myIsInComputedMode (Standard_False),
33 myIsActive (Standard_False),
34 myIsRemoved (Standard_False),
35 myShadingModel (Graphic3d_TOSM_FRAGMENT),
36 myVisualization (Graphic3d_TOV_WIREFRAME),
39 myId = myStructureManager->Identification (this);
42 //=======================================================================
43 //function : Destructor
45 //=======================================================================
46 Graphic3d_CView::~Graphic3d_CView()
48 myXRSession.Nullify();
51 myStructureManager->UnIdentification (this);
55 // =======================================================================
56 // function : Activate
58 // =======================================================================
59 void Graphic3d_CView::Activate()
63 myIsActive = Standard_True;
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())
75 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
76 if (IsDisplayed (aStruct))
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)
94 // =======================================================================
95 // function : Deactivate
97 // =======================================================================
98 void Graphic3d_CView::Deactivate()
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())
112 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
113 if (!IsDisplayed (aStruct))
118 const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
119 if (anAnswer == Graphic3d_TOA_YES
120 || anAnswer == Graphic3d_TOA_COMPUTE)
127 myIsActive = Standard_False;
131 // ========================================================================
134 // ========================================================================
135 void Graphic3d_CView::Remove()
142 Graphic3d_MapOfStructure aDisplayedStructs (myStructsDisplayed);
144 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aDisplayedStructs); aStructIter.More(); aStructIter.Next())
146 Erase (aStructIter.Value());
149 myStructsToCompute.Clear();
150 myStructsComputed .Clear();
151 myStructsDisplayed.Clear();
153 if (!myStructureManager.IsNull())
155 myStructureManager->UnIdentification (this);
158 myIsActive = Standard_False;
159 myIsRemoved = Standard_True;
162 // ========================================================================
163 // function : SetComputedMode
165 // ========================================================================
166 void Graphic3d_CView::SetComputedMode (const Standard_Boolean theMode)
168 if (( theMode && myIsInComputedMode)
169 || (!theMode && !myIsInComputedMode))
174 myIsInComputedMode = theMode;
175 if (!myIsInComputedMode)
177 for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
179 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
180 const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
181 if (anAnswer != Graphic3d_TOA_COMPUTE)
186 const Standard_Integer anIndex = IsComputed (aStruct);
189 const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (anIndex);
190 eraseStructure (aStructComp->CStructure());
191 displayStructure (aStruct->CStructure(), aStruct->DisplayPriority());
192 Update (aStruct->GetZLayer());
198 for (Graphic3d_MapOfStructure::Iterator aDispStructIter (myStructsDisplayed); aDispStructIter.More(); aDispStructIter.Next())
200 Handle(Graphic3d_Structure) aStruct = aDispStructIter.Key();
201 const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
202 if (anAnswer != Graphic3d_TOA_COMPUTE)
207 const Standard_Integer anIndex = IsComputed (aStruct);
210 eraseStructure (aStruct->CStructure());
211 displayStructure (myStructsComputed.Value (anIndex)->CStructure(), aStruct->DisplayPriority());
214 if (aStruct->IsHighlighted())
216 const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.Value (anIndex);
217 if (!aCompStruct->IsHighlighted())
219 aCompStruct->Highlight (aStruct->HighlightStyle(), Standard_False);
225 Handle(Graphic3d_Structure) aCompStruct;
226 aStruct->computeHLR (myCamera, aCompStruct);
227 if (aCompStruct.IsNull())
231 aCompStruct->SetHLRValidation (Standard_True);
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);
240 if (aStruct->IsHighlighted())
242 aCompStruct->Highlight (aStruct->HighlightStyle(), Standard_False);
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)
250 if (myStructsToCompute.Value (aToCompStructIter)->Identification() == aStructId)
252 hasResult = Standard_True;
253 myStructsComputed.ChangeValue (aToCompStructIter) = aCompStruct;
260 myStructsToCompute.Append (aStruct);
261 myStructsComputed .Append (aCompStruct);
264 aCompStruct->CalculateBoundBox();
265 eraseStructure (aStruct->CStructure());
266 displayStructure (aCompStruct->CStructure(), aStruct->DisplayPriority());
272 // =======================================================================
273 // function : ReCompute
275 // =======================================================================
276 void Graphic3d_CView::ReCompute (const Handle(Graphic3d_Structure)& theStruct)
278 theStruct->CalculateBoundBox();
279 if (!theStruct->IsMutable()
280 && !theStruct->CStructure()->IsForHighlight
281 && !theStruct->CStructure()->IsInfinite)
283 const Graphic3d_ZLayerId aLayerId = theStruct->GetZLayer();
284 InvalidateBVHData (aLayerId);
289 || !theStruct->IsDisplayed())
294 const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStruct->Visual());
295 if (anAnswer != Graphic3d_TOA_COMPUTE)
300 const Standard_Integer anIndex = IsComputed (theStruct);
306 // compute + validation
307 Handle(Graphic3d_Structure) aCompStructOld = myStructsComputed.ChangeValue (anIndex);
308 Handle(Graphic3d_Structure) aCompStruct = aCompStructOld;
309 aCompStruct->SetTransformation (Handle(TopLoc_Datum3D)());
310 theStruct->computeHLR (myCamera, aCompStruct);
311 if (aCompStruct.IsNull())
316 aCompStruct->SetHLRValidation (Standard_True);
317 aCompStruct->CalculateBoundBox();
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)
326 aCompStruct->SetVisual (Graphic3d_TOS_WIREFRAME);
328 else if (toComputeShading)
330 aCompStruct->SetVisual (Graphic3d_TOS_SHADING);
333 if (theStruct->IsHighlighted())
335 aCompStruct->Highlight (theStruct->HighlightStyle(), Standard_False);
338 // The previous calculation is removed and the new one is displayed
339 eraseStructure (aCompStructOld->CStructure());
340 displayStructure (aCompStruct->CStructure(), theStruct->DisplayPriority());
342 // why not just replace existing items?
343 //myStructsToCompute.ChangeValue (anIndex) = theStruct;
344 //myStructsComputed .ChangeValue (anIndex) = aCompStruct;
346 // hlhsr and the new associated compute are added
347 myStructsToCompute.Append (theStruct);
348 myStructsComputed .Append (aCompStruct);
350 // hlhsr and the new associated compute are removed
351 myStructsToCompute.Remove (anIndex);
352 myStructsComputed .Remove (anIndex);
355 // =======================================================================
358 // =======================================================================
359 void Graphic3d_CView::Update (const Graphic3d_ZLayerId theLayerId)
361 InvalidateZLayerBoundingBox (theLayerId);
364 // =======================================================================
365 // function : InvalidateZLayerBoundingBox
367 // =======================================================================
368 void Graphic3d_CView::InvalidateZLayerBoundingBox (const Graphic3d_ZLayerId theLayerId)
370 if (Handle(Graphic3d_Layer) aLayer = Layer (theLayerId))
372 aLayer->InvalidateBoundingBox();
376 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (Layers()); aLayerIter.More(); aLayerIter.Next())
378 const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
379 if (aLayer->NbOfTransformPersistenceObjects() > 0)
381 aLayer->InvalidateBoundingBox();
386 // =======================================================================
387 // function : ContainsFacet
389 // =======================================================================
390 Standard_Boolean Graphic3d_CView::ContainsFacet() const
392 for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
394 if (aStructIter.Key()->ContainsFacet())
396 return Standard_True;
399 return Standard_False;
402 // =======================================================================
403 // function : ContainsFacet
405 // =======================================================================
406 Standard_Boolean Graphic3d_CView::ContainsFacet (const Graphic3d_MapOfStructure& theSet) const
408 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
410 if (aStructIter.Key()->ContainsFacet())
412 return Standard_True;
415 return Standard_False;
418 // =======================================================================
419 // function : DisplayedStructures
421 // =======================================================================
422 void Graphic3d_CView::DisplayedStructures (Graphic3d_MapOfStructure& theStructures) const
424 for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
426 theStructures.Add (aStructIter.Key());
430 // =======================================================================
431 // function : MinMaxValues
433 // =======================================================================
434 Bnd_Box Graphic3d_CView::MinMaxValues (const Standard_Boolean theToIncludeAuxiliary) const
441 const Handle(Graphic3d_Camera)& aCamera = Camera();
442 Graphic3d_Vec2i aWinSize;
443 Window()->Size (aWinSize.x(), aWinSize.y());
446 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (Layers()); aLayerIter.More(); aLayerIter.Next())
448 const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
449 Bnd_Box aBox = aLayer->BoundingBox (Identification(),
451 aWinSize.x(), aWinSize.y(),
452 theToIncludeAuxiliary);
458 // =======================================================================
459 // function : ConsiderZoomPersistenceObjects
461 // =======================================================================
462 Standard_Real Graphic3d_CView::ConsiderZoomPersistenceObjects()
469 const Handle(Graphic3d_Camera)& aCamera = Camera();
470 Graphic3d_Vec2i aWinSize;
471 Window()->Size (aWinSize.x(), aWinSize.y());
473 Standard_Real aMaxCoef = 1.0;
474 for (NCollection_List<Handle(Graphic3d_Layer)>::Iterator aLayerIter (Layers()); aLayerIter.More(); aLayerIter.Next())
476 const Handle(Graphic3d_Layer)& aLayer = aLayerIter.Value();
477 aMaxCoef = Max (aMaxCoef, aLayer->considerZoomPersistenceObjects (Identification(), aCamera, aWinSize.x(), aWinSize.y()));
483 // =======================================================================
484 // function : MinMaxValues
486 // =======================================================================
487 Bnd_Box Graphic3d_CView::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
488 const Standard_Boolean theToIgnoreInfiniteFlag) const
491 const Standard_Integer aViewId = Identification();
493 Handle(Graphic3d_Camera) aCamera = Camera();
494 Standard_Integer aWinWidth = 0;
495 Standard_Integer aWinHeight = 0;
498 Window()->Size (aWinWidth, aWinHeight);
501 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
503 const Handle(Graphic3d_Structure)& aStructure = aStructIter.Key();
504 if (aStructure->IsEmpty()
505 || !aStructure->CStructure()->IsVisible (aViewId))
510 // "FitAll" operation ignores object with transform persistence parameter
511 if (!aStructure->TransformPersistence().IsNull())
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.
515 if (!theToIgnoreInfiniteFlag
516 || aStructure->TransformPersistence()->IsTrihedronOr2d())
522 Bnd_Box aBox = aStructure->MinMaxValues (theToIgnoreInfiniteFlag);
524 if (aBox.IsWhole() || aBox.IsVoid())
529 if (!aStructure->TransformPersistence().IsNull())
531 const Graphic3d_Mat4d& aProjectionMat = aCamera->ProjectionMatrix();
532 const Graphic3d_Mat4d& aWorldViewMat = aCamera->OrientationMatrix();
533 aStructure->TransformPersistence()->Apply (aCamera, aProjectionMat, aWorldViewMat, aWinWidth, aWinHeight, aBox);
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())
554 // =======================================================================
555 // function : acceptDisplay
557 // =======================================================================
558 Graphic3d_TypeOfAnswer Graphic3d_CView::acceptDisplay (const Graphic3d_TypeOfStructure theStructType) const
560 switch (theStructType)
562 case Graphic3d_TOS_ALL:
564 return Graphic3d_TOA_YES; // The structure accepts any type of view
566 case Graphic3d_TOS_SHADING:
568 return myVisualization == Graphic3d_TOV_SHADING
572 case Graphic3d_TOS_WIREFRAME:
574 return myVisualization == Graphic3d_TOV_WIREFRAME
578 case Graphic3d_TOS_COMPUTED:
580 return (myVisualization == Graphic3d_TOV_SHADING || myVisualization == Graphic3d_TOV_WIREFRAME)
581 ? Graphic3d_TOA_COMPUTE
585 return Graphic3d_TOA_NO;
588 // =======================================================================
589 // function : Compute
591 // =======================================================================
592 void Graphic3d_CView::Compute()
594 // force HLRValidation to False on all structures calculated in the view
595 for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructsComputed); aStructIter.More(); aStructIter.Next())
597 aStructIter.Value()->SetHLRValidation (Standard_False);
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())
611 const Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (aStructIter.Key()->Visual());
612 if (anAnswer == Graphic3d_TOA_COMPUTE)
614 aStructsSeq.Append (aStructIter.Key()); // if the structure was calculated, it is recalculated
618 for (NCollection_Sequence<Handle(Graphic3d_Structure)>::Iterator aStructIter (aStructsSeq); aStructIter.More(); aStructIter.Next())
620 Display (aStructIter.ChangeValue());
624 // =======================================================================
627 // =======================================================================
628 void Graphic3d_CView::Clear (Graphic3d_Structure* theStructure,
629 const Standard_Boolean theWithDestruction)
631 const Standard_Integer anIndex = IsComputed (theStructure);
634 const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.Value (anIndex);
635 aCompStruct->GraphicClear (theWithDestruction);
636 aCompStruct->SetHLRValidation (Standard_False);
640 // =======================================================================
641 // function : Connect
643 // =======================================================================
644 void Graphic3d_CView::Connect (const Graphic3d_Structure* theMother,
645 const Graphic3d_Structure* theDaughter)
647 Standard_Integer anIndexM = IsComputed (theMother);
648 Standard_Integer anIndexD = IsComputed (theDaughter);
652 const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
653 const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
654 aStructM->GraphicConnect (aStructD);
658 // =======================================================================
659 // function : Disconnect
661 // =======================================================================
662 void Graphic3d_CView::Disconnect (const Graphic3d_Structure* theMother,
663 const Graphic3d_Structure* theDaughter)
665 Standard_Integer anIndexM = IsComputed (theMother);
666 Standard_Integer anIndexD = IsComputed (theDaughter);
670 const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
671 const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
672 aStructM->GraphicDisconnect (aStructD);
676 // =======================================================================
677 // function : Display
679 // =======================================================================
680 void Graphic3d_CView::Display (const Handle(Graphic3d_Structure)& theStructure)
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);
693 && theStructure->Visual() != Graphic3d_TOS_COMPUTED)
695 myStructsToCompute.Remove (anIndex);
696 myStructsComputed .Remove (anIndex);
700 Graphic3d_TypeOfAnswer anAnswer = acceptDisplay (theStructure->Visual());
701 if (anAnswer == Graphic3d_TOA_NO)
708 anAnswer = Graphic3d_TOA_YES;
711 if (anAnswer == Graphic3d_TOA_YES)
713 if (!myStructsDisplayed.Add (theStructure))
718 theStructure->CalculateBoundBox();
719 displayStructure (theStructure->CStructure(), theStructure->DisplayPriority());
720 Update (theStructure->GetZLayer());
723 else if (anAnswer != Graphic3d_TOA_COMPUTE)
730 // Already computed, is COMPUTED still valid?
731 const Handle(Graphic3d_Structure)& anOldStruct = myStructsComputed.Value (anIndex);
732 if (anOldStruct->HLRValidation())
734 // Case COMPUTED valid, to be displayed
735 if (!myStructsDisplayed.Add (theStructure))
740 displayStructure (anOldStruct->CStructure(), theStructure->DisplayPriority());
741 Update (anOldStruct->GetZLayer());
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);
755 // Case of COMPUTED invalid, WITH a valid of replacement; to be displayed
756 if (!myStructsDisplayed.Add (theStructure))
761 const Handle(Graphic3d_Structure)& aNewStruct = myStructsComputed.Value (aNewIndex);
762 myStructsComputed.SetValue (anIndex, aNewStruct);
763 displayStructure (aNewStruct->CStructure(), theStructure->DisplayPriority());
764 Update (aNewStruct->GetZLayer());
769 // Case COMPUTED invalid, WITHOUT a valid of replacement
770 // COMPUTED is removed if displayed
771 if (myStructsDisplayed.Contains (theStructure))
773 eraseStructure (anOldStruct->CStructure());
779 // Compute + Validation
780 Handle(Graphic3d_Structure) aStruct;
783 aStruct = myStructsComputed.Value (anIndex);
784 aStruct->SetTransformation (Handle(TopLoc_Datum3D)());
786 theStructure->computeHLR (myCamera, aStruct);
787 if (aStruct.IsNull())
791 aStruct->SetHLRValidation (Standard_True);
793 // TOCOMPUTE and COMPUTED associated to sequences are added
794 myStructsToCompute.Append (theStructure);
795 myStructsComputed .Append (aStruct);
797 // The previous are removed if necessary
800 myStructsToCompute.Remove (anIndex);
801 myStructsComputed .Remove (anIndex);
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)
811 anAnswer = Graphic3d_TOA_NO;
815 aStruct->SetVisual (toComputeWireframe ? Graphic3d_TOS_WIREFRAME : Graphic3d_TOS_SHADING);
816 anAnswer = acceptDisplay (aStruct->Visual());
819 if (theStructure->IsHighlighted())
821 aStruct->Highlight (theStructure->HighlightStyle(), Standard_False);
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)
831 myStructsDisplayed.Add (theStructure);
832 displayStructure (aStruct->CStructure(), theStructure->DisplayPriority());
834 Update (aStruct->GetZLayer());
837 // =======================================================================
840 // =======================================================================
841 void Graphic3d_CView::Erase (const Handle(Graphic3d_Structure)& theStructure)
843 if (!IsDisplayed (theStructure))
848 const Graphic3d_TypeOfAnswer anAnswer = myIsInComputedMode ? acceptDisplay (theStructure->Visual()) : Graphic3d_TOA_YES;
849 if (anAnswer != Graphic3d_TOA_COMPUTE)
851 eraseStructure (theStructure->CStructure());
854 const Standard_Integer anIndex = !myStructsToCompute.IsEmpty() ? IsComputed (theStructure) : 0;
857 if (anAnswer == Graphic3d_TOA_COMPUTE
858 && myIsInComputedMode)
860 const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
861 eraseStructure (aCompStruct->CStructure());
863 myStructsComputed .Remove (anIndex);
864 myStructsToCompute.Remove (anIndex);
867 myStructsDisplayed.Remove (theStructure);
868 Update (theStructure->GetZLayer());
871 // =======================================================================
872 // function : Highlight
874 // =======================================================================
875 void Graphic3d_CView::Highlight (const Handle(Graphic3d_Structure)& theStructure)
877 const Standard_Integer anIndex = IsComputed (theStructure);
880 const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
881 aCompStruct->Highlight (theStructure->HighlightStyle(), Standard_False);
885 // =======================================================================
886 // function : SetTransform
888 // =======================================================================
889 void Graphic3d_CView::SetTransform (const Handle(Graphic3d_Structure)& theStructure,
890 const Handle(TopLoc_Datum3D)& theTrsf)
892 const Standard_Integer anIndex = IsComputed (theStructure);
895 // Test is somewhat light !
896 // trsf is transferred only if it is :
899 if (!theTrsf.IsNull()
900 && (theTrsf->Form() == gp_Translation
901 || theTrsf->Form() == gp_Scale
902 || theTrsf->Form() == gp_CompoundTrsf))
904 ReCompute (theStructure);
908 const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
909 aCompStruct->GraphicTransform (theTrsf);
913 theStructure->CalculateBoundBox();
914 if (!theStructure->IsMutable()
915 && !theStructure->CStructure()->IsForHighlight
916 && !theStructure->CStructure()->IsInfinite)
918 const Graphic3d_ZLayerId aLayerId = theStructure->GetZLayer();
919 InvalidateBVHData (aLayerId);
923 // =======================================================================
924 // function : UnHighlight
926 // =======================================================================
927 void Graphic3d_CView::UnHighlight (const Handle(Graphic3d_Structure)& theStructure)
929 Standard_Integer anIndex = IsComputed (theStructure);
932 const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
933 aCompStruct->CStructure()->GraphicUnhighlight();
937 // ========================================================================
938 // function : IsComputed
940 // ========================================================================
941 Standard_Boolean Graphic3d_CView::IsComputed (const Standard_Integer theStructId,
942 Handle(Graphic3d_Structure)& theComputedStruct) const
944 theComputedStruct.Nullify();
946 return Standard_False;
948 const Standard_Integer aNbStructs = myStructsToCompute.Length();
949 for (Standard_Integer aStructIter = 1; aStructIter <= aNbStructs; ++aStructIter)
951 if (myStructsToCompute.Value (aStructIter)->Identification() == theStructId)
953 theComputedStruct = myStructsComputed (aStructIter);
954 return Standard_True;
957 return Standard_False;
960 // =======================================================================
961 // function : IsComputed
963 // =======================================================================
964 Standard_Integer Graphic3d_CView::IsComputed (const Graphic3d_Structure* theStructure) const
966 const Standard_Integer aStructId = theStructure->Identification();
967 Standard_Integer aStructIndex = 1;
968 for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructsToCompute); aStructIter.More(); aStructIter.Next(), ++aStructIndex)
970 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Value();
971 if (aStruct->Identification() == aStructId)
979 // =======================================================================
980 // function : IsDisplayed
982 // =======================================================================
983 Standard_Boolean Graphic3d_CView::IsDisplayed (const Handle(Graphic3d_Structure)& theStructure) const
985 return myStructsDisplayed.Contains (theStructure);
988 // =======================================================================
989 // function : ChangePriority
991 // =======================================================================
992 void Graphic3d_CView::ChangePriority (const Handle(Graphic3d_Structure)& theStructure,
993 const Standard_Integer /*theOldPriority*/,
994 const Standard_Integer theNewPriority)
997 || !IsDisplayed (theStructure))
1002 if (!myIsInComputedMode)
1004 changePriority (theStructure->CStructure(), theNewPriority);
1008 const Standard_Integer anIndex = IsComputed (theStructure);
1009 const Handle(Graphic3d_CStructure)& aCStruct = anIndex != 0
1010 ? myStructsComputed.Value (anIndex)->CStructure()
1011 : theStructure->CStructure();
1013 changePriority (aCStruct, theNewPriority);
1016 // =======================================================================
1017 // function : ChangeZLayer
1019 // =======================================================================
1020 void Graphic3d_CView::ChangeZLayer (const Handle(Graphic3d_Structure)& theStructure,
1021 const Graphic3d_ZLayerId theLayerId)
1024 || !IsDisplayed (theStructure))
1029 if (!myIsInComputedMode)
1031 changeZLayer (theStructure->CStructure(), theLayerId);
1035 const Standard_Integer anIndex = IsComputed (theStructure);
1036 Handle(Graphic3d_CStructure) aCStruct = anIndex != 0
1037 ? myStructsComputed.Value (anIndex)->CStructure()
1038 : theStructure->CStructure();
1040 changeZLayer (aCStruct, theLayerId);
1043 // =======================================================================
1044 // function : HaveTheSameOwner
1046 // =======================================================================
1047 Standard_Integer Graphic3d_CView::HaveTheSameOwner (const Handle(Graphic3d_Structure)& theStructure) const
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)
1056 const Handle(Graphic3d_Structure)& aStructToComp = myStructsToCompute.Value (aStructIter);
1057 if (aStructToComp->Owner() == theStructure->Owner()
1058 && aStructToComp->Identification() != theStructure->Identification())
1060 const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (aStructIter);
1061 if (aStructComp->HLRValidation())
1070 // =======================================================================
1071 // function : CopySettings
1073 // =======================================================================
1074 void Graphic3d_CView::CopySettings (const Handle(Graphic3d_CView)& theOther)
1076 ChangeRenderingParams() = theOther->RenderingParams();
1077 SetBackground (theOther->Background());
1078 SetGradientBackground (theOther->GradientBackground());
1079 SetBackgroundImage (theOther->BackgroundImage());
1080 SetBackgroundImageStyle (theOther->BackgroundImageStyle());
1081 SetTextureEnv (theOther->TextureEnv());
1082 SetShadingModel (theOther->ShadingModel());
1083 SetBackfacingModel (theOther->BackfacingModel());
1084 SetCamera (new Graphic3d_Camera (theOther->Camera()));
1085 SetLights (theOther->Lights());
1086 SetClipPlanes (theOther->ClipPlanes());
1089 // =======================================================================
1090 // function : SetShadingModel
1092 // =======================================================================
1093 void Graphic3d_CView::SetShadingModel (Graphic3d_TypeOfShadingModel theModel)
1095 if (theModel == Graphic3d_TOSM_DEFAULT)
1097 throw Standard_ProgramError ("Graphic3d_CView::SetShadingModel() - attempt to set invalid Shading Model!");
1100 myShadingModel = theModel;
1103 // =======================================================================
1104 // function : SetUnitFactor
1106 // =======================================================================
1107 void Graphic3d_CView::SetUnitFactor (Standard_Real theFactor)
1109 if (theFactor <= 0.0)
1111 throw Standard_ProgramError ("Graphic3d_CView::SetUnitFactor() - invalid unit factor");
1113 myUnitFactor = theFactor;
1114 if (!myXRSession.IsNull())
1116 myXRSession->SetUnitFactor (theFactor);
1120 // =======================================================================
1121 // function : IsActiveXR
1123 // =======================================================================
1124 bool Graphic3d_CView::IsActiveXR() const
1126 return !myXRSession.IsNull()
1127 && myXRSession->IsOpen();
1130 // =======================================================================
1131 // function : InitXR
1133 // =======================================================================
1134 bool Graphic3d_CView::InitXR()
1136 if (myXRSession.IsNull())
1138 myXRSession = new Aspect_OpenVRSession();
1139 myXRSession->SetUnitFactor (myUnitFactor);
1141 if (!myXRSession->IsOpen())
1143 myXRSession->Open();
1144 if (myBackXRCamera.IsNull())
1146 // backup camera properties
1147 myBackXRCamera = new Graphic3d_Camera (myCamera);
1150 return myXRSession->IsOpen();
1153 // =======================================================================
1154 // function : ReleaseXR
1156 // =======================================================================
1157 void Graphic3d_CView::ReleaseXR()
1159 if (!myXRSession.IsNull())
1161 if (myXRSession->IsOpen()
1162 && !myBackXRCamera.IsNull())
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();
1173 myXRSession->Close();
1177 //=======================================================================
1178 //function : ProcessXRInput
1180 //=======================================================================
1181 void Graphic3d_CView::ProcessXRInput()
1183 if (myRenderParams.StereoMode == Graphic3d_StereoMode_OpenVR
1184 && myCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo)
1195 myBaseXRCamera.Nullify();
1196 myPosedXRCamera.Nullify();
1200 myXRSession->ProcessEvents();
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);
1209 // VR APIs tend to decompose camera orientation-projection matrices into the following components:
1211 // Model * [View * Eye^-1] * [Projection]
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())
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));
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);
1230 myBaseXRCamera = myCamera;
1231 if (myPosedXRCamera.IsNull())
1233 myPosedXRCamera = new Graphic3d_Camera();
1235 SynchronizeXRBaseToPosedCamera();
1238 //=======================================================================
1239 //function : SynchronizeXRBaseToPosedCamera
1241 //=======================================================================
1242 void Graphic3d_CView::SynchronizeXRBaseToPosedCamera()
1244 if (!myPosedXRCamera.IsNull())
1246 ComputeXRPosedCameraFromBase (*myPosedXRCamera, myXRSession->HeadPose());
1250 //=======================================================================
1251 //function : ComputeXRPosedCameraFromBase
1253 //=======================================================================
1254 void Graphic3d_CView::ComputeXRPosedCameraFromBase (Graphic3d_Camera& theCam,
1255 const gp_Trsf& theXRTrsf) const
1257 theCam.Copy (myBaseXRCamera);
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());
1263 aTrsfCS.SetTransformation (aCameraCS, anAxVr);
1264 const gp_Trsf aTrsfToCamera = aTrsfCS * theXRTrsf * aTrsfCS.Inverted();
1266 aTrsfToEye.SetTranslation (myBaseXRCamera->Eye().XYZ());
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);
1277 //=======================================================================
1278 //function : SynchronizeXRPosedToBaseCamera
1280 //=======================================================================
1281 void Graphic3d_CView::SynchronizeXRPosedToBaseCamera()
1283 if (myPosedXRCameraCopy.IsNull()
1284 || myPosedXRCamera.IsNull()
1285 || myBaseXRCamera.IsNull()
1286 || myCamera != myPosedXRCamera)
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()))
1296 // avoid floating point math in case of no changes
1300 // re-compute myBaseXRCamera from myPosedXRCamera by applying reversed head pose transformation
1301 ComputeXRBaseCameraFromPosed (myPosedXRCamera, myXRSession->HeadPose());
1302 myPosedXRCameraCopy->Copy (myPosedXRCamera);
1305 //=======================================================================
1306 //function : ComputeXRBaseCameraFromPosed
1308 //=======================================================================
1309 void Graphic3d_CView::ComputeXRBaseCameraFromPosed (const Graphic3d_Camera& theCamPosed,
1310 const gp_Trsf& thePoseTrsf)
1312 const gp_Ax3 anAxVr (gp::Origin(), gp::DZ(), gp::DX());
1313 const gp_Ax3 aCameraCS (gp::Origin(), -myBaseXRCamera->Direction(), -myBaseXRCamera->SideRight());
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);
1326 //=======================================================================
1327 //function : TurnViewXRCamera
1329 //=======================================================================
1330 void Graphic3d_CView::TurnViewXRCamera (const gp_Trsf& theTrsfTurn)
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();
1339 aCamBase->SetDirectionFromEye (aCamBase->Direction().Transformed (theTrsfTurn));
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());
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);
1350 SynchronizeXRBaseToPosedCamera();
1353 //=======================================================================
1354 //function : SetupXRPosedCamera
1356 //=======================================================================
1357 void Graphic3d_CView::SetupXRPosedCamera()
1359 if (!myPosedXRCamera.IsNull())
1361 myCamera = myPosedXRCamera;
1362 if (myPosedXRCameraCopy.IsNull())
1364 myPosedXRCameraCopy = new Graphic3d_Camera();
1366 myPosedXRCameraCopy->Copy (myPosedXRCamera);
1370 //=======================================================================
1371 //function : UnsetXRPosedCamera
1373 //=======================================================================
1374 void Graphic3d_CView::UnsetXRPosedCamera()
1376 if (myCamera == myPosedXRCamera
1377 && !myBaseXRCamera.IsNull())
1379 SynchronizeXRPosedToBaseCamera();
1380 myCamera = myBaseXRCamera;
1384 //=======================================================================
1385 //function : DiagnosticInformation
1387 //=======================================================================
1388 void Graphic3d_CView::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
1389 Graphic3d_DiagnosticInfo theFlags) const
1391 if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0
1392 && !myXRSession.IsNull())
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()) + "]";
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;