1 // Copyright (c) 1999-2014 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 <V3d_View.hxx>
16 #include <Aspect_GradientBackground.hxx>
17 #include <Aspect_Grid.hxx>
18 #include <Aspect_Window.hxx>
19 #include <Bnd_Box.hxx>
23 #include <Graphic3d_AspectMarker3d.hxx>
24 #include <Graphic3d_GraphicDriver.hxx>
25 #include <Graphic3d_Group.hxx>
26 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
27 #include <Graphic3d_MapOfStructure.hxx>
28 #include <Graphic3d_Structure.hxx>
29 #include <Graphic3d_TextureEnv.hxx>
30 #include <Image_AlienPixMap.hxx>
31 #include <Message.hxx>
32 #include <Message_Messenger.hxx>
33 #include <NCollection_Array1.hxx>
34 #include <Precision.hxx>
35 #include <Quantity_Color.hxx>
36 #include <Standard_Assert.hxx>
37 #include <Standard_DivideByZero.hxx>
38 #include <Standard_ErrorHandler.hxx>
39 #include <Standard_MultiplyDefined.hxx>
40 #include <Standard_ShortReal.hxx>
41 #include <Standard_Type.hxx>
42 #include <Standard_TypeMismatch.hxx>
43 #include <TColgp_Array1OfPnt.hxx>
44 #include <TColStd_Array2OfReal.hxx>
45 #include <TColStd_HSequenceOfInteger.hxx>
47 #include <V3d_BadValue.hxx>
48 #include <V3d_Light.hxx>
49 #include <V3d_StereoDumpOptions.hxx>
50 #include <V3d_UnMapped.hxx>
51 #include <V3d_Viewer.hxx>
53 IMPLEMENT_STANDARD_RTTIEXT(V3d_View,Standard_Transient)
55 #define DEUXPI (2. * M_PI)
59 static const Standard_Integer THE_NB_BOUND_POINTS = 8;
62 //=============================================================================
63 //function : Constructor
65 //=============================================================================
66 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType)
67 : myIsInvalidatedImmediate (Standard_True),
68 MyViewer (theViewer.operator->()),
69 SwitchSetFront (Standard_False),
70 myZRotation (Standard_False),
71 myTrihedron (new V3d_Trihedron()),
74 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
76 myView->SetBackground (theViewer->GetBackgroundColor());
77 myView->SetGradientBackground (theViewer->GetGradientBackground());
79 ChangeRenderingParams() = theViewer->DefaultRenderingParams();
82 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
83 aCamera->SetFOVy (45.0);
84 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
85 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
86 aCamera->SetProjectionType ((theType == V3d_ORTHOGRAPHIC)
87 ? Graphic3d_Camera::Projection_Orthographic
88 : Graphic3d_Camera::Projection_Perspective);
90 myDefaultCamera = new Graphic3d_Camera();
92 myImmediateUpdate = Standard_False;
93 SetAutoZFitMode (Standard_True, 1.0);
94 SetBackFacingModel (V3d_TOBM_AUTOMATIC);
96 SetAxis (0.,0.,0.,1.,1.,1.);
97 SetVisualization (theViewer->DefaultVisualization());
98 SetShadingModel (theViewer->DefaultShadingModel());
101 SetProj (theViewer->DefaultViewProj());
102 SetSize (theViewer->DefaultViewSize());
103 Standard_Real zsize = theViewer->DefaultViewSize();
105 SetDepth (theViewer->DefaultViewSize() / 2.0);
106 SetViewMappingDefault();
107 SetViewOrientationDefault();
108 theViewer->AddView (this);
110 myImmediateUpdate = Standard_True;
113 //=============================================================================
114 //function : Constructor
116 //=============================================================================
117 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
118 : myIsInvalidatedImmediate (Standard_True),
119 MyViewer (theViewer.operator->()),
120 SwitchSetFront(Standard_False),
121 myZRotation (Standard_False),
124 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
126 myView->CopySettings (theView->View());
127 myDefaultViewPoint = theView->myDefaultViewPoint;
128 myDefaultViewAxis = theView->myDefaultViewAxis;
130 myDefaultCamera = new Graphic3d_Camera (theView->DefaultCamera());
132 myImmediateUpdate = Standard_False;
133 SetAutoZFitMode (theView->AutoZFitMode(), theView->AutoZFitScaleFactor());
134 theViewer->AddView (this);
136 myImmediateUpdate = Standard_True;
139 //=============================================================================
140 //function : Destructor
142 //=============================================================================
143 V3d_View::~V3d_View()
145 if (!myView->IsRemoved())
151 //=============================================================================
152 //function : SetMagnify
154 //=============================================================================
155 void V3d_View::SetMagnify (const Handle(Aspect_Window)& theWindow,
156 const Handle(V3d_View)& thePreviousView,
157 const Standard_Integer theX1,
158 const Standard_Integer theY1,
159 const Standard_Integer theX2,
160 const Standard_Integer theY2)
162 if (!myView->IsRemoved() && !myView->IsDefined())
164 Standard_Real aU1, aV1, aU2, aV2;
165 thePreviousView->Convert (theX1, theY1, aU1, aV1);
166 thePreviousView->Convert (theX2, theY2, aU2, aV2);
167 myView->SetWindow (theWindow);
168 FitAll (aU1, aV1, aU2, aV2);
169 MyViewer->SetViewOn (this);
170 MyWindow = theWindow;
173 SetViewMappingDefault();
177 //=============================================================================
178 //function : SetWindow
180 //=============================================================================
181 void V3d_View::SetWindow (const Handle(Aspect_Window)& theWindow,
182 const Aspect_RenderingContext theContext)
184 if (myView->IsRemoved())
189 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
190 MyWindow = theWindow;
191 myView->SetWindow (theWindow, theContext);
192 MyViewer->SetViewOn (this);
194 if (myImmediateUpdate)
200 //=============================================================================
203 //=============================================================================
204 void V3d_View::Remove() const
206 if (!MyGrid.IsNull())
210 if (!myTrihedron.IsNull())
212 myTrihedron->Erase();
215 MyViewer->DelView (this);
217 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
221 //=============================================================================
224 //=============================================================================
225 void V3d_View::Update() const
227 if (!myView->IsDefined()
228 || !myView->IsActive())
233 myIsInvalidatedImmediate = Standard_False;
240 //=============================================================================
243 //=============================================================================
244 void V3d_View::Redraw() const
246 if (!myView->IsDefined()
247 || !myView->IsActive())
252 myIsInvalidatedImmediate = Standard_False;
253 Handle(Graphic3d_StructureManager) aStructureMgr = MyViewer->StructureManager();
254 for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
256 if (aStructureMgr->IsDeviceLost())
258 aStructureMgr->RecomputeStructures();
265 if (!aStructureMgr->IsDeviceLost())
272 //=============================================================================
273 //function : RedrawImmediate
275 //=============================================================================
276 void V3d_View::RedrawImmediate() const
278 if (!myView->IsDefined()
279 || !myView->IsActive())
284 myIsInvalidatedImmediate = Standard_False;
285 myView->RedrawImmediate();
288 //=============================================================================
289 //function : Invalidate
291 //=============================================================================
292 void V3d_View::Invalidate() const
294 if (!myView->IsDefined())
299 myView->Invalidate();
302 //=============================================================================
303 //function : IsInvalidated
305 //=============================================================================
306 Standard_Boolean V3d_View::IsInvalidated() const
308 return !myView->IsDefined()
309 || myView->IsInvalidated();
312 // ========================================================================
313 // function : SetAutoZFitMode
315 // ========================================================================
316 void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn,
317 const Standard_Real theScaleFactor)
319 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
320 myAutoZFitScaleFactor = theScaleFactor;
321 myAutoZFitIsOn = theIsOn;
324 //=============================================================================
325 //function : AutoZFit
327 //=============================================================================
328 void V3d_View::AutoZFit() const
335 ZFitAll (myAutoZFitScaleFactor);
338 //=============================================================================
341 //=============================================================================
342 void V3d_View::ZFitAll (const Standard_Real theScaleFactor) const
344 Bnd_Box aMinMaxBox = myView->MinMaxValues (Standard_False); // applicative min max boundaries
345 Bnd_Box aGraphicBox = myView->MinMaxValues (Standard_True); // real graphical boundaries (not accounting infinite flag).
347 myView->Camera()->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
350 //=============================================================================
353 //=============================================================================
354 Standard_Boolean V3d_View::IsEmpty() const
356 Standard_Boolean TheStatus = Standard_True ;
357 if( myView->IsDefined() ) {
358 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
359 if( Nstruct > 0 ) TheStatus = Standard_False ;
364 //=============================================================================
365 //function : UpdateLights
367 //=============================================================================
368 void V3d_View::UpdateLights() const
370 Handle(Graphic3d_LightSet) aLights = new Graphic3d_LightSet();
371 for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
373 aLights->Add (anActiveLightIter.Value());
375 myView->SetLights (aLights);
378 //=============================================================================
379 //function : DoMapping
381 //=============================================================================
382 void V3d_View::DoMapping()
384 if (!myView->IsDefined())
389 myView->Window()->DoMapping();
392 //=============================================================================
393 //function : MustBeResized
395 //=============================================================================
396 void V3d_View::MustBeResized()
398 if (!myView->IsDefined())
406 if (myImmediateUpdate)
412 //=============================================================================
413 //function : SetBackgroundColor
415 //=============================================================================
416 void V3d_View::SetBackgroundColor (const Quantity_TypeOfColor theType,
417 const Standard_Real theV1,
418 const Standard_Real theV2,
419 const Standard_Real theV3)
421 Standard_Real aV1 = Max (Min (theV1, 1.0), 0.0);
422 Standard_Real aV2 = Max (Min (theV2, 1.0), 0.0);
423 Standard_Real aV3 = Max (Min (theV3, 1.0), 0.0);
425 SetBackgroundColor (Quantity_Color (aV1, aV2, aV3, theType));
428 //=============================================================================
429 //function : SetBackgroundColor
431 //=============================================================================
432 void V3d_View::SetBackgroundColor (const Quantity_Color& theColor)
434 myView->SetBackground (Aspect_Background (theColor));
436 if (myImmediateUpdate)
442 //=============================================================================
443 //function : SetBgGradientColors
445 //=============================================================================
446 void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
447 const Quantity_Color& theColor2,
448 const Aspect_GradientFillMethod theFillStyle,
449 const Standard_Boolean theToUpdate)
451 Aspect_GradientBackground aGradientBg (theColor1, theColor2, theFillStyle);
453 myView->SetGradientBackground (aGradientBg);
455 if (myImmediateUpdate || theToUpdate)
461 //=============================================================================
462 //function : SetBgGradientStyle
464 //=============================================================================
465 void V3d_View::SetBgGradientStyle (const Aspect_GradientFillMethod theFillStyle, const Standard_Boolean theToUpdate)
467 Quantity_Color aColor1;
468 Quantity_Color aColor2;
469 GradientBackground().Colors (aColor1, aColor2);
471 SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
474 //=============================================================================
475 //function : SetBackgroundImage
477 //=============================================================================
478 void V3d_View::SetBackgroundImage (const Standard_CString theFileName,
479 const Aspect_FillMethod theFillStyle,
480 const Standard_Boolean theToUpdate)
482 Handle(Graphic3d_Texture2D) aTextureMap = new Graphic3d_Texture2Dmanual (theFileName);
483 aTextureMap->DisableModulate();
484 SetBackgroundImage (aTextureMap, theFillStyle, theToUpdate);
487 //=============================================================================
488 //function : SetBackgroundImage
490 //=============================================================================
491 void V3d_View::SetBackgroundImage (const Handle(Graphic3d_Texture2D)& theTexture,
492 const Aspect_FillMethod theFillStyle,
493 const Standard_Boolean theToUpdate)
495 myView->SetBackgroundImage (theTexture);
496 myView->SetBackgroundImageStyle (theFillStyle);
497 if (myImmediateUpdate || theToUpdate)
503 //=============================================================================
504 //function : SetBgImageStyle
506 //=============================================================================
507 void V3d_View::SetBgImageStyle (const Aspect_FillMethod theFillStyle, const Standard_Boolean theToUpdate)
509 myView->SetBackgroundImageStyle (theFillStyle);
511 if (myImmediateUpdate || theToUpdate)
517 //=============================================================================
518 //function : SetBackgroundCubeMap
520 //=============================================================================
521 void V3d_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
522 Standard_Boolean theToUpdatePBREnv,
523 Standard_Boolean theToUpdate)
525 myView->SetBackgroundImage (theCubeMap, theToUpdatePBREnv);
526 if (myImmediateUpdate || theToUpdate)
532 //=============================================================================
533 //function : GeneratePBREnvironment
535 //=============================================================================
536 void V3d_View::GeneratePBREnvironment (Standard_Boolean theToUpdate)
538 myView->GeneratePBREnvironment();
539 if (myImmediateUpdate || theToUpdate)
545 //=============================================================================
546 //function : ClearPBREnvironment
548 //=============================================================================
549 void V3d_View::ClearPBREnvironment (Standard_Boolean theToUpdate)
551 myView->ClearPBREnvironment();
552 if (myImmediateUpdate || theToUpdate)
558 //=============================================================================
561 //=============================================================================
562 void V3d_View::SetAxis (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
563 const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
565 myDefaultViewPoint.SetCoord (theX, theY, theZ);
566 myDefaultViewAxis.SetCoord (theVx, theVy, theVz);
569 //=============================================================================
570 //function : SetShadingModel
572 //=============================================================================
573 void V3d_View::SetShadingModel (const Graphic3d_TypeOfShadingModel theShadingModel)
575 myView->SetShadingModel (theShadingModel);
578 //=============================================================================
579 //function : SetTextureEnv
581 //=============================================================================
582 void V3d_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTexture)
584 myView->SetTextureEnv (theTexture);
586 if (myImmediateUpdate)
592 //=============================================================================
593 //function : SetVisualization
595 //=============================================================================
596 void V3d_View::SetVisualization (const V3d_TypeOfVisualization theType)
598 myView->SetVisualizationType (static_cast <Graphic3d_TypeOfVisualization> (theType));
600 if (myImmediateUpdate)
606 //=============================================================================
607 //function : SetFront
609 //=============================================================================
610 void V3d_View::SetFront()
612 gp_Ax3 a = MyViewer->PrivilegedPlane();
613 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
615 a.Direction().Coord(vx,vy,vz);
616 a.YDirection().Coord(xu,yu,zu);
617 a.Location().Coord(xo,yo,zo);
619 Handle(Graphic3d_Camera) aCamera = Camera();
621 aCamera->SetCenter (gp_Pnt (xo, yo, zo));
625 aCamera->SetDirection (gp_Dir (vx, vy, vz));
629 aCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
632 aCamera->SetUp (gp_Dir (xu, yu, zu));
634 SwitchSetFront = !SwitchSetFront;
639 //=============================================================================
642 //=============================================================================
643 void V3d_View::Rotate (const Standard_Real ax,
644 const Standard_Real ay,
645 const Standard_Real az,
646 const Standard_Boolean Start)
648 Standard_Real Ax = ax;
649 Standard_Real Ay = ay;
650 Standard_Real Az = az;
652 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
653 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
654 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
655 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
656 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
657 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
659 Handle(Graphic3d_Camera) aCamera = Camera();
663 myCamStartOpUp = aCamera->Up();
664 myCamStartOpDir = aCamera->Direction();
665 myCamStartOpEye = aCamera->Eye();
666 myCamStartOpCenter = aCamera->Center();
669 aCamera->SetUp (myCamStartOpUp);
670 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
671 aCamera->SetDirectionFromEye (myCamStartOpDir);
673 // rotate camera around 3 initial axes
674 gp_Dir aBackDir = -myCamStartOpDir;
675 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
676 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
677 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
679 gp_Trsf aRot[3], aTrsf;
680 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
681 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
682 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
683 aTrsf.Multiply (aRot[0]);
684 aTrsf.Multiply (aRot[1]);
685 aTrsf.Multiply (aRot[2]);
687 aCamera->Transform (aTrsf);
692 //=============================================================================
695 //=============================================================================
696 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
697 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
700 Standard_Real Ax = ax ;
701 Standard_Real Ay = ay ;
702 Standard_Real Az = az ;
704 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
705 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
706 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
707 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
708 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
709 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
711 Handle(Graphic3d_Camera) aCamera = Camera();
715 myGravityReferencePoint.SetCoord (X, Y, Z);
716 myCamStartOpUp = aCamera->Up();
717 myCamStartOpDir = aCamera->Direction();
718 myCamStartOpEye = aCamera->Eye();
719 myCamStartOpCenter = aCamera->Center();
722 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
724 aCamera->SetUp (myCamStartOpUp);
725 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
726 aCamera->SetDirectionFromEye (myCamStartOpDir);
728 // rotate camera around 3 initial axes
729 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
731 gp_Dir aZAxis (aCamera->Direction().Reversed());
732 gp_Dir aYAxis (aCamera->Up());
733 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
735 gp_Trsf aRot[3], aTrsf;
736 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
737 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
738 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
739 aTrsf.Multiply (aRot[0]);
740 aTrsf.Multiply (aRot[1]);
741 aTrsf.Multiply (aRot[2]);
743 aCamera->Transform (aTrsf);
748 //=============================================================================
751 //=============================================================================
752 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
756 Rotate(angle,0.,0.,Start);
759 Rotate(0.,angle,0.,Start);
762 Rotate(0.,0.,angle,Start);
767 //=============================================================================
770 //=============================================================================
771 void V3d_View::Rotate (const V3d_TypeOfAxe theAxe, const Standard_Real theAngle,
772 const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ, const Standard_Boolean theStart)
774 Standard_Real anAngle = theAngle;
776 if (anAngle > 0.0) while (anAngle > DEUXPI) anAngle -= DEUXPI;
777 else if (anAngle < 0.0) while (anAngle < -DEUXPI) anAngle += DEUXPI;
779 Handle(Graphic3d_Camera) aCamera = Camera();
783 myGravityReferencePoint.SetCoord (theX, theY, theZ);
784 myCamStartOpUp = aCamera->Up();
785 myCamStartOpDir = aCamera->Direction();
786 myCamStartOpEye = aCamera->Eye();
787 myCamStartOpCenter = aCamera->Center();
790 case V3d_X: myViewAxis = gp::DX(); break;
791 case V3d_Y: myViewAxis = gp::DY(); break;
792 case V3d_Z: myViewAxis = gp::DZ(); break;
796 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
798 aCamera->SetUp (myCamStartOpUp);
799 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
800 aCamera->SetDirectionFromEye (myCamStartOpDir);
802 // rotate camera around passed axis
804 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
805 gp_Dir aRAxis ((theAxe == V3d_X) ? 1.0 : 0.0,
806 (theAxe == V3d_Y) ? 1.0 : 0.0,
807 (theAxe == V3d_Z) ? 1.0 : 0.0);
809 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), anAngle);
811 aCamera->Transform (aRotation);
816 //=============================================================================
819 //=============================================================================
820 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
822 Standard_Real Angle = angle;
824 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
825 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
827 Handle(Graphic3d_Camera) aCamera = Camera();
831 myCamStartOpUp = aCamera->Up();
832 myCamStartOpDir = aCamera->Direction();
833 myCamStartOpEye = aCamera->Eye();
834 myCamStartOpCenter = aCamera->Center();
837 aCamera->SetUp (myCamStartOpUp);
838 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
839 aCamera->SetDirectionFromEye (myCamStartOpDir);
842 gp_Pnt aRCenter (myDefaultViewPoint);
843 gp_Dir aRAxis (myDefaultViewAxis);
844 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
846 aCamera->Transform (aRotation);
851 //=============================================================================
854 //=============================================================================
855 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
857 Standard_Real Ax = ax;
858 Standard_Real Ay = ay;
859 Standard_Real Az = az;
861 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
862 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
863 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
864 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
865 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
866 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
868 Handle(Graphic3d_Camera) aCamera = Camera();
872 myCamStartOpUp = aCamera->Up();
873 myCamStartOpDir = aCamera->Direction();
874 myCamStartOpEye = aCamera->Eye();
875 myCamStartOpCenter = aCamera->Center();
878 aCamera->SetUp (myCamStartOpUp);
879 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
880 aCamera->SetDirectionFromEye (myCamStartOpDir);
882 // rotate camera around 3 initial axes
883 gp_Pnt aRCenter = aCamera->Eye();
884 gp_Dir aZAxis (aCamera->Direction().Reversed());
885 gp_Dir aYAxis (aCamera->Up());
886 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
888 gp_Trsf aRot[3], aTrsf;
889 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
890 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
891 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
892 aTrsf.Multiply (aRot[0]);
893 aTrsf.Multiply (aRot[1]);
894 aTrsf.Multiply (aRot[2]);
896 aCamera->Transform (aTrsf);
901 //=============================================================================
904 //=============================================================================
905 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
909 Turn(angle,0.,0.,Start);
912 Turn(0.,angle,0.,Start);
915 Turn(0.,0.,angle,Start);
920 //=============================================================================
923 //=============================================================================
924 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
926 Standard_Real Angle = angle ;
928 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
929 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
931 Handle(Graphic3d_Camera) aCamera = Camera();
935 myCamStartOpUp = aCamera->Up();
936 myCamStartOpDir = aCamera->Direction();
937 myCamStartOpEye = aCamera->Eye();
938 myCamStartOpCenter = aCamera->Center();
941 aCamera->SetUp (myCamStartOpUp);
942 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
943 aCamera->SetDirectionFromEye (myCamStartOpDir);
946 gp_Pnt aRCenter = aCamera->Eye();
947 gp_Dir aRAxis (myDefaultViewAxis);
948 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
950 aCamera->Transform (aRotation);
955 //=============================================================================
956 //function : SetTwist
958 //=============================================================================
959 void V3d_View::SetTwist(const Standard_Real angle)
961 Standard_Real Angle = angle ;
963 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
964 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
966 Handle(Graphic3d_Camera) aCamera = Camera();
968 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
969 if (!screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
970 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
971 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
973 throw V3d_BadValue ("V3d_ViewSetTwist, alignment of Eye,At,Up,");
976 gp_Pnt aRCenter = aCamera->Center();
977 gp_Dir aZAxis (aCamera->Direction().Reversed());
980 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
982 aCamera->SetUp (gp_Dir (myYscreenAxis));
983 aCamera->Transform (aTrsf);
988 //=============================================================================
991 //=============================================================================
992 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
994 Standard_Real aTwistBefore = Twist();
996 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
998 Handle(Graphic3d_Camera) aCamera = Camera();
1000 aCamera->SetEye (gp_Pnt (X, Y, Z));
1002 SetTwist (aTwistBefore);
1004 SetImmediateUpdate (wasUpdateEnabled);
1009 //=============================================================================
1010 //function : SetDepth
1012 //=============================================================================
1013 void V3d_View::SetDepth(const Standard_Real Depth)
1015 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1017 Handle(Graphic3d_Camera) aCamera = Camera();
1021 // Move eye using center (target) as anchor.
1022 aCamera->SetDistance (Depth);
1026 // Move the view ref point instead of the eye.
1027 gp_Vec aDir (aCamera->Direction());
1028 gp_Pnt aCameraEye = aCamera->Eye();
1029 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1031 aCamera->SetCenter (aCameraCenter);
1037 //=============================================================================
1038 //function : SetProj
1040 //=============================================================================
1041 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1043 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1044 "V3d_View::SetProj, null projection vector");
1046 Standard_Real aTwistBefore = Twist();
1048 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1050 Camera()->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1052 SetTwist(aTwistBefore);
1054 SetImmediateUpdate (wasUpdateEnabled);
1059 //=============================================================================
1060 //function : SetProj
1062 //=============================================================================
1063 void V3d_View::SetProj (const V3d_TypeOfOrientation theOrientation,
1064 const Standard_Boolean theIsYup)
1066 Graphic3d_Vec3d anUp = theIsYup ? Graphic3d_Vec3d (0.0, 1.0, 0.0) : Graphic3d_Vec3d (0.0, 0.0, 1.0);
1069 if (theOrientation == V3d_Ypos
1070 || theOrientation == V3d_Yneg)
1072 anUp.SetValues (0.0, 0.0, -1.0);
1077 if (theOrientation == V3d_Zpos)
1079 anUp.SetValues (0.0, 1.0, 0.0);
1081 else if (theOrientation == V3d_Zneg)
1083 anUp.SetValues (0.0, -1.0, 0.0);
1087 const gp_Dir aBck = V3d::GetProjAxis (theOrientation);
1089 // retain camera panning from origin when switching projection
1090 const Handle(Graphic3d_Camera)& aCamera = Camera();
1091 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
1093 const Standard_Real aNewDist = aCamera->Eye().Distance (gp_Pnt (0, 0, 0));
1094 aCamera->SetEyeAndCenter (gp_XYZ (0, 0, 0) + aBck.XYZ() * aNewDist,
1096 aCamera->SetDirectionFromEye (-aBck);
1097 aCamera->SetUp (gp_Dir (anUp.x(), anUp.y(), anUp.z()));
1098 aCamera->OrthogonalizeUp();
1100 Panning (anOriginVCS.X(), anOriginVCS.Y());
1105 //=============================================================================
1108 //=============================================================================
1109 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1111 Standard_Real aTwistBefore = Twist();
1113 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1115 Camera()->SetCenter (gp_Pnt (X, Y, Z));
1117 SetTwist (aTwistBefore);
1119 SetImmediateUpdate (wasUpdateEnabled);
1124 //=============================================================================
1127 //=============================================================================
1128 void V3d_View::SetUp (const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
1130 Handle(Graphic3d_Camera) aCamera = Camera();
1132 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1133 const gp_Dir anUp (theVx, theVy, theVz);
1134 if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis)
1135 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1136 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1137 && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1139 throw V3d_BadValue ("V3d_View::Setup, alignment of Eye,At,Up");
1142 aCamera->SetUp (gp_Dir (myYscreenAxis));
1147 //=============================================================================
1150 //=============================================================================
1151 void V3d_View::SetUp (const V3d_TypeOfOrientation theOrientation)
1153 Handle(Graphic3d_Camera) aCamera = Camera();
1155 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1156 const gp_Dir anUp = V3d::GetProjAxis (theOrientation);
1157 if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis)
1158 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1159 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1160 && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1162 throw V3d_BadValue ("V3d_View::SetUp, alignment of Eye,At,Up");
1165 aCamera->SetUp (gp_Dir (myYscreenAxis));
1170 //=============================================================================
1171 //function : SetViewOrientationDefault
1173 //=============================================================================
1174 void V3d_View::SetViewOrientationDefault()
1176 myDefaultCamera->CopyOrientationData (Camera());
1179 //=======================================================================
1180 //function : SetViewMappingDefault
1182 //=======================================================================
1183 void V3d_View::SetViewMappingDefault()
1185 myDefaultCamera->CopyMappingData (Camera());
1188 //=============================================================================
1189 //function : ResetViewOrientation
1191 //=============================================================================
1192 void V3d_View::ResetViewOrientation()
1194 Camera()->CopyOrientationData (myDefaultCamera);
1198 //=======================================================================
1199 //function : ResetViewMapping
1201 //=======================================================================
1202 void V3d_View::ResetViewMapping()
1204 Camera()->CopyMappingData (myDefaultCamera);
1208 //=============================================================================
1211 //=============================================================================
1212 void V3d_View::Reset (const Standard_Boolean theToUpdate)
1214 Camera()->Copy (myDefaultCamera);
1216 SwitchSetFront = Standard_False;
1218 if (myImmediateUpdate || theToUpdate)
1224 //=======================================================================
1225 //function : SetCenter
1227 //=======================================================================
1228 void V3d_View::SetCenter (const Standard_Integer theXp,
1229 const Standard_Integer theYp)
1231 Standard_Real aXv, aYv;
1232 Convert (theXp, theYp, aXv, aYv);
1233 Translate (Camera(), aXv, aYv);
1238 //=============================================================================
1239 //function : SetSize
1241 //=============================================================================
1242 void V3d_View::SetSize (const Standard_Real theSize)
1244 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1246 Handle(Graphic3d_Camera) aCamera = Camera();
1248 aCamera->SetScale (aCamera->Aspect() >= 1.0 ? theSize / aCamera->Aspect() : theSize);
1253 //=============================================================================
1254 //function : SetZSize
1256 //=============================================================================
1257 void V3d_View::SetZSize (const Standard_Real theSize)
1259 Handle(Graphic3d_Camera) aCamera = Camera();
1261 Standard_Real Zmax = theSize / 2.;
1263 Standard_Real aDistance = aCamera->Distance();
1270 // ShortReal precision factor used to add meaningful tolerance to
1271 // ZNear, ZFar values in order to avoid equality after type conversion
1272 // to ShortReal matrices type.
1273 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1275 Standard_Real aZFar = Zmax + aDistance * 2.0;
1276 Standard_Real aZNear = -Zmax + aDistance;
1277 aZNear -= Abs (aZNear) * aPrecision;
1278 aZFar += Abs (aZFar) * aPrecision;
1280 if (!aCamera->IsOrthographic())
1282 if (aZFar < aPrecision)
1284 // Invalid case when both values are negative
1285 aZNear = aPrecision;
1286 aZFar = aPrecision * 2.0;
1288 else if (aZNear < Abs (aZFar) * aPrecision)
1290 // Z is less than 0.0, try to fix it using any appropriate z-scale
1291 aZNear = Abs (aZFar) * aPrecision;
1295 // If range is too small
1296 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1298 aZFar = aZNear + Abs (aZFar) * aPrecision;
1301 aCamera->SetZRange (aZNear, aZFar);
1303 if (myImmediateUpdate)
1309 //=============================================================================
1310 //function : SetZoom
1312 //=============================================================================
1313 void V3d_View::SetZoom (const Standard_Real theCoef,const Standard_Boolean theToStart)
1315 V3d_BadValue_Raise_if (theCoef <= 0., "V3d_View::SetZoom, bad coefficient");
1317 Handle(Graphic3d_Camera) aCamera = Camera();
1321 myCamStartOpEye = aCamera->Eye();
1322 myCamStartOpCenter = aCamera->Center();
1325 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
1326 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
1328 // ensure that zoom will not be too small or too big
1329 Standard_Real aCoef = theCoef;
1330 if (aViewWidth < aCoef * Precision::Confusion())
1332 aCoef = aViewWidth / Precision::Confusion();
1334 else if (aViewWidth > aCoef * 1e12)
1336 aCoef = aViewWidth / 1e12;
1338 if (aViewHeight < aCoef * Precision::Confusion())
1340 aCoef = aViewHeight / Precision::Confusion();
1342 else if (aViewHeight > aCoef * 1e12)
1344 aCoef = aViewHeight / 1e12;
1347 aCamera->SetEye (myCamStartOpEye);
1348 aCamera->SetCenter (myCamStartOpCenter);
1349 aCamera->SetScale (aCamera->Scale() / aCoef);
1354 //=============================================================================
1355 //function : SetScale
1357 //=============================================================================
1358 void V3d_View::SetScale( const Standard_Real Coef )
1360 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1362 Handle(Graphic3d_Camera) aCamera = Camera();
1364 Standard_Real aDefaultScale = myDefaultCamera->Scale();
1365 aCamera->SetAspect (myDefaultCamera->Aspect());
1366 aCamera->SetScale (aDefaultScale / Coef);
1371 //=============================================================================
1372 //function : SetAxialScale
1374 //=============================================================================
1375 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1377 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1379 Camera()->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1382 //=============================================================================
1383 //function : SetRatio
1385 //=============================================================================
1386 void V3d_View::SetRatio()
1388 if (MyWindow.IsNull())
1393 Standard_Integer aWidth = 0;
1394 Standard_Integer aHeight = 0;
1395 MyWindow->Size (aWidth, aHeight);
1396 if (aWidth > 0 && aHeight > 0)
1398 Standard_Real aRatio = static_cast<Standard_Real> (aWidth) /
1399 static_cast<Standard_Real> (aHeight);
1401 Camera() ->SetAspect (aRatio);
1402 myDefaultCamera->SetAspect (aRatio);
1406 //=============================================================================
1409 //=============================================================================
1410 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1412 FitAll (myView->MinMaxValues(), theMargin, theToUpdate);
1415 //=============================================================================
1418 //=============================================================================
1419 void V3d_View::FitAll (const Bnd_Box& theBox, const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1421 Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1423 if (myView->NumberOfDisplayedStructures() == 0)
1428 if (!FitMinMax (Camera(), theBox, theMargin, 10.0 * Precision::Confusion()))
1433 if (myImmediateUpdate || theToUpdate)
1439 //=============================================================================
1440 //function : DepthFitAll
1442 //=============================================================================
1443 void V3d_View::DepthFitAll(const Standard_Real Aspect,
1444 const Standard_Real Margin)
1446 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1447 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1448 Standard_Real Dx,Dy,Dz,Size;
1450 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1452 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1457 Bnd_Box aBox = myView->MinMaxValues();
1463 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1464 Project (Xmin,Ymin,Zmin,U,V,W) ;
1465 Project (Xmax,Ymax,Zmax,U1,V1,W1) ;
1466 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1467 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1468 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1469 Project (Xmin,Ymin,Zmax,U,V,W) ;
1470 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1471 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1472 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1473 Project (Xmax,Ymin,Zmax,U,V,W) ;
1474 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1475 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1476 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1477 Project (Xmax,Ymin,Zmin,U,V,W) ;
1478 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1479 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1480 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1481 Project (Xmax,Ymax,Zmin,U,V,W) ;
1482 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1483 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1484 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1485 Project (Xmin,Ymax,Zmax,U,V,W) ;
1486 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1487 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1488 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1489 Project (Xmin,Ymax,Zmin,U,V,W) ;
1490 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1491 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1492 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1495 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1496 Dz = 2.*Wmax + Margin * Wmax;
1498 // Compute depth value
1499 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1500 Dx += Margin * Dx; Dy += Margin * Dy;
1501 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1504 SetDepth( Aspect * Size / 2.);
1510 //=======================================================================
1511 //function : WindowFit
1513 //=======================================================================
1514 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1515 const Standard_Integer theMinYp,
1516 const Standard_Integer theMaxXp,
1517 const Standard_Integer theMaxYp)
1519 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1521 Handle(Graphic3d_Camera) aCamera = Camera();
1523 if (!aCamera->IsOrthographic())
1525 // normalize view coordinates
1526 Standard_Integer aWinWidth, aWinHeight;
1527 MyWindow->Size (aWinWidth, aWinHeight);
1529 // z coordinate of camera center
1530 Standard_Real aDepth = aCamera->Project (aCamera->Center()).Z();
1532 // camera projection coordinate are in NDC which are normalized [-1, 1]
1533 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1534 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1535 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1536 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1538 // compute camera panning
1539 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1540 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1541 gp_Pnt aPanTo = aCamera->ConvertProj2View (aFitCenter);
1542 gp_Pnt aPanFrom = aCamera->ConvertProj2View (aScreenCenter);
1543 gp_Vec aPanVec (aPanFrom, aPanTo);
1545 // compute section size
1546 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1547 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1548 gp_Pnt aViewBotLeft = aCamera->ConvertProj2View (aFitBotLeft);
1549 gp_Pnt aViewTopRight = aCamera->ConvertProj2View (aFitTopRight);
1551 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1552 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1554 Translate (aCamera, aPanVec.X(), -aPanVec.Y());
1555 Scale (aCamera, aUSize, aVSize);
1559 Standard_Real aX1, aY1, aX2, aY2;
1560 Convert (theMinXp, theMinYp, aX1, aY1);
1561 Convert (theMaxXp, theMaxYp, aX2, aY2);
1562 FitAll (aX1, aY1, aX2, aY2);
1565 SetImmediateUpdate (wasUpdateEnabled);
1570 //=======================================================================
1571 //function : ConvertToGrid
1573 //=======================================================================
1574 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1575 const Standard_Integer Yp,
1578 Standard_Real& Zg) const
1580 Graphic3d_Vertex aVrp;
1581 Standard_Real anX, anY, aZ;
1582 Convert (Xp, Yp, anX, anY, aZ);
1583 aVrp.SetCoord (anX, anY, aZ);
1585 if( MyViewer->Grid()->IsActive() ) {
1586 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1587 aNewVrp.Coord (Xg,Yg,Zg) ;
1589 aVrp.Coord (Xg,Yg,Zg) ;
1592 //=======================================================================
1593 //function : ConvertToGrid
1595 //=======================================================================
1596 void V3d_View::ConvertToGrid(const Standard_Real X,
1597 const Standard_Real Y,
1598 const Standard_Real Z,
1601 Standard_Real& Zg) const
1603 if( MyViewer->Grid()->IsActive() ) {
1604 Graphic3d_Vertex aVrp (X,Y,Z) ;
1605 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1606 aNewVrp.Coord(Xg,Yg,Zg) ;
1608 Xg = X; Yg = Y; Zg = Z;
1612 //=======================================================================
1613 //function : Convert
1615 //=======================================================================
1616 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1618 Standard_Integer aDxw, aDyw ;
1620 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1622 MyWindow->Size (aDxw, aDyw);
1623 Standard_Real aValue;
1625 gp_Pnt aViewDims = Camera()->ViewDimensions();
1626 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1631 //=======================================================================
1632 //function : Convert
1634 //=======================================================================
1635 void V3d_View::Convert(const Standard_Integer Xp,
1636 const Standard_Integer Yp,
1638 Standard_Real& Yv) const
1640 Standard_Integer aDxw, aDyw;
1642 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1644 MyWindow->Size (aDxw, aDyw);
1646 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1647 aPoint = Camera()->ConvertProj2View (aPoint);
1653 //=======================================================================
1654 //function : Convert
1656 //=======================================================================
1657 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1659 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1661 Standard_Integer aDxw, aDyw;
1662 MyWindow->Size (aDxw, aDyw);
1664 gp_Pnt aViewDims = Camera()->ViewDimensions();
1665 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1670 //=======================================================================
1671 //function : Convert
1673 //=======================================================================
1674 void V3d_View::Convert(const Standard_Real Xv,
1675 const Standard_Real Yv,
1676 Standard_Integer& Xp,
1677 Standard_Integer& Yp) const
1679 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1681 Standard_Integer aDxw, aDyw;
1682 MyWindow->Size (aDxw, aDyw);
1684 gp_Pnt aPoint (Xv, Yv, 0.0);
1685 aPoint = Camera()->ConvertView2Proj (aPoint);
1686 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1688 Xp = RealToInt (aPoint.X());
1689 Yp = RealToInt (aPoint.Y());
1692 //=======================================================================
1693 //function : Convert
1695 //=======================================================================
1696 void V3d_View::Convert(const Standard_Integer Xp,
1697 const Standard_Integer Yp,
1700 Standard_Real& Z) const
1702 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1703 Standard_Integer aHeight, aWidth;
1704 MyWindow->Size (aWidth, aHeight);
1706 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1707 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1708 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1710 gp_Pnt aResult = Camera()->UnProject (gp_Pnt (anX, anY, aZ));
1717 //=======================================================================
1718 //function : ConvertWithProj
1720 //=======================================================================
1721 void V3d_View::ConvertWithProj(const Standard_Integer theXp,
1722 const Standard_Integer theYp,
1723 Standard_Real& theX,
1724 Standard_Real& theY,
1725 Standard_Real& theZ,
1726 Standard_Real& theDx,
1727 Standard_Real& theDy,
1728 Standard_Real& theDz) const
1730 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1731 Standard_Integer aHeight = 0, aWidth = 0;
1732 MyWindow->Size (aWidth, aHeight);
1734 const Standard_Real anX = 2.0 * theXp / aWidth - 1.0;
1735 const Standard_Real anY = 2.0 * (aHeight - 1 - theYp) / aHeight - 1.0;
1736 const Standard_Real aZ = 2.0 * 0.0 - 1.0;
1738 const Handle(Graphic3d_Camera)& aCamera = Camera();
1739 const gp_Pnt aResult1 = aCamera->UnProject (gp_Pnt (anX, anY, aZ));
1740 const gp_Pnt aResult2 = aCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1742 theX = aResult1.X();
1743 theY = aResult1.Y();
1744 theZ = aResult1.Z();
1745 Graphic3d_Vec3d aNormDir (theX - aResult2.X(),
1746 theY - aResult2.Y(),
1747 theZ - aResult2.Z());
1748 aNormDir.Normalize();
1750 theDx = aNormDir.x();
1751 theDy = aNormDir.y();
1752 theDz = aNormDir.z();
1755 //=======================================================================
1756 //function : Convert
1758 //=======================================================================
1759 void V3d_View::Convert(const Standard_Real X,
1760 const Standard_Real Y,
1761 const Standard_Real Z,
1762 Standard_Integer& Xp,
1763 Standard_Integer& Yp) const
1765 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1766 Standard_Integer aHeight, aWidth;
1767 MyWindow->Size (aWidth, aHeight);
1769 gp_Pnt aPoint = Camera()->Project (gp_Pnt (X, Y, Z));
1771 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1772 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1775 //=======================================================================
1776 //function : Project
1778 //=======================================================================
1779 void V3d_View::Project (const Standard_Real theX,
1780 const Standard_Real theY,
1781 const Standard_Real theZ,
1782 Standard_Real& theXp,
1783 Standard_Real& theYp) const
1786 Project (theX, theY, theZ, theXp, theYp, aZp);
1789 //=======================================================================
1790 //function : Project
1792 //=======================================================================
1793 void V3d_View::Project (const Standard_Real theX,
1794 const Standard_Real theY,
1795 const Standard_Real theZ,
1796 Standard_Real& theXp,
1797 Standard_Real& theYp,
1798 Standard_Real& theZp) const
1800 Handle(Graphic3d_Camera) aCamera = Camera();
1802 gp_XYZ aViewSpaceDimensions = aCamera->ViewDimensions();
1803 Standard_Real aXSize = aViewSpaceDimensions.X();
1804 Standard_Real aYSize = aViewSpaceDimensions.Y();
1805 Standard_Real aZSize = aViewSpaceDimensions.Z();
1807 gp_Pnt aPoint = aCamera->Project (gp_Pnt (theX, theY, theZ));
1809 // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
1810 theXp = aPoint.X() * aXSize * 0.5;
1811 theYp = aPoint.Y() * aYSize * 0.5;
1812 theZp = aPoint.Z() * aZSize * 0.5;
1815 //=======================================================================
1816 //function : BackgroundColor
1818 //=======================================================================
1819 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1822 Standard_Real& V3) const
1824 Quantity_Color C = BackgroundColor() ;
1825 C.Values(V1,V2,V3,Type) ;
1828 //=======================================================================
1829 //function : BackgroundColor
1831 //=======================================================================
1832 Quantity_Color V3d_View::BackgroundColor() const
1834 return myView->Background().Color() ;
1837 //=======================================================================
1838 //function : GradientBackgroundColors
1840 //=======================================================================
1841 void V3d_View::GradientBackgroundColors (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1843 myView->GradientBackground().Colors (theColor1, theColor2);
1846 //=======================================================================
1847 //function : GradientBackground
1849 //=======================================================================
1850 Aspect_GradientBackground V3d_View::GradientBackground() const
1852 return myView->GradientBackground();
1855 //=======================================================================
1858 //=======================================================================
1859 Standard_Real V3d_View::Scale() const
1861 return myDefaultCamera->Scale() / Camera()->Scale();
1864 //=======================================================================
1865 //function : AxialScale
1867 //=======================================================================
1868 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1870 gp_Pnt anAxialScale = Camera()->AxialScale();
1871 Sx = anAxialScale.X();
1872 Sy = anAxialScale.Y();
1873 Sz = anAxialScale.Z();
1876 //=======================================================================
1879 //=======================================================================
1880 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1882 gp_Pnt aViewDims = Camera()->ViewDimensions();
1884 Width = aViewDims.X();
1885 Height = aViewDims.Y();
1888 //=======================================================================
1891 //=======================================================================
1892 Standard_Real V3d_View::ZSize() const
1894 gp_Pnt aViewDims = Camera()->ViewDimensions();
1896 return aViewDims.Z();
1899 //=======================================================================
1902 //=======================================================================
1903 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
1904 Standard_Real& Vmin,
1905 Standard_Real& Umax,
1906 Standard_Real& Vmax) const
1908 Standard_Real Wmin,Wmax,U,V,W ;
1909 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
1911 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1914 Bnd_Box aBox = myView->MinMaxValues();
1915 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1916 Project (Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
1917 Project (Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
1918 Project (Xmin,Ymin,Zmax,U,V,W) ;
1919 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1920 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1921 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1922 Project (Xmax,Ymin,Zmax,U,V,W) ;
1923 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1924 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1925 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1926 Project (Xmax,Ymin,Zmin,U,V,W) ;
1927 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1928 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1929 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1930 Project (Xmax,Ymax,Zmin,U,V,W) ;
1931 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1932 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1933 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1934 Project (Xmin,Ymax,Zmax,U,V,W) ;
1935 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1936 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1937 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1938 Project (Xmin,Ymax,Zmin,U,V,W) ;
1939 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1940 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1941 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1946 //=======================================================================
1949 //=======================================================================
1950 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
1951 Standard_Real& Ymin,
1952 Standard_Real& Zmin,
1953 Standard_Real& Xmax,
1954 Standard_Real& Ymax,
1955 Standard_Real& Zmax) const
1958 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
1959 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1962 Bnd_Box aBox = myView->MinMaxValues();
1963 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1968 //=======================================================================
1969 //function : GravityPoint
1971 //=======================================================================
1972 gp_Pnt V3d_View::GravityPoint() const
1974 Graphic3d_MapOfStructure aSetOfStructures;
1975 myView->DisplayedStructures (aSetOfStructures);
1977 Standard_Boolean hasSelection = Standard_False;
1978 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
1979 aStructIter.More(); aStructIter.Next())
1981 if (aStructIter.Key()->IsHighlighted()
1982 && aStructIter.Key()->IsVisible())
1984 hasSelection = Standard_True;
1989 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
1990 Standard_Integer aNbPoints = 0;
1991 gp_XYZ aResult (0.0, 0.0, 0.0);
1992 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
1993 aStructIter.More(); aStructIter.Next())
1995 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
1996 if (!aStruct->IsVisible()
1997 || aStruct->IsInfinite()
1998 || (hasSelection && !aStruct->IsHighlighted()))
2003 const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox();
2004 if (!aBox.IsValid())
2009 // skip transformation-persistent objects
2010 if (!aStruct->TransformPersistence().IsNull())
2015 // use camera projection to find gravity point
2016 Xmin = aBox.CornerMin().x();
2017 Ymin = aBox.CornerMin().y();
2018 Zmin = aBox.CornerMin().z();
2019 Xmax = aBox.CornerMax().x();
2020 Ymax = aBox.CornerMax().y();
2021 Zmax = aBox.CornerMax().z();
2022 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2024 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2025 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2026 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2027 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2030 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2032 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2033 const gp_Pnt aProjected = Camera()->Project (aBndPnt);
2034 if (Abs (aProjected.X()) <= 1.0
2035 && Abs (aProjected.Y()) <= 1.0)
2037 aResult += aBndPnt.XYZ();
2045 // fallback - just use bounding box of entire scene
2046 Bnd_Box aBox = myView->MinMaxValues();
2049 aBox.Get (Xmin, Ymin, Zmin,
2051 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2053 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2054 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2055 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2056 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2059 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2061 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2062 aResult += aBndPnt.XYZ();
2070 aResult /= aNbPoints;
2076 //=======================================================================
2079 //=======================================================================
2080 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2082 gp_Pnt aCameraEye = Camera()->Eye();
2088 //=============================================================================
2089 //function : ProjReferenceAxe
2091 //=============================================================================
2092 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2093 const Standard_Integer Ypix,
2099 Standard_Real& VZ) const
2101 Standard_Real Xo,Yo,Zo;
2103 Convert (Xpix, Ypix, XP, YP, ZP);
2104 if ( Type() == V3d_PERSPECTIVE )
2106 FocalReferencePoint (Xo,Yo,Zo);
2117 //=============================================================================
2120 //=============================================================================
2121 Standard_Real V3d_View::Depth() const
2123 return Camera()->Distance();
2126 //=============================================================================
2129 //=============================================================================
2130 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2132 gp_Dir aCameraDir = Camera()->Direction().Reversed();
2133 Dx = aCameraDir.X();
2134 Dy = aCameraDir.Y();
2135 Dz = aCameraDir.Z();
2138 //=============================================================================
2141 //=============================================================================
2142 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2144 gp_Pnt aCameraCenter = Camera()->Center();
2145 X = aCameraCenter.X();
2146 Y = aCameraCenter.Y();
2147 Z = aCameraCenter.Z();
2150 //=============================================================================
2153 //=============================================================================
2154 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2156 gp_Dir aCameraUp = Camera()->Up();
2162 //=============================================================================
2165 //=============================================================================
2166 Standard_Real V3d_View::Twist() const
2168 gp_Vec Xaxis, Yaxis, Zaxis;
2169 const gp_Dir aReferencePlane (Camera()->Direction().Reversed());
2170 if (!screenAxis (aReferencePlane, gp::DZ(), Xaxis, Yaxis, Zaxis)
2171 && !screenAxis (aReferencePlane, gp::DY(), Xaxis, Yaxis, Zaxis)
2172 && !screenAxis (aReferencePlane, gp::DX(), Xaxis, Yaxis, Zaxis))
2177 // Compute Cross Vector From Up & Origin
2178 const gp_Dir aCameraUp = Camera()->Up();
2179 const gp_XYZ aP = Yaxis.XYZ().Crossed (aCameraUp.XYZ());
2182 Standard_Real anAngle = ASin (Max (Min (aP.Modulus(), 1.0), -1.0));
2183 if (Yaxis.Dot (aCameraUp.XYZ()) < 0.0)
2185 anAngle = M_PI - anAngle;
2190 const gp_Dir aProjDir = Camera()->Direction().Reversed();
2191 if (aP.Dot (aProjDir.XYZ()) < 0.0)
2193 anAngle = DEUXPI - anAngle;
2199 //=============================================================================
2200 //function : ShadingModel
2202 //=============================================================================
2203 Graphic3d_TypeOfShadingModel V3d_View::ShadingModel() const
2205 return myView->ShadingModel();
2208 //=============================================================================
2209 //function : TextureEnv
2211 //=============================================================================
2212 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2214 return myView->TextureEnv();
2217 //=============================================================================
2218 //function : Visualization
2220 //=============================================================================
2221 V3d_TypeOfVisualization V3d_View::Visualization() const
2223 return static_cast<V3d_TypeOfVisualization> (myView->VisualizationType());
2226 //=============================================================================
2227 //function : IfWindow
2229 //=============================================================================
2230 Standard_Boolean V3d_View::IfWindow() const
2232 return myView->IsDefined();
2235 //=============================================================================
2238 //=============================================================================
2239 V3d_TypeOfView V3d_View::Type() const
2241 return Camera()->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2244 //=============================================================================
2245 //function : SetFocale
2247 //=============================================================================
2248 void V3d_View::SetFocale( const Standard_Real focale )
2250 Handle(Graphic3d_Camera) aCamera = Camera();
2252 if (aCamera->IsOrthographic())
2257 Standard_Real aFOVyRad = ATan (focale / (aCamera->Distance() * 2.0));
2259 aCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2264 //=============================================================================
2267 //=============================================================================
2268 Standard_Real V3d_View::Focale() const
2270 Handle(Graphic3d_Camera) aCamera = Camera();
2272 if (aCamera->IsOrthographic())
2277 return aCamera->Distance() * 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
2280 //=============================================================================
2281 //function : screenAxis
2283 //=============================================================================
2284 Standard_Boolean V3d_View::screenAxis (const gp_Dir& theVpn, const gp_Dir& theVup,
2285 gp_Vec& theXaxe, gp_Vec& theYaxe, gp_Vec& theZaxe)
2287 theXaxe = theVup.XYZ().Crossed (theVpn.XYZ());
2288 if (theXaxe.Magnitude() <= gp::Resolution())
2290 return Standard_False;
2292 theXaxe.Normalize();
2294 theYaxe = theVpn.XYZ().Crossed (theXaxe.XYZ());
2295 if (theYaxe.Magnitude() <= gp::Resolution())
2297 return Standard_False;
2299 theYaxe.Normalize();
2301 theZaxe = theVpn.XYZ();
2302 theZaxe.Normalize();
2303 return Standard_True;
2306 //=============================================================================
2307 //function : TrsPoint
2309 //=============================================================================
2310 gp_XYZ V3d_View::TrsPoint (const Graphic3d_Vertex& thePnt, const TColStd_Array2OfReal& theMat)
2313 const Standard_Integer lr = theMat.LowerRow();
2314 const Standard_Integer ur = theMat.UpperRow();
2315 const Standard_Integer lc = theMat.LowerCol();
2316 const Standard_Integer uc = theMat.UpperCol();
2317 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4))
2319 return gp_XYZ (thePnt.X(), thePnt.Y(), thePnt.Z());
2322 Standard_Real X, Y, Z;
2323 thePnt.Coord (X,Y,Z);
2324 const Standard_Real XX = (theMat(lr,lc+3) + X*theMat(lr,lc) + Y*theMat(lr,lc+1) + Z*theMat(lr,lc+2)) / theMat(lr+3,lc+3);
2325 const Standard_Real YY = (theMat(lr+1,lc+3) + X*theMat(lr+1,lc) + Y*theMat(lr+1,lc+1) + Z*theMat(lr+1,lc+2))/theMat(lr+3,lc+3);
2326 const Standard_Real ZZ = (theMat(lr+2,lc+3) + X*theMat(lr+2,lc) + Y*theMat(lr+2,lc+1) + Z*theMat(lr+2,lc+2))/theMat(lr+3,lc+3);
2327 return gp_XYZ (XX, YY, ZZ);
2330 //=======================================================================
2333 //=======================================================================
2334 void V3d_View::Pan (const Standard_Integer theDXp,
2335 const Standard_Integer theDYp,
2336 const Standard_Real theZoomFactor,
2337 const Standard_Boolean theToStart)
2339 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2342 //=======================================================================
2343 //function : Panning
2345 //=======================================================================
2346 void V3d_View::Panning (const Standard_Real theDXv,
2347 const Standard_Real theDYv,
2348 const Standard_Real theZoomFactor,
2349 const Standard_Boolean theToStart)
2351 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2353 Handle(Graphic3d_Camera) aCamera = Camera();
2357 myCamStartOpDir = aCamera->Direction();
2358 myCamStartOpEye = aCamera->Eye();
2359 myCamStartOpCenter = aCamera->Center();
2362 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2364 gp_Pnt aViewDims = aCamera->ViewDimensions();
2366 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
2367 aCamera->SetDirectionFromEye (myCamStartOpDir);
2368 Translate (aCamera, -theDXv, -theDYv);
2369 Scale (aCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2371 SetImmediateUpdate (wasUpdateEnabled);
2376 //=======================================================================
2379 //=======================================================================
2380 void V3d_View::Zoom (const Standard_Integer theXp1,
2381 const Standard_Integer theYp1,
2382 const Standard_Integer theXp2,
2383 const Standard_Integer theYp2)
2385 Standard_Integer aDx = theXp2 - theXp1;
2386 Standard_Integer aDy = theYp2 - theYp1;
2387 if (aDx != 0 || aDy != 0)
2389 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2390 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2391 SetZoom (aCoeff, Standard_True);
2395 //=======================================================================
2396 //function : StartZoomAtPoint
2398 //=======================================================================
2399 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2400 const Standard_Integer theYp)
2402 MyZoomAtPointX = theXp;
2403 MyZoomAtPointY = theYp;
2406 //=======================================================================
2407 //function : ZoomAtPoint
2409 //=======================================================================
2410 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2411 const Standard_Integer theMouseStartY,
2412 const Standard_Integer theMouseEndX,
2413 const Standard_Integer theMouseEndY)
2415 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2418 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2419 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2420 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2422 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2424 Handle(Graphic3d_Camera) aCamera = Camera();
2426 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
2427 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
2429 // ensure that zoom will not be too small or too big.
2430 Standard_Real aCoef = aDZoom;
2431 if (aViewWidth < aCoef * Precision::Confusion())
2433 aCoef = aViewWidth / Precision::Confusion();
2435 else if (aViewWidth > aCoef * 1e12)
2437 aCoef = aViewWidth / 1e12;
2439 if (aViewHeight < aCoef * Precision::Confusion())
2441 aCoef = aViewHeight / Precision::Confusion();
2443 else if (aViewHeight > aCoef * 1e12)
2445 aCoef = aViewHeight / 1e12;
2448 Standard_Real aZoomAtPointXv = 0.0;
2449 Standard_Real aZoomAtPointYv = 0.0;
2450 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2452 Standard_Real aDxv = aZoomAtPointXv / aCoef;
2453 Standard_Real aDyv = aZoomAtPointYv / aCoef;
2455 aCamera->SetScale (aCamera->Scale() / aCoef);
2456 Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2458 SetImmediateUpdate (wasUpdateEnabled);
2463 //=============================================================================
2464 //function : AxialScale
2466 //=============================================================================
2467 void V3d_View::AxialScale (const Standard_Integer Dx,
2468 const Standard_Integer Dy,
2469 const V3d_TypeOfAxe Axis)
2471 if( Dx != 0. || Dy != 0. ) {
2472 Standard_Real Sx, Sy, Sz;
2473 AxialScale( Sx, Sy, Sz );
2474 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2475 dscale = (Dx > 0) ? dscale : 1./dscale;
2476 if( Axis == V3d_X ) Sx = dscale;
2477 if( Axis == V3d_Y ) Sy = dscale;
2478 if( Axis == V3d_Z ) Sz = dscale;
2479 SetAxialScale( Sx, Sy, Sz );
2483 //=============================================================================
2486 //=============================================================================
2487 void V3d_View::FitAll(const Standard_Real theXmin,
2488 const Standard_Real theYmin,
2489 const Standard_Real theXmax,
2490 const Standard_Real theYmax)
2492 Handle(Graphic3d_Camera) aCamera = Camera();
2493 Standard_Real anAspect = aCamera->Aspect();
2495 Standard_Real aFitSizeU = Abs (theXmax - theXmin);
2496 Standard_Real aFitSizeV = Abs (theYmax - theYmin);
2497 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2498 if (aFitAspect >= anAspect)
2500 aFitSizeV = aFitSizeU / anAspect;
2504 aFitSizeU = aFitSizeV * anAspect;
2507 Translate (aCamera, (theXmin + theXmax) * 0.5, (theYmin + theYmax) * 0.5);
2508 Scale (aCamera, aFitSizeU, aFitSizeV);
2513 //=============================================================================
2514 //function : StartRotation
2516 //=============================================================================
2517 void V3d_View::StartRotation(const Standard_Integer X,
2518 const Standard_Integer Y,
2519 const Standard_Real zRotationThreshold)
2524 rx = Standard_Real(Convert(x));
2525 ry = Standard_Real(Convert(y));
2526 myRotateGravity = GravityPoint();
2527 Rotate (0.0, 0.0, 0.0,
2528 myRotateGravity.X(), myRotateGravity.Y(), myRotateGravity.Z(),
2530 myZRotation = Standard_False;
2531 if( zRotationThreshold > 0. ) {
2532 Standard_Real dx = Abs(sx - rx/2.);
2533 Standard_Real dy = Abs(sy - ry/2.);
2534 // if( dx > rx/3. || dy > ry/3. ) myZRotation = Standard_True;
2535 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2536 if( dx > dd || dy > dd ) myZRotation = Standard_True;
2541 //=============================================================================
2542 //function : Rotation
2544 //=============================================================================
2545 void V3d_View::Rotation(const Standard_Integer X,
2546 const Standard_Integer Y)
2548 if( rx == 0. || ry == 0. ) {
2552 Standard_Real dx=0.,dy=0.,dz=0.;
2554 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2555 atan2(sx-rx/2.,ry/2.-sy);
2557 dx = (Standard_Real(X) - sx) * M_PI / rx;
2558 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2562 myRotateGravity.X(), myRotateGravity.Y(), myRotateGravity.Z(),
2566 //=============================================================================
2567 //function : SetComputedMode
2569 //=============================================================================
2570 void V3d_View::SetComputedMode (const Standard_Boolean theMode)
2576 myView->SetComputedMode (Standard_True);
2581 myView->SetComputedMode (Standard_False);
2585 //=============================================================================
2586 //function : ComputedMode
2588 //=============================================================================
2589 Standard_Boolean V3d_View::ComputedMode() const
2591 return myView->ComputedMode();
2594 //=============================================================================
2595 //function : SetBackFacingModel
2597 //=============================================================================
2598 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel theModel)
2600 myView->SetBackfacingModel (static_cast<Graphic3d_TypeOfBackfacingModel> (theModel));
2604 //=============================================================================
2605 //function : BackFacingModel
2607 //=============================================================================
2608 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2610 return static_cast<V3d_TypeOfBackfacingModel> (myView->BackfacingModel());
2613 //=============================================================================
2616 //=============================================================================
2617 void V3d_View::Init()
2619 myComputedMode = MyViewer->ComputedMode();
2620 if (!myComputedMode || !MyViewer->DefaultComputedMode())
2622 SetComputedMode (Standard_False);
2626 //=============================================================================
2629 //=============================================================================
2630 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2631 const Graphic3d_BufferType& theBufferType)
2633 Standard_Integer aWinWidth, aWinHeight;
2634 MyWindow->Size (aWinWidth, aWinHeight);
2635 Image_AlienPixMap anImage;
2637 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2640 //=============================================================================
2641 //function : ToPixMap
2643 //=============================================================================
2644 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
2645 const V3d_ImageDumpOptions& theParams)
2647 Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
2648 if (aTargetSize.x() != 0
2649 && aTargetSize.y() != 0)
2651 // allocate image buffer for dumping
2652 if (theImage.IsEmpty()
2653 || theImage.SizeX() != Standard_Size(aTargetSize.x())
2654 || theImage.SizeY() != Standard_Size(aTargetSize.y()))
2656 Image_Format aFormat = Image_Format_UNKNOWN;
2657 switch (theParams.BufferType)
2659 case Graphic3d_BT_RGB: aFormat = Image_Format_RGB; break;
2660 case Graphic3d_BT_RGBA: aFormat = Image_Format_RGBA; break;
2661 case Graphic3d_BT_Depth: aFormat = Image_Format_GrayF; break;
2662 case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF; break;
2663 case Graphic3d_BT_Red: aFormat = Image_Format_Gray; break;
2666 if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
2668 Message::SendFail (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y() + " for view dump");
2669 return Standard_False;
2673 if (theImage.IsEmpty())
2675 Message::SendFail ("V3d_View::ToPixMap() has been called without image dimensions");
2676 return Standard_False;
2678 aTargetSize.x() = (Standard_Integer )theImage.SizeX();
2679 aTargetSize.y() = (Standard_Integer )theImage.SizeY();
2681 Handle(Standard_Transient) aFBOPtr;
2682 Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
2683 Graphic3d_Vec2i aFBOVPSize = aTargetSize;
2685 bool isTiling = false;
2686 if (theParams.TileSize > 0)
2688 if (aFBOVPSize.x() > theParams.TileSize
2689 || aFBOVPSize.y() > theParams.TileSize)
2691 aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
2692 aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
2697 Graphic3d_Vec2i aPrevFBOVPSize;
2698 if (!aPrevFBOPtr.IsNull())
2700 Graphic3d_Vec2i aPrevFBOSizeMax;
2701 myView->FBOGetDimensions (aPrevFBOPtr,
2702 aPrevFBOVPSize.x(), aPrevFBOVPSize.y(),
2703 aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
2704 if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
2705 && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
2707 aFBOPtr = aPrevFBOPtr;
2711 if (aFBOPtr.IsNull())
2713 Standard_Integer aMaxTexSizeX = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeX);
2714 Standard_Integer aMaxTexSizeY = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeY);
2715 if (theParams.TileSize > aMaxTexSizeX
2716 || theParams.TileSize > aMaxTexSizeY)
2718 Message::SendFail (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
2719 + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")");
2720 return Standard_False;
2723 if (aFBOVPSize.x() > aMaxTexSizeX
2724 || aFBOVPSize.y() > aMaxTexSizeY)
2726 if (MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_IsWorkaroundFBO))
2728 Message::SendWarning ("Warning, workaround for Intel driver problem with empty FBO for images with big width is applied");
2730 Message::SendInfo (TCollection_AsciiString ("Info, tiling image dump is used, image size (")
2731 + aFBOVPSize.x() + "x" + aFBOVPSize.y() + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")");
2732 aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSizeX);
2733 aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSizeY);
2737 // Try to create hardware accelerated buffer
2738 aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
2740 myView->SetFBO (aFBOPtr);
2742 if (aFBOPtr.IsNull())
2744 // try to use on-screen buffer
2745 Graphic3d_Vec2i aWinSize;
2746 MyWindow->Size (aWinSize.x(), aWinSize.y());
2747 if (aFBOVPSize.x() != aWinSize.x()
2748 || aFBOVPSize.y() != aWinSize.y())
2752 aFBOVPSize = aWinSize;
2754 Message::SendWarning ("Warning, on screen buffer is used for image dump - content might be invalid");
2757 // backup camera parameters
2758 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2759 Handle(Graphic3d_Camera) aCamera = Camera();
2760 aStoreMapping->Copy (aCamera);
2761 if (aCamera->IsStereo())
2763 switch (theParams.StereoOptions)
2767 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2770 case V3d_SDO_LEFT_EYE:
2772 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2775 case V3d_SDO_RIGHT_EYE:
2777 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2780 case V3d_SDO_BLENDED:
2782 break; // dump as is
2786 if (theParams.ToAdjustAspect)
2788 aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
2791 // render immediate structures into back buffer rather than front
2792 const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
2794 Standard_Boolean isSuccess = Standard_True;
2797 if (!aFBOPtr.IsNull())
2799 myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
2802 isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
2806 Image_PixMap aTilePixMap;
2807 aTilePixMap.SetTopDown (theImage.IsTopDown());
2809 Graphic3d_Vec2i anOffset (0, 0);
2810 for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
2813 for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
2815 Graphic3d_CameraTile aTileUncropped;
2816 aTileUncropped.Offset = anOffset;
2817 aTileUncropped.TotalSize = aTargetSize;
2818 aTileUncropped.TileSize = aFBOVPSize;
2819 const Graphic3d_CameraTile aTile = aTileUncropped.Cropped();
2820 if (aTile.TileSize.x() < 1
2821 || aTile.TileSize.y() < 1)
2826 const Standard_Integer aLeft = aTile.Offset.x();
2827 Standard_Integer aBottom = aTile.Offset.y();
2828 if (theImage.IsTopDown())
2830 const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
2831 aBottom = aTargetSize.y() - aTop;
2833 aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
2834 + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
2835 aTile.TileSize.x(), aTile.TileSize.y(),
2836 theImage.SizeRowBytes());
2838 if (!aFBOPtr.IsNull())
2840 aCamera->SetTile (aTile);
2841 myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
2845 // no API to resize viewport of on-screen buffer - render uncropped
2846 aCamera->SetTile (aTileUncropped);
2849 isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
2863 myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
2864 aCamera->Copy (aStoreMapping);
2865 if (aFBOPtr != aPrevFBOPtr)
2867 myView->FBORelease (aFBOPtr);
2869 else if (!aPrevFBOPtr.IsNull())
2871 myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
2873 myView->SetFBO (aPrevFBOPtr);
2877 //=============================================================================
2878 //function : ImmediateUpdate
2880 //=============================================================================
2881 void V3d_View::ImmediateUpdate() const
2883 if (myImmediateUpdate)
2889 //=============================================================================
2890 //function : SetImmediateUpdate
2892 //=============================================================================
2893 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2895 Standard_Boolean aPreviousMode = myImmediateUpdate;
2896 myImmediateUpdate = theImmediateUpdate;
2897 return aPreviousMode;
2900 // =======================================================================
2901 // function : SetCamera
2903 // =======================================================================
2904 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2906 myView->SetCamera (theCamera);
2911 // =======================================================================
2912 // function : GetCamera
2914 // =======================================================================
2915 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
2917 return myView->Camera();
2920 // =======================================================================
2921 // function : FitMinMax
2922 // purpose : Internal
2923 // =======================================================================
2924 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
2925 const Bnd_Box& theBox,
2926 const Standard_Real theMargin,
2927 const Standard_Real theResolution,
2928 const Standard_Boolean theToEnlargeIfLine) const
2930 // Check bounding box for validness
2931 if (theBox.IsVoid())
2933 return Standard_False; // bounding box is out of bounds...
2936 // Apply "axial scaling" to the bounding points.
2937 // It is not the best approach to make this scaling as a part of fit all operation,
2938 // but the axial scale is integrated into camera orientation matrix and the other
2939 // option is to perform frustum plane adjustment algorithm in view camera space,
2940 // which will lead to a number of additional world-view space conversions and
2941 // loosing precision as well.
2942 gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (theCamera->AxialScale());
2943 gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (theCamera->AxialScale());
2945 if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
2947 return Standard_False; // nothing to fit all
2950 // Prepare camera frustum planes.
2951 NCollection_Array1<gp_Pln> aFrustumPlane (1, 6);
2952 theCamera->Frustum (aFrustumPlane.ChangeValue (1),
2953 aFrustumPlane.ChangeValue (2),
2954 aFrustumPlane.ChangeValue (3),
2955 aFrustumPlane.ChangeValue (4),
2956 aFrustumPlane.ChangeValue (5),
2957 aFrustumPlane.ChangeValue (6));
2959 // Prepare camera up, side, direction vectors.
2960 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
2961 gp_Dir aCamDir = theCamera->Direction();
2962 gp_Dir aCamSide = aCamDir ^ aCamUp;
2964 // Prepare scene bounding box parameters.
2965 gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
2967 NCollection_Array1<gp_Pnt> aBndCorner (1, 8);
2968 aBndCorner.ChangeValue (1) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
2969 aBndCorner.ChangeValue (2) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
2970 aBndCorner.ChangeValue (3) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
2971 aBndCorner.ChangeValue (4) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
2972 aBndCorner.ChangeValue (5) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
2973 aBndCorner.ChangeValue (6) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
2974 aBndCorner.ChangeValue (7) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
2975 aBndCorner.ChangeValue (8) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
2977 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
2978 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
2979 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
2980 // set up perspective-correct camera projection matching the bounding box.
2981 // These steps support non-asymmetric transformations of view-projection space provided by camera.
2982 // The zooming can be done by calculating view plane size matching the bounding box at center of
2983 // the bounding box. The only limitation here is that the scale of camera should define size of
2984 // its view plane passing through the camera center, and the center of camera should be on the
2985 // same line with the center of bounding box.
2987 // The following method is applied:
2988 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
2989 // 2) Determine new location of frustum planes, "matching" the bounding box.
2990 // 3) Determine new camera projection vector using the normalized asymmetry.
2991 // 4) Determine new zooming in view space.
2993 // 1. Determine normalized projection asymmetry (if any).
2994 Standard_Real anAssymX = Tan (( aCamSide).Angle (aFrustumPlane (1).Axis().Direction()))
2995 - Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction()));
2996 Standard_Real anAssymY = Tan (( aCamUp) .Angle (aFrustumPlane (3).Axis().Direction()))
2997 - Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction()));
2999 // 2. Determine how far should be the frustum planes placed from center
3000 // of bounding box, in order to match the bounding box closely.
3001 NCollection_Array1<Standard_Real> aFitDistance (1, 6);
3002 aFitDistance.ChangeValue (1) = 0.0;
3003 aFitDistance.ChangeValue (2) = 0.0;
3004 aFitDistance.ChangeValue (3) = 0.0;
3005 aFitDistance.ChangeValue (4) = 0.0;
3006 aFitDistance.ChangeValue (5) = 0.0;
3007 aFitDistance.ChangeValue (6) = 0.0;
3009 for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
3011 // Measure distances from center of bounding box to its corners towards the frustum plane.
3012 const gp_Dir& aPlaneN = aFrustumPlane.ChangeValue (anI).Axis().Direction();
3014 Standard_Real& aFitDist = aFitDistance.ChangeValue (anI);
3016 for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
3018 aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner (aJ)).Dot (aPlaneN));
3021 // The center of camera is placed on the same line with center of bounding box.
3022 // The view plane section crosses the bounding box at its center.
3023 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3024 // into view section size between the point and the frustum plane.
3026 // /|\ right half of frame //
3028 // point o<-- distance * coeff -->//---- (view plane section)
3037 aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan ( aCamSide .Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
3038 aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
3039 aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan ( aCamUp .Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
3040 aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
3041 aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan ( aCamDir .Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
3042 aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan ((-aCamDir) .Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
3044 Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
3045 Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
3046 Standard_Real aViewSizeZv = aFitDistance (5) + aFitDistance (6);
3048 // 3. Place center of camera on the same line with center of bounding
3049 // box applying corresponding projection asymmetry (if any).
3050 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3051 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3052 Standard_Real anOffsetXv = (aFitDistance (2) - aFitDistance (1)) * 0.5 + anAssymXv;
3053 Standard_Real anOffsetYv = (aFitDistance (4) - aFitDistance (3)) * 0.5 + anAssymYv;
3054 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3055 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3056 gp_Pnt aCamNewCenter = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3058 gp_Trsf aCenterTrsf;
3059 aCenterTrsf.SetTranslation (theCamera->Center(), aCamNewCenter);
3060 theCamera->Transform (aCenterTrsf);
3061 theCamera->SetDistance (aFitDistance (6) + aFitDistance (5));
3063 // Bounding box collapses to a point or thin line going in depth of the screen
3064 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3066 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3068 return Standard_True; // This is just one point or line and zooming has no effect.
3071 // Looking along line and "theToEnlargeIfLine" is requested.
3072 // Fit view to see whole scene on rotation.
3073 aViewSizeXv = aViewSizeZv;
3074 aViewSizeYv = aViewSizeZv;
3077 Scale (theCamera, aViewSizeXv, aViewSizeYv);
3079 const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
3081 Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
3083 return Standard_True;
3086 // =======================================================================
3088 // purpose : Internal
3089 // =======================================================================
3090 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3091 const Standard_Real theSizeXv,
3092 const Standard_Real theSizeYv) const
3094 Standard_Real anAspect = theCamera->Aspect();
3097 theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
3101 theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
3105 // =======================================================================
3106 // function : Translate
3107 // purpose : Internal
3108 // =======================================================================
3109 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3110 const Standard_Real theDXv,
3111 const Standard_Real theDYv) const
3113 const gp_Pnt& aCenter = theCamera->Center();
3114 const gp_Dir& aDir = theCamera->Direction();
3115 const gp_Dir& anUp = theCamera->Up();
3116 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3118 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3119 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3120 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3122 aPanTrsf.SetTranslation (aCameraPan);
3124 theCamera->Transform (aPanTrsf);
3127 // =======================================================================
3128 // function : DiagnosticInformation
3130 // =======================================================================
3131 void V3d_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
3132 Graphic3d_DiagnosticInfo theFlags) const
3134 myView->DiagnosticInformation (theDict, theFlags);
3137 //=======================================================================
3138 //function : StatisticInformation
3140 //=======================================================================
3141 void V3d_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
3143 myView->StatisticInformation (theDict);
3146 // =======================================================================
3147 // function : StatisticInformation
3149 // =======================================================================
3150 TCollection_AsciiString V3d_View::StatisticInformation() const
3152 return myView->StatisticInformation();
3155 //=============================================================================
3156 //function : RenderingParams
3158 //=============================================================================
3159 const Graphic3d_RenderingParams& V3d_View::RenderingParams() const
3161 return myView->RenderingParams();
3164 //=============================================================================
3165 //function : ChangeRenderingParams
3167 //=============================================================================
3168 Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams()
3170 return myView->ChangeRenderingParams();
3173 // =======================================================================
3174 // function : DumpJson
3176 // =======================================================================
3177 void V3d_View::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
3179 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
3181 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myOldMouseX)
3182 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myOldMouseY)
3183 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCamStartOpUp)
3184 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCamStartOpDir)
3185 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCamStartOpEye)
3186 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCamStartOpCenter)
3187 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myDefaultCamera.get())
3188 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myView.get())
3189 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myImmediateUpdate)
3190 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsInvalidatedImmediate)
3192 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, MyViewer)
3193 for (V3d_ListOfLight::Iterator anIterator (myActiveLights); anIterator.More(); anIterator.Next())
3195 class Handle(Graphic3d_CLight)& anActiveLight = anIterator.Value();
3196 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, anActiveLight)
3198 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myDefaultViewAxis)
3199 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myDefaultViewPoint)
3200 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, MyWindow.get())
3201 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, sx)
3202 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, sy)
3203 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, rx)
3204 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, ry)
3205 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myRotateGravity)
3206 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myComputedMode)
3207 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, SwitchSetFront)
3208 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myZRotation)
3209 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, MyZoomAtPointX)
3210 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, MyZoomAtPointY)
3211 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myTrihedron.get())
3212 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, MyGrid.get())
3213 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &MyPlane)
3214 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, MyGridEchoStructure.get())
3215 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, MyGridEchoGroup.get())
3216 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myXscreenAxis)
3217 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myYscreenAxis)
3218 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myZscreenAxis)
3219 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myViewAxis)
3220 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myGravityReferencePoint)
3221 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAutoZFitIsOn)
3222 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAutoZFitScaleFactor)