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 : MyViewer (theViewer.operator->()),
68 SwitchSetFront (Standard_False),
69 myZRotation (Standard_False),
70 myTrihedron (new V3d_Trihedron()),
73 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
75 myView->SetBackground (theViewer->GetBackgroundColor());
76 myView->SetGradientBackground (theViewer->GetGradientBackground());
78 ChangeRenderingParams() = theViewer->DefaultRenderingParams();
81 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
82 aCamera->SetFOVy (45.0);
83 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
84 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
85 aCamera->SetProjectionType ((theType == V3d_ORTHOGRAPHIC)
86 ? Graphic3d_Camera::Projection_Orthographic
87 : Graphic3d_Camera::Projection_Perspective);
89 myDefaultCamera = new Graphic3d_Camera();
91 myImmediateUpdate = Standard_False;
92 SetAutoZFitMode (Standard_True, 1.0);
93 SetBackFacingModel (V3d_TOBM_AUTOMATIC);
95 SetAxis (0.,0.,0.,1.,1.,1.);
96 SetVisualization (theViewer->DefaultVisualization());
97 SetShadingModel (theViewer->DefaultShadingModel());
100 SetProj (theViewer->DefaultViewProj());
101 SetSize (theViewer->DefaultViewSize());
102 Standard_Real zsize = theViewer->DefaultViewSize();
104 SetDepth (theViewer->DefaultViewSize() / 2.0);
105 SetViewMappingDefault();
106 SetViewOrientationDefault();
107 theViewer->AddView (this);
109 myImmediateUpdate = Standard_True;
112 //=============================================================================
113 //function : Constructor
115 //=============================================================================
116 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
117 : MyViewer (theViewer.operator->()),
118 SwitchSetFront(Standard_False),
119 myZRotation (Standard_False),
122 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
124 myView->CopySettings (theView->View());
125 myDefaultViewPoint = theView->myDefaultViewPoint;
126 myDefaultViewAxis = theView->myDefaultViewAxis;
128 myDefaultCamera = new Graphic3d_Camera (theView->DefaultCamera());
130 myImmediateUpdate = Standard_False;
131 SetAutoZFitMode (theView->AutoZFitMode(), theView->AutoZFitScaleFactor());
132 theViewer->AddView (this);
134 myImmediateUpdate = Standard_True;
137 //=============================================================================
138 //function : Destructor
140 //=============================================================================
141 V3d_View::~V3d_View()
143 if (!myView->IsRemoved())
149 //=============================================================================
150 //function : SetMagnify
152 //=============================================================================
153 void V3d_View::SetMagnify (const Handle(Aspect_Window)& theWindow,
154 const Handle(V3d_View)& thePreviousView,
155 const Standard_Integer theX1,
156 const Standard_Integer theY1,
157 const Standard_Integer theX2,
158 const Standard_Integer theY2)
160 if (!myView->IsRemoved() && !myView->IsDefined())
162 Standard_Real aU1, aV1, aU2, aV2;
163 thePreviousView->Convert (theX1, theY1, aU1, aV1);
164 thePreviousView->Convert (theX2, theY2, aU2, aV2);
165 myView->SetWindow (theWindow);
166 FitAll (aU1, aV1, aU2, aV2);
167 MyViewer->SetViewOn (this);
168 MyWindow = theWindow;
171 SetViewMappingDefault();
175 //=============================================================================
176 //function : SetWindow
178 //=============================================================================
179 void V3d_View::SetWindow (const Handle(Aspect_Window)& theWindow,
180 const Aspect_RenderingContext theContext)
182 if (myView->IsRemoved())
187 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
188 MyWindow = theWindow;
189 myView->SetWindow (theWindow, theContext);
190 MyViewer->SetViewOn (this);
192 if (myImmediateUpdate)
198 //=============================================================================
201 //=============================================================================
202 void V3d_View::Remove() const
204 if (!MyGrid.IsNull())
208 if (!myTrihedron.IsNull())
210 myTrihedron->Erase();
213 MyViewer->DelView (this);
215 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
219 //=============================================================================
222 //=============================================================================
223 void V3d_View::Update() const
225 if (!myView->IsDefined()
226 || !myView->IsActive())
236 //=============================================================================
239 //=============================================================================
240 void V3d_View::Redraw() const
242 if (!myView->IsDefined()
243 || !myView->IsActive())
248 Handle(Graphic3d_StructureManager) aStructureMgr = MyViewer->StructureManager();
249 for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
251 if (aStructureMgr->IsDeviceLost())
253 aStructureMgr->RecomputeStructures();
260 if (!aStructureMgr->IsDeviceLost())
267 //=============================================================================
268 //function : RedrawImmediate
270 //=============================================================================
271 void V3d_View::RedrawImmediate() const
273 if (!myView->IsDefined()
274 || !myView->IsActive())
279 myView->RedrawImmediate();
282 //=============================================================================
283 //function : Invalidate
285 //=============================================================================
286 void V3d_View::Invalidate() const
288 if (!myView->IsDefined())
293 myView->Invalidate();
296 //=============================================================================
297 //function : IsInvalidated
299 //=============================================================================
300 Standard_Boolean V3d_View::IsInvalidated() const
302 return !myView->IsDefined()
303 || myView->IsInvalidated();
306 // ========================================================================
307 // function : SetAutoZFitMode
309 // ========================================================================
310 void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn,
311 const Standard_Real theScaleFactor)
313 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
314 myAutoZFitScaleFactor = theScaleFactor;
315 myAutoZFitIsOn = theIsOn;
318 //=============================================================================
319 //function : AutoZFit
321 //=============================================================================
322 void V3d_View::AutoZFit() const
329 ZFitAll (myAutoZFitScaleFactor);
332 //=============================================================================
335 //=============================================================================
336 void V3d_View::ZFitAll (const Standard_Real theScaleFactor) const
338 Bnd_Box aMinMaxBox = myView->MinMaxValues (Standard_False); // applicative min max boundaries
339 Bnd_Box aGraphicBox = myView->MinMaxValues (Standard_True); // real graphical boundaries (not accounting infinite flag).
341 myView->Camera()->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
344 //=============================================================================
347 //=============================================================================
348 Standard_Boolean V3d_View::IsEmpty() const
350 Standard_Boolean TheStatus = Standard_True ;
351 if( myView->IsDefined() ) {
352 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
353 if( Nstruct > 0 ) TheStatus = Standard_False ;
358 //=============================================================================
359 //function : UpdateLights
361 //=============================================================================
362 void V3d_View::UpdateLights() const
364 Handle(Graphic3d_LightSet) aLights = new Graphic3d_LightSet();
365 for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
367 aLights->Add (anActiveLightIter.Value());
369 myView->SetLights (aLights);
372 //=============================================================================
373 //function : DoMapping
375 //=============================================================================
376 void V3d_View::DoMapping()
378 if (!myView->IsDefined())
383 myView->Window()->DoMapping();
386 //=============================================================================
387 //function : MustBeResized
389 //=============================================================================
390 void V3d_View::MustBeResized()
392 if (!myView->IsDefined())
400 if (myImmediateUpdate)
406 //=============================================================================
407 //function : SetBackgroundColor
409 //=============================================================================
410 void V3d_View::SetBackgroundColor (const Quantity_TypeOfColor theType,
411 const Standard_Real theV1,
412 const Standard_Real theV2,
413 const Standard_Real theV3)
415 Standard_Real aV1 = Max (Min (theV1, 1.0), 0.0);
416 Standard_Real aV2 = Max (Min (theV2, 1.0), 0.0);
417 Standard_Real aV3 = Max (Min (theV3, 1.0), 0.0);
419 SetBackgroundColor (Quantity_Color (aV1, aV2, aV3, theType));
422 //=============================================================================
423 //function : SetBackgroundColor
425 //=============================================================================
426 void V3d_View::SetBackgroundColor (const Quantity_Color& theColor)
428 myView->SetBackground (Aspect_Background (theColor));
430 if (myImmediateUpdate)
436 //=============================================================================
437 //function : SetBgGradientColors
439 //=============================================================================
440 void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
441 const Quantity_Color& theColor2,
442 const Aspect_GradientFillMethod theFillStyle,
443 const Standard_Boolean theToUpdate)
445 Aspect_GradientBackground aGradientBg (theColor1, theColor2, theFillStyle);
447 myView->SetGradientBackground (aGradientBg);
449 if (myImmediateUpdate || theToUpdate)
455 //=============================================================================
456 //function : SetBgGradientStyle
458 //=============================================================================
459 void V3d_View::SetBgGradientStyle (const Aspect_GradientFillMethod theFillStyle, const Standard_Boolean theToUpdate)
461 Quantity_Color aColor1;
462 Quantity_Color aColor2;
463 GradientBackground().Colors (aColor1, aColor2);
465 SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
468 //=============================================================================
469 //function : SetBackgroundImage
471 //=============================================================================
472 void V3d_View::SetBackgroundImage (const Standard_CString theFileName,
473 const Aspect_FillMethod theFillStyle,
474 const Standard_Boolean theToUpdate)
476 myView->SetBackgroundImage (theFileName);
477 myView->SetBackgroundImageStyle (theFillStyle);
479 if (myImmediateUpdate || theToUpdate)
485 //=============================================================================
486 //function : SetBgImageStyle
488 //=============================================================================
489 void V3d_View::SetBgImageStyle (const Aspect_FillMethod theFillStyle, const Standard_Boolean theToUpdate)
491 myView->SetBackgroundImageStyle (theFillStyle);
493 if (myImmediateUpdate || theToUpdate)
499 //=============================================================================
502 //=============================================================================
503 void V3d_View::SetAxis (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
504 const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
506 myDefaultViewPoint.SetCoord (theX, theY, theZ);
507 myDefaultViewAxis.SetCoord (theVx, theVy, theVz);
510 //=============================================================================
511 //function : SetShadingModel
513 //=============================================================================
514 void V3d_View::SetShadingModel (const Graphic3d_TypeOfShadingModel theShadingModel)
516 myView->SetShadingModel (theShadingModel);
519 //=============================================================================
520 //function : SetTextureEnv
522 //=============================================================================
523 void V3d_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTexture)
525 myView->SetTextureEnv (theTexture);
527 if (myImmediateUpdate)
533 //=============================================================================
534 //function : SetVisualization
536 //=============================================================================
537 void V3d_View::SetVisualization (const V3d_TypeOfVisualization theType)
539 myView->SetVisualizationType (static_cast <Graphic3d_TypeOfVisualization> (theType));
541 if (myImmediateUpdate)
547 //=============================================================================
548 //function : SetFront
550 //=============================================================================
551 void V3d_View::SetFront()
553 gp_Ax3 a = MyViewer->PrivilegedPlane();
554 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
556 a.Direction().Coord(vx,vy,vz);
557 a.YDirection().Coord(xu,yu,zu);
558 a.Location().Coord(xo,yo,zo);
560 Handle(Graphic3d_Camera) aCamera = Camera();
562 aCamera->SetCenter (gp_Pnt (xo, yo, zo));
566 aCamera->SetDirection (gp_Dir (vx, vy, vz));
570 aCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
573 aCamera->SetUp (gp_Dir (xu, yu, zu));
577 SwitchSetFront = !SwitchSetFront;
582 //=============================================================================
585 //=============================================================================
586 void V3d_View::Rotate (const Standard_Real ax,
587 const Standard_Real ay,
588 const Standard_Real az,
589 const Standard_Boolean Start)
591 Standard_Real Ax = ax;
592 Standard_Real Ay = ay;
593 Standard_Real Az = az;
595 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
596 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
597 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
598 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
599 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
600 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
602 Handle(Graphic3d_Camera) aCamera = Camera();
606 myCamStartOpUp = aCamera->Up();
607 myCamStartOpEye = aCamera->Eye();
608 myCamStartOpCenter = aCamera->Center();
611 aCamera->SetUp (myCamStartOpUp);
612 aCamera->SetEye (myCamStartOpEye);
613 aCamera->SetCenter (myCamStartOpCenter);
615 // rotate camera around 3 initial axes
616 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
617 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
618 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
619 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
621 gp_Trsf aRot[3], aTrsf;
622 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
623 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
624 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
625 aTrsf.Multiply (aRot[0]);
626 aTrsf.Multiply (aRot[1]);
627 aTrsf.Multiply (aRot[2]);
629 aCamera->Transform (aTrsf);
636 //=============================================================================
639 //=============================================================================
640 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
641 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
644 Standard_Real Ax = ax ;
645 Standard_Real Ay = ay ;
646 Standard_Real Az = az ;
648 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
649 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
650 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
651 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
652 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
653 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
655 Handle(Graphic3d_Camera) aCamera = Camera();
659 myGravityReferencePoint.SetCoord (X, Y, Z);
660 myCamStartOpUp = aCamera->Up();
661 myCamStartOpEye = aCamera->Eye();
662 myCamStartOpCenter = aCamera->Center();
665 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
667 aCamera->SetUp (myCamStartOpUp);
668 aCamera->SetEye (myCamStartOpEye);
669 aCamera->SetCenter (myCamStartOpCenter);
671 // rotate camera around 3 initial axes
672 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
674 gp_Dir aZAxis (aCamera->Direction().Reversed());
675 gp_Dir aYAxis (aCamera->Up());
676 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
678 gp_Trsf aRot[3], aTrsf;
679 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
680 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
681 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
682 aTrsf.Multiply (aRot[0]);
683 aTrsf.Multiply (aRot[1]);
684 aTrsf.Multiply (aRot[2]);
686 aCamera->Transform (aTrsf);
693 //=============================================================================
696 //=============================================================================
697 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
701 Rotate(angle,0.,0.,Start);
704 Rotate(0.,angle,0.,Start);
707 Rotate(0.,0.,angle,Start);
712 //=============================================================================
715 //=============================================================================
716 void V3d_View::Rotate (const V3d_TypeOfAxe theAxe, const Standard_Real theAngle,
717 const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ, const Standard_Boolean theStart)
719 Standard_Real anAngle = theAngle;
721 if (anAngle > 0.0) while (anAngle > DEUXPI) anAngle -= DEUXPI;
722 else if (anAngle < 0.0) while (anAngle < -DEUXPI) anAngle += DEUXPI;
724 Handle(Graphic3d_Camera) aCamera = Camera();
728 myGravityReferencePoint.SetCoord (theX, theY, theZ);
729 myCamStartOpUp = aCamera->Up();
730 myCamStartOpEye = aCamera->Eye();
731 myCamStartOpCenter = aCamera->Center();
735 case V3d_X: myViewAxis = gp::DX(); break;
736 case V3d_Y: myViewAxis = gp::DY(); break;
737 case V3d_Z: myViewAxis = gp::DZ(); break;
740 myCamStartOpUp = aCamera->Up();
741 myCamStartOpEye = aCamera->Eye();
742 myCamStartOpCenter = aCamera->Center();
745 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
747 aCamera->SetUp (myCamStartOpUp);
748 aCamera->SetEye (myCamStartOpEye);
749 aCamera->SetCenter (myCamStartOpCenter);
751 // rotate camera around passed axis
753 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
754 gp_Dir aRAxis ((theAxe == V3d_X) ? 1.0 : 0.0,
755 (theAxe == V3d_Y) ? 1.0 : 0.0,
756 (theAxe == V3d_Z) ? 1.0 : 0.0);
758 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), anAngle);
760 aCamera->Transform (aRotation);
767 //=============================================================================
770 //=============================================================================
771 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
773 Standard_Real Angle = angle;
775 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
776 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
778 Handle(Graphic3d_Camera) aCamera = Camera();
781 myCamStartOpUp = aCamera->Up();
782 myCamStartOpEye = aCamera->Eye();
783 myCamStartOpCenter = aCamera->Center();
786 aCamera->SetUp (myCamStartOpUp);
787 aCamera->SetEye (myCamStartOpEye);
788 aCamera->SetCenter (myCamStartOpCenter);
791 gp_Pnt aRCenter (myDefaultViewPoint);
792 gp_Dir aRAxis (myDefaultViewAxis);
793 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
795 aCamera->Transform (aRotation);
802 //=============================================================================
805 //=============================================================================
806 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
808 Standard_Real Ax = ax;
809 Standard_Real Ay = ay;
810 Standard_Real Az = az;
812 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
813 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
814 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
815 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
816 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
817 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
819 Handle(Graphic3d_Camera) aCamera = Camera();
822 myCamStartOpUp = aCamera->Up();
823 myCamStartOpEye = aCamera->Eye();
824 myCamStartOpCenter = aCamera->Center();
827 aCamera->SetUp (myCamStartOpUp);
828 aCamera->SetEye (myCamStartOpEye);
829 aCamera->SetCenter (myCamStartOpCenter);
831 // rotate camera around 3 initial axes
832 gp_Pnt aRCenter = aCamera->Eye();
833 gp_Dir aZAxis (aCamera->Direction().Reversed());
834 gp_Dir aYAxis (aCamera->Up());
835 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
837 gp_Trsf aRot[3], aTrsf;
838 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
839 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
840 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
841 aTrsf.Multiply (aRot[0]);
842 aTrsf.Multiply (aRot[1]);
843 aTrsf.Multiply (aRot[2]);
845 aCamera->Transform (aTrsf);
852 //=============================================================================
855 //=============================================================================
856 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
860 Turn(angle,0.,0.,Start);
863 Turn(0.,angle,0.,Start);
866 Turn(0.,0.,angle,Start);
871 //=============================================================================
874 //=============================================================================
875 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
877 Standard_Real Angle = angle ;
879 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
880 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
882 Handle(Graphic3d_Camera) aCamera = Camera();
885 myCamStartOpUp = aCamera->Up();
886 myCamStartOpEye = aCamera->Eye();
887 myCamStartOpCenter = aCamera->Center();
890 aCamera->SetUp (myCamStartOpUp);
891 aCamera->SetEye (myCamStartOpEye);
892 aCamera->SetCenter (myCamStartOpCenter);
895 gp_Pnt aRCenter = aCamera->Eye();
896 gp_Dir aRAxis (myDefaultViewAxis);
897 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
899 aCamera->Transform (aRotation);
906 //=============================================================================
907 //function : SetTwist
909 //=============================================================================
910 void V3d_View::SetTwist(const Standard_Real angle)
912 Standard_Real Angle = angle ;
914 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
915 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
917 Handle(Graphic3d_Camera) aCamera = Camera();
919 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
920 if (!screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
921 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
922 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
924 throw V3d_BadValue ("V3d_ViewSetTwist, alignment of Eye,At,Up,");
927 gp_Pnt aRCenter = aCamera->Center();
928 gp_Dir aZAxis (aCamera->Direction().Reversed());
931 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
933 aCamera->SetUp (gp_Dir (myYscreenAxis));
934 aCamera->Transform (aTrsf);
941 //=============================================================================
944 //=============================================================================
945 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
947 Standard_Real aTwistBefore = Twist();
949 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
951 Handle(Graphic3d_Camera) aCamera = Camera();
953 aCamera->SetEye (gp_Pnt (X, Y, Z));
955 SetTwist (aTwistBefore);
959 SetImmediateUpdate (wasUpdateEnabled);
964 //=============================================================================
965 //function : SetDepth
967 //=============================================================================
968 void V3d_View::SetDepth(const Standard_Real Depth)
970 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
972 Handle(Graphic3d_Camera) aCamera = Camera();
976 // Move eye using center (target) as anchor.
977 aCamera->SetDistance (Depth);
981 // Move the view ref point instead of the eye.
982 gp_Vec aDir (aCamera->Direction());
983 gp_Pnt aCameraEye = aCamera->Eye();
984 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
986 aCamera->SetCenter (aCameraCenter);
994 //=============================================================================
997 //=============================================================================
998 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1000 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1001 "V3d_View::SetProj, null projection vector");
1003 Standard_Real aTwistBefore = Twist();
1005 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1007 Camera()->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1009 SetTwist(aTwistBefore);
1013 SetImmediateUpdate (wasUpdateEnabled);
1018 //=============================================================================
1019 //function : SetProj
1021 //=============================================================================
1022 void V3d_View::SetProj (const V3d_TypeOfOrientation theOrientation,
1023 const Standard_Boolean theIsYup)
1025 Graphic3d_Vec3d anUp = theIsYup ? Graphic3d_Vec3d (0.0, 1.0, 0.0) : Graphic3d_Vec3d (0.0, 0.0, 1.0);
1028 if (theOrientation == V3d_Ypos
1029 || theOrientation == V3d_Yneg)
1031 anUp.SetValues (0.0, 0.0, -1.0);
1036 if (theOrientation == V3d_Zpos)
1038 anUp.SetValues (0.0, 1.0, 0.0);
1040 else if (theOrientation == V3d_Zneg)
1042 anUp.SetValues (0.0, -1.0, 0.0);
1046 const gp_Dir aBck = V3d::GetProjAxis (theOrientation);
1048 // retain camera panning from origin when switching projection
1049 const Handle(Graphic3d_Camera)& aCamera = Camera();
1050 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
1052 aCamera->SetCenter (gp_Pnt (0, 0, 0));
1053 aCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1054 aCamera->SetUp (gp_Dir (anUp.x(), anUp.y(), anUp.z()));
1055 aCamera->OrthogonalizeUp();
1057 Panning (anOriginVCS.X(), anOriginVCS.Y());
1064 //=============================================================================
1067 //=============================================================================
1068 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1070 Standard_Real aTwistBefore = Twist();
1072 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1074 Camera()->SetCenter (gp_Pnt (X, Y, Z));
1076 SetTwist (aTwistBefore);
1080 SetImmediateUpdate (wasUpdateEnabled);
1085 //=============================================================================
1088 //=============================================================================
1089 void V3d_View::SetUp (const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
1091 Handle(Graphic3d_Camera) aCamera = Camera();
1093 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1094 const gp_Dir anUp (theVx, theVy, theVz);
1095 if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis)
1096 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1097 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1098 && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1100 throw V3d_BadValue ("V3d_View::Setup, alignment of Eye,At,Up");
1103 aCamera->SetUp (gp_Dir (myYscreenAxis));
1110 //=============================================================================
1113 //=============================================================================
1114 void V3d_View::SetUp (const V3d_TypeOfOrientation theOrientation)
1116 Handle(Graphic3d_Camera) aCamera = Camera();
1118 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1119 const gp_Dir anUp = V3d::GetProjAxis (theOrientation);
1120 if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis)
1121 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1122 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1123 && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1125 throw V3d_BadValue ("V3d_View::SetUp, alignment of Eye,At,Up");
1128 aCamera->SetUp (gp_Dir (myYscreenAxis));
1135 //=============================================================================
1136 //function : SetViewOrientationDefault
1138 //=============================================================================
1139 void V3d_View::SetViewOrientationDefault()
1141 myDefaultCamera->CopyOrientationData (Camera());
1144 //=======================================================================
1145 //function : SetViewMappingDefault
1147 //=======================================================================
1148 void V3d_View::SetViewMappingDefault()
1150 myDefaultCamera->CopyMappingData (Camera());
1153 //=============================================================================
1154 //function : ResetViewOrientation
1156 //=============================================================================
1157 void V3d_View::ResetViewOrientation()
1159 Camera()->CopyOrientationData (myDefaultCamera);
1166 //=======================================================================
1167 //function : ResetViewMapping
1169 //=======================================================================
1170 void V3d_View::ResetViewMapping()
1172 Camera()->CopyMappingData (myDefaultCamera);
1179 //=============================================================================
1182 //=============================================================================
1183 void V3d_View::Reset (const Standard_Boolean theToUpdate)
1185 Camera()->Copy (myDefaultCamera);
1189 SwitchSetFront = Standard_False;
1191 if (myImmediateUpdate || theToUpdate)
1197 //=======================================================================
1198 //function : SetCenter
1200 //=======================================================================
1201 void V3d_View::SetCenter (const Standard_Integer theXp,
1202 const Standard_Integer theYp)
1204 Standard_Real aXv, aYv;
1205 Convert (theXp, theYp, aXv, aYv);
1206 Translate (Camera(), aXv, aYv);
1211 //=============================================================================
1212 //function : SetSize
1214 //=============================================================================
1215 void V3d_View::SetSize (const Standard_Real theSize)
1217 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1219 Handle(Graphic3d_Camera) aCamera = Camera();
1221 aCamera->SetScale (aCamera->Aspect() >= 1.0 ? theSize / aCamera->Aspect() : theSize);
1228 //=============================================================================
1229 //function : SetZSize
1231 //=============================================================================
1232 void V3d_View::SetZSize (const Standard_Real theSize)
1234 Handle(Graphic3d_Camera) aCamera = Camera();
1236 Standard_Real Zmax = theSize / 2.;
1238 Standard_Real aDistance = aCamera->Distance();
1245 // ShortReal precision factor used to add meaningful tolerance to
1246 // ZNear, ZFar values in order to avoid equality after type conversion
1247 // to ShortReal matrices type.
1248 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1250 Standard_Real aZFar = Zmax + aDistance * 2.0;
1251 Standard_Real aZNear = -Zmax + aDistance;
1252 aZNear -= Abs (aZNear) * aPrecision;
1253 aZFar += Abs (aZFar) * aPrecision;
1255 if (!aCamera->IsOrthographic())
1257 if (aZFar < aPrecision)
1259 // Invalid case when both values are negative
1260 aZNear = aPrecision;
1261 aZFar = aPrecision * 2.0;
1263 else if (aZNear < Abs (aZFar) * aPrecision)
1265 // Z is less than 0.0, try to fix it using any appropriate z-scale
1266 aZNear = Abs (aZFar) * aPrecision;
1270 // If range is too small
1271 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1273 aZFar = aZNear + Abs (aZFar) * aPrecision;
1276 aCamera->SetZRange (aZNear, aZFar);
1278 if (myImmediateUpdate)
1284 //=============================================================================
1285 //function : SetZoom
1287 //=============================================================================
1288 void V3d_View::SetZoom (const Standard_Real theCoef,const Standard_Boolean theToStart)
1290 V3d_BadValue_Raise_if (theCoef <= 0., "V3d_View::SetZoom, bad coefficient");
1292 Handle(Graphic3d_Camera) aCamera = Camera();
1296 myCamStartOpEye = aCamera->Eye();
1297 myCamStartOpCenter = aCamera->Center();
1300 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
1301 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
1303 // ensure that zoom will not be too small or too big
1304 Standard_Real aCoef = theCoef;
1305 if (aViewWidth < aCoef * Precision::Confusion())
1307 aCoef = aViewWidth / Precision::Confusion();
1309 else if (aViewWidth > aCoef * 1e12)
1311 aCoef = aViewWidth / 1e12;
1313 if (aViewHeight < aCoef * Precision::Confusion())
1315 aCoef = aViewHeight / Precision::Confusion();
1317 else if (aViewHeight > aCoef * 1e12)
1319 aCoef = aViewHeight / 1e12;
1322 aCamera->SetEye (myCamStartOpEye);
1323 aCamera->SetCenter (myCamStartOpCenter);
1324 aCamera->SetScale (aCamera->Scale() / aCoef);
1331 //=============================================================================
1332 //function : SetScale
1334 //=============================================================================
1335 void V3d_View::SetScale( const Standard_Real Coef )
1337 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1339 Handle(Graphic3d_Camera) aCamera = Camera();
1341 Standard_Real aDefaultScale = myDefaultCamera->Scale();
1342 aCamera->SetAspect (myDefaultCamera->Aspect());
1343 aCamera->SetScale (aDefaultScale / Coef);
1350 //=============================================================================
1351 //function : SetAxialScale
1353 //=============================================================================
1354 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1356 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1358 Camera()->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1363 //=============================================================================
1364 //function : SetRatio
1366 //=============================================================================
1367 void V3d_View::SetRatio()
1369 if (MyWindow.IsNull())
1374 Standard_Integer aWidth = 0;
1375 Standard_Integer aHeight = 0;
1376 MyWindow->Size (aWidth, aHeight);
1377 if (aWidth > 0 && aHeight > 0)
1379 Standard_Real aRatio = static_cast<Standard_Real> (aWidth) /
1380 static_cast<Standard_Real> (aHeight);
1382 Camera() ->SetAspect (aRatio);
1383 myDefaultCamera->SetAspect (aRatio);
1387 //=============================================================================
1390 //=============================================================================
1391 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1393 FitAll (myView->MinMaxValues(), theMargin, theToUpdate);
1396 //=============================================================================
1399 //=============================================================================
1400 void V3d_View::FitAll (const Bnd_Box& theBox, const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1402 Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1404 if (myView->NumberOfDisplayedStructures() == 0)
1409 if (!FitMinMax (Camera(), theBox, theMargin, 10.0 * Precision::Confusion()))
1416 if (myImmediateUpdate || theToUpdate)
1422 //=============================================================================
1423 //function : DepthFitAll
1425 //=============================================================================
1426 void V3d_View::DepthFitAll(const Standard_Real Aspect,
1427 const Standard_Real Margin)
1429 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1430 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1431 Standard_Real Dx,Dy,Dz,Size;
1433 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1435 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1440 Bnd_Box aBox = myView->MinMaxValues();
1446 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1447 Project (Xmin,Ymin,Zmin,U,V,W) ;
1448 Project (Xmax,Ymax,Zmax,U1,V1,W1) ;
1449 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1450 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1451 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1452 Project (Xmin,Ymin,Zmax,U,V,W) ;
1453 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1454 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1455 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1456 Project (Xmax,Ymin,Zmax,U,V,W) ;
1457 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1458 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1459 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1460 Project (Xmax,Ymin,Zmin,U,V,W) ;
1461 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1462 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1463 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1464 Project (Xmax,Ymax,Zmin,U,V,W) ;
1465 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1466 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1467 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1468 Project (Xmin,Ymax,Zmax,U,V,W) ;
1469 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1470 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1471 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1472 Project (Xmin,Ymax,Zmin,U,V,W) ;
1473 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1474 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1475 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1478 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1479 Dz = 2.*Wmax + Margin * Wmax;
1481 // Compute depth value
1482 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1483 Dx += Margin * Dx; Dy += Margin * Dy;
1484 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1487 SetDepth( Aspect * Size / 2.);
1493 //=======================================================================
1494 //function : WindowFit
1496 //=======================================================================
1497 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1498 const Standard_Integer theMinYp,
1499 const Standard_Integer theMaxXp,
1500 const Standard_Integer theMaxYp)
1502 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1504 Handle(Graphic3d_Camera) aCamera = Camera();
1506 if (!aCamera->IsOrthographic())
1508 // normalize view coordinates
1509 Standard_Integer aWinWidth, aWinHeight;
1510 MyWindow->Size (aWinWidth, aWinHeight);
1512 // z coordinate of camera center
1513 Standard_Real aDepth = aCamera->Project (aCamera->Center()).Z();
1515 // camera projection coordinate are in NDC which are normalized [-1, 1]
1516 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1517 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1518 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1519 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1521 // compute camera panning
1522 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1523 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1524 gp_Pnt aPanTo = aCamera->ConvertProj2View (aFitCenter);
1525 gp_Pnt aPanFrom = aCamera->ConvertProj2View (aScreenCenter);
1526 gp_Vec aPanVec (aPanFrom, aPanTo);
1528 // compute section size
1529 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1530 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1531 gp_Pnt aViewBotLeft = aCamera->ConvertProj2View (aFitBotLeft);
1532 gp_Pnt aViewTopRight = aCamera->ConvertProj2View (aFitTopRight);
1534 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1535 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1537 Translate (aCamera, aPanVec.X(), -aPanVec.Y());
1538 Scale (aCamera, aUSize, aVSize);
1543 Standard_Real aX1, aY1, aX2, aY2;
1544 Convert (theMinXp, theMinYp, aX1, aY1);
1545 Convert (theMaxXp, theMaxYp, aX2, aY2);
1546 FitAll (aX1, aY1, aX2, aY2);
1549 SetImmediateUpdate (wasUpdateEnabled);
1554 //=======================================================================
1555 //function : ConvertToGrid
1557 //=======================================================================
1558 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1559 const Standard_Integer Yp,
1562 Standard_Real& Zg) const
1564 Graphic3d_Vertex aVrp;
1565 Standard_Real anX, anY, aZ;
1566 Convert (Xp, Yp, anX, anY, aZ);
1567 aVrp.SetCoord (anX, anY, aZ);
1569 if( MyViewer->Grid()->IsActive() ) {
1570 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1571 aNewVrp.Coord (Xg,Yg,Zg) ;
1573 aVrp.Coord (Xg,Yg,Zg) ;
1576 //=======================================================================
1577 //function : ConvertToGrid
1579 //=======================================================================
1580 void V3d_View::ConvertToGrid(const Standard_Real X,
1581 const Standard_Real Y,
1582 const Standard_Real Z,
1585 Standard_Real& Zg) const
1587 if( MyViewer->Grid()->IsActive() ) {
1588 Graphic3d_Vertex aVrp (X,Y,Z) ;
1589 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1590 aNewVrp.Coord(Xg,Yg,Zg) ;
1592 Xg = X; Yg = Y; Zg = Z;
1596 //=======================================================================
1597 //function : Convert
1599 //=======================================================================
1600 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1602 Standard_Integer aDxw, aDyw ;
1604 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1606 MyWindow->Size (aDxw, aDyw);
1607 Standard_Real aValue;
1609 gp_Pnt aViewDims = Camera()->ViewDimensions();
1610 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1615 //=======================================================================
1616 //function : Convert
1618 //=======================================================================
1619 void V3d_View::Convert(const Standard_Integer Xp,
1620 const Standard_Integer Yp,
1622 Standard_Real& Yv) const
1624 Standard_Integer aDxw, aDyw;
1626 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1628 MyWindow->Size (aDxw, aDyw);
1630 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1631 aPoint = Camera()->ConvertProj2View (aPoint);
1637 //=======================================================================
1638 //function : Convert
1640 //=======================================================================
1641 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1643 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1645 Standard_Integer aDxw, aDyw;
1646 MyWindow->Size (aDxw, aDyw);
1648 gp_Pnt aViewDims = Camera()->ViewDimensions();
1649 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1654 //=======================================================================
1655 //function : Convert
1657 //=======================================================================
1658 void V3d_View::Convert(const Standard_Real Xv,
1659 const Standard_Real Yv,
1660 Standard_Integer& Xp,
1661 Standard_Integer& Yp) const
1663 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1665 Standard_Integer aDxw, aDyw;
1666 MyWindow->Size (aDxw, aDyw);
1668 gp_Pnt aPoint (Xv, Yv, 0.0);
1669 aPoint = Camera()->ConvertView2Proj (aPoint);
1670 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1672 Xp = RealToInt (aPoint.X());
1673 Yp = RealToInt (aPoint.Y());
1676 //=======================================================================
1677 //function : Convert
1679 //=======================================================================
1680 void V3d_View::Convert(const Standard_Integer Xp,
1681 const Standard_Integer Yp,
1684 Standard_Real& Z) const
1686 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1687 Standard_Integer aHeight, aWidth;
1688 MyWindow->Size (aWidth, aHeight);
1690 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1691 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1692 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1694 gp_Pnt aResult = Camera()->UnProject (gp_Pnt (anX, anY, aZ));
1701 //=======================================================================
1702 //function : ConvertWithProj
1704 //=======================================================================
1705 void V3d_View::ConvertWithProj(const Standard_Integer theXp,
1706 const Standard_Integer theYp,
1707 Standard_Real& theX,
1708 Standard_Real& theY,
1709 Standard_Real& theZ,
1710 Standard_Real& theDx,
1711 Standard_Real& theDy,
1712 Standard_Real& theDz) const
1714 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1715 Standard_Integer aHeight = 0, aWidth = 0;
1716 MyWindow->Size (aWidth, aHeight);
1718 const Standard_Real anX = 2.0 * theXp / aWidth - 1.0;
1719 const Standard_Real anY = 2.0 * (aHeight - 1 - theYp) / aHeight - 1.0;
1720 const Standard_Real aZ = 2.0 * 0.0 - 1.0;
1722 const Handle(Graphic3d_Camera)& aCamera = Camera();
1723 const gp_Pnt aResult1 = aCamera->UnProject (gp_Pnt (anX, anY, aZ));
1724 const gp_Pnt aResult2 = aCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1726 theX = aResult1.X();
1727 theY = aResult1.Y();
1728 theZ = aResult1.Z();
1729 Graphic3d_Vec3d aNormDir (theX - aResult2.X(),
1730 theY - aResult2.Y(),
1731 theZ - aResult2.Z());
1732 aNormDir.Normalize();
1734 theDx = aNormDir.x();
1735 theDy = aNormDir.y();
1736 theDz = aNormDir.z();
1739 //=======================================================================
1740 //function : Convert
1742 //=======================================================================
1743 void V3d_View::Convert(const Standard_Real X,
1744 const Standard_Real Y,
1745 const Standard_Real Z,
1746 Standard_Integer& Xp,
1747 Standard_Integer& Yp) const
1749 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1750 Standard_Integer aHeight, aWidth;
1751 MyWindow->Size (aWidth, aHeight);
1753 gp_Pnt aPoint = Camera()->Project (gp_Pnt (X, Y, Z));
1755 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1756 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1759 //=======================================================================
1760 //function : Project
1762 //=======================================================================
1763 void V3d_View::Project (const Standard_Real theX,
1764 const Standard_Real theY,
1765 const Standard_Real theZ,
1766 Standard_Real& theXp,
1767 Standard_Real& theYp) const
1770 Project (theX, theY, theZ, theXp, theYp, aZp);
1773 //=======================================================================
1774 //function : Project
1776 //=======================================================================
1777 void V3d_View::Project (const Standard_Real theX,
1778 const Standard_Real theY,
1779 const Standard_Real theZ,
1780 Standard_Real& theXp,
1781 Standard_Real& theYp,
1782 Standard_Real& theZp) const
1784 Handle(Graphic3d_Camera) aCamera = Camera();
1786 gp_XYZ aViewSpaceDimensions = aCamera->ViewDimensions();
1787 Standard_Real aXSize = aViewSpaceDimensions.X();
1788 Standard_Real aYSize = aViewSpaceDimensions.Y();
1789 Standard_Real aZSize = aViewSpaceDimensions.Z();
1791 gp_Pnt aPoint = aCamera->Project (gp_Pnt (theX, theY, theZ));
1793 // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
1794 theXp = aPoint.X() * aXSize * 0.5;
1795 theYp = aPoint.Y() * aYSize * 0.5;
1796 theZp = aPoint.Z() * aZSize * 0.5;
1799 //=======================================================================
1800 //function : BackgroundColor
1802 //=======================================================================
1803 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1806 Standard_Real& V3) const
1808 Quantity_Color C = BackgroundColor() ;
1809 C.Values(V1,V2,V3,Type) ;
1812 //=======================================================================
1813 //function : BackgroundColor
1815 //=======================================================================
1816 Quantity_Color V3d_View::BackgroundColor() const
1818 return myView->Background().Color() ;
1821 //=======================================================================
1822 //function : GradientBackgroundColors
1824 //=======================================================================
1825 void V3d_View::GradientBackgroundColors (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1827 myView->GradientBackground().Colors (theColor1, theColor2);
1830 //=======================================================================
1831 //function : GradientBackground
1833 //=======================================================================
1834 Aspect_GradientBackground V3d_View::GradientBackground() const
1836 return myView->GradientBackground();
1839 //=======================================================================
1842 //=======================================================================
1843 Standard_Real V3d_View::Scale() const
1845 return myDefaultCamera->Scale() / Camera()->Scale();
1848 //=======================================================================
1849 //function : AxialScale
1851 //=======================================================================
1852 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1854 gp_Pnt anAxialScale = Camera()->AxialScale();
1855 Sx = anAxialScale.X();
1856 Sy = anAxialScale.Y();
1857 Sz = anAxialScale.Z();
1860 //=======================================================================
1863 //=======================================================================
1864 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1866 gp_Pnt aViewDims = Camera()->ViewDimensions();
1868 Width = aViewDims.X();
1869 Height = aViewDims.Y();
1872 //=======================================================================
1875 //=======================================================================
1876 Standard_Real V3d_View::ZSize() const
1878 gp_Pnt aViewDims = Camera()->ViewDimensions();
1880 return aViewDims.Z();
1883 //=======================================================================
1886 //=======================================================================
1887 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
1888 Standard_Real& Vmin,
1889 Standard_Real& Umax,
1890 Standard_Real& Vmax) const
1892 Standard_Real Wmin,Wmax,U,V,W ;
1893 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
1895 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1898 Bnd_Box aBox = myView->MinMaxValues();
1899 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1900 Project (Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
1901 Project (Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
1902 Project (Xmin,Ymin,Zmax,U,V,W) ;
1903 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1904 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1905 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1906 Project (Xmax,Ymin,Zmax,U,V,W) ;
1907 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1908 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1909 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1910 Project (Xmax,Ymin,Zmin,U,V,W) ;
1911 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1912 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1913 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1914 Project (Xmax,Ymax,Zmin,U,V,W) ;
1915 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1916 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1917 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1918 Project (Xmin,Ymax,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 (Xmin,Ymax,Zmin,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) ;
1930 //=======================================================================
1933 //=======================================================================
1934 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
1935 Standard_Real& Ymin,
1936 Standard_Real& Zmin,
1937 Standard_Real& Xmax,
1938 Standard_Real& Ymax,
1939 Standard_Real& Zmax) const
1942 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
1943 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1946 Bnd_Box aBox = myView->MinMaxValues();
1947 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1952 //=======================================================================
1953 //function : Gravity
1955 //=======================================================================
1956 void V3d_View::Gravity (Standard_Real& theX,
1957 Standard_Real& theY,
1958 Standard_Real& theZ) const
1960 Graphic3d_MapOfStructure aSetOfStructures;
1961 myView->DisplayedStructures (aSetOfStructures);
1963 Standard_Boolean hasSelection = Standard_False;
1964 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
1965 aStructIter.More(); aStructIter.Next())
1967 if (aStructIter.Key()->IsHighlighted()
1968 && aStructIter.Key()->IsVisible())
1970 hasSelection = Standard_True;
1975 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
1976 Standard_Integer aNbPoints = 0;
1977 gp_XYZ aResult (0.0, 0.0, 0.0);
1978 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
1979 aStructIter.More(); aStructIter.Next())
1981 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
1982 if (!aStruct->IsVisible()
1983 || aStruct->IsInfinite()
1984 || (hasSelection && !aStruct->IsHighlighted()))
1989 const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox();
1990 if (!aBox.IsValid())
1995 // skip transformation-persistent objects
1996 if (!aStruct->TransformPersistence().IsNull())
2001 // use camera projection to find gravity point
2002 Xmin = aBox.CornerMin().x();
2003 Ymin = aBox.CornerMin().y();
2004 Zmin = aBox.CornerMin().z();
2005 Xmax = aBox.CornerMax().x();
2006 Ymax = aBox.CornerMax().y();
2007 Zmax = aBox.CornerMax().z();
2008 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2010 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2011 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2012 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2013 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2016 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2018 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2019 const gp_Pnt aProjected = Camera()->Project (aBndPnt);
2020 if (Abs (aProjected.X()) <= 1.0
2021 && Abs (aProjected.Y()) <= 1.0)
2023 aResult += aBndPnt.XYZ();
2031 // fallback - just use bounding box of entire scene
2032 Bnd_Box aBox = myView->MinMaxValues();
2035 aBox.Get (Xmin, Ymin, Zmin,
2037 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2039 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2040 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2041 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2042 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2045 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2047 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2048 aResult += aBndPnt.XYZ();
2056 aResult /= aNbPoints;
2063 //=======================================================================
2066 //=======================================================================
2067 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2069 gp_Pnt aCameraEye = Camera()->Eye();
2075 //=============================================================================
2076 //function : ProjReferenceAxe
2078 //=============================================================================
2079 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2080 const Standard_Integer Ypix,
2086 Standard_Real& VZ) const
2088 Standard_Real Xo,Yo,Zo;
2090 Convert (Xpix, Ypix, XP, YP, ZP);
2091 if ( Type() == V3d_PERSPECTIVE )
2093 FocalReferencePoint (Xo,Yo,Zo);
2104 //=============================================================================
2107 //=============================================================================
2108 Standard_Real V3d_View::Depth() const
2110 return Camera()->Distance();
2113 //=============================================================================
2116 //=============================================================================
2117 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2119 gp_Dir aCameraDir = Camera()->Direction().Reversed();
2120 Dx = aCameraDir.X();
2121 Dy = aCameraDir.Y();
2122 Dz = aCameraDir.Z();
2125 //=============================================================================
2128 //=============================================================================
2129 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2131 gp_Pnt aCameraCenter = Camera()->Center();
2132 X = aCameraCenter.X();
2133 Y = aCameraCenter.Y();
2134 Z = aCameraCenter.Z();
2137 //=============================================================================
2140 //=============================================================================
2141 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2143 gp_Dir aCameraUp = Camera()->Up();
2149 //=============================================================================
2152 //=============================================================================
2153 Standard_Real V3d_View::Twist() const
2155 gp_Vec Xaxis, Yaxis, Zaxis;
2156 const gp_Dir aReferencePlane (Camera()->Direction().Reversed());
2157 if (!screenAxis (aReferencePlane, gp::DZ(), Xaxis, Yaxis, Zaxis)
2158 && !screenAxis (aReferencePlane, gp::DY(), Xaxis, Yaxis, Zaxis)
2159 && !screenAxis (aReferencePlane, gp::DX(), Xaxis, Yaxis, Zaxis))
2164 // Compute Cross Vector From Up & Origin
2165 const gp_Dir aCameraUp = Camera()->Up();
2166 const gp_XYZ aP = Yaxis.XYZ().Crossed (aCameraUp.XYZ());
2169 Standard_Real anAngle = ASin (Max (Min (aP.Modulus(), 1.0), -1.0));
2170 if (Yaxis.Dot (aCameraUp.XYZ()) < 0.0)
2172 anAngle = M_PI - anAngle;
2177 const gp_Dir aProjDir = Camera()->Direction().Reversed();
2178 if (aP.Dot (aProjDir.XYZ()) < 0.0)
2180 anAngle = DEUXPI - anAngle;
2186 //=============================================================================
2187 //function : ShadingModel
2189 //=============================================================================
2190 Graphic3d_TypeOfShadingModel V3d_View::ShadingModel() const
2192 return myView->ShadingModel();
2195 //=============================================================================
2196 //function : TextureEnv
2198 //=============================================================================
2199 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2201 return myView->TextureEnv();
2204 //=============================================================================
2205 //function : Visualization
2207 //=============================================================================
2208 V3d_TypeOfVisualization V3d_View::Visualization() const
2210 return static_cast<V3d_TypeOfVisualization> (myView->VisualizationType());
2213 //=============================================================================
2214 //function : IfWindow
2216 //=============================================================================
2217 Standard_Boolean V3d_View::IfWindow() const
2219 return myView->IsDefined();
2222 //=============================================================================
2225 //=============================================================================
2226 V3d_TypeOfView V3d_View::Type() const
2228 return Camera()->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2231 //=============================================================================
2232 //function : SetFocale
2234 //=============================================================================
2235 void V3d_View::SetFocale( const Standard_Real focale )
2237 Handle(Graphic3d_Camera) aCamera = Camera();
2239 if (aCamera->IsOrthographic())
2244 Standard_Real aFOVyRad = ATan (focale / (aCamera->Distance() * 2.0));
2246 aCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2251 //=============================================================================
2254 //=============================================================================
2255 Standard_Real V3d_View::Focale() const
2257 Handle(Graphic3d_Camera) aCamera = Camera();
2259 if (aCamera->IsOrthographic())
2264 return aCamera->Distance() * 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
2267 //=============================================================================
2268 //function : screenAxis
2270 //=============================================================================
2271 Standard_Boolean V3d_View::screenAxis (const gp_Dir& theVpn, const gp_Dir& theVup,
2272 gp_Vec& theXaxe, gp_Vec& theYaxe, gp_Vec& theZaxe)
2274 theXaxe = theVup.XYZ().Crossed (theVpn.XYZ());
2275 if (theXaxe.Magnitude() <= gp::Resolution())
2277 return Standard_False;
2279 theXaxe.Normalize();
2281 theYaxe = theVpn.XYZ().Crossed (theXaxe.XYZ());
2282 if (theYaxe.Magnitude() <= gp::Resolution())
2284 return Standard_False;
2286 theYaxe.Normalize();
2288 theZaxe = theVpn.XYZ();
2289 theZaxe.Normalize();
2290 return Standard_True;
2293 //=============================================================================
2294 //function : TrsPoint
2296 //=============================================================================
2297 gp_XYZ V3d_View::TrsPoint (const Graphic3d_Vertex& thePnt, const TColStd_Array2OfReal& theMat)
2300 const Standard_Integer lr = theMat.LowerRow();
2301 const Standard_Integer ur = theMat.UpperRow();
2302 const Standard_Integer lc = theMat.LowerCol();
2303 const Standard_Integer uc = theMat.UpperCol();
2304 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4))
2306 return gp_XYZ (thePnt.X(), thePnt.Y(), thePnt.Z());
2309 Standard_Real X, Y, Z;
2310 thePnt.Coord (X,Y,Z);
2311 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);
2312 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);
2313 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);
2314 return gp_XYZ (XX, YY, ZZ);
2317 //=======================================================================
2320 //=======================================================================
2321 void V3d_View::Pan (const Standard_Integer theDXp,
2322 const Standard_Integer theDYp,
2323 const Standard_Real theZoomFactor,
2324 const Standard_Boolean theToStart)
2326 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2329 //=======================================================================
2330 //function : Panning
2332 //=======================================================================
2333 void V3d_View::Panning (const Standard_Real theDXv,
2334 const Standard_Real theDYv,
2335 const Standard_Real theZoomFactor,
2336 const Standard_Boolean theToStart)
2338 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2340 Handle(Graphic3d_Camera) aCamera = Camera();
2344 myCamStartOpEye = aCamera->Eye();
2345 myCamStartOpCenter = aCamera->Center();
2348 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2350 gp_Pnt aViewDims = aCamera->ViewDimensions();
2352 aCamera->SetEye (myCamStartOpEye);
2353 aCamera->SetCenter (myCamStartOpCenter);
2354 Translate (aCamera, -theDXv, -theDYv);
2355 Scale (aCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2357 SetImmediateUpdate (wasUpdateEnabled);
2362 //=======================================================================
2365 //=======================================================================
2366 void V3d_View::Zoom (const Standard_Integer theXp1,
2367 const Standard_Integer theYp1,
2368 const Standard_Integer theXp2,
2369 const Standard_Integer theYp2)
2371 Standard_Integer aDx = theXp2 - theXp1;
2372 Standard_Integer aDy = theYp2 - theYp1;
2373 if (aDx != 0 || aDy != 0)
2375 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2376 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2377 SetZoom (aCoeff, Standard_True);
2381 //=======================================================================
2382 //function : StartZoomAtPoint
2384 //=======================================================================
2385 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2386 const Standard_Integer theYp)
2388 MyZoomAtPointX = theXp;
2389 MyZoomAtPointY = theYp;
2392 //=======================================================================
2393 //function : ZoomAtPoint
2395 //=======================================================================
2396 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2397 const Standard_Integer theMouseStartY,
2398 const Standard_Integer theMouseEndX,
2399 const Standard_Integer theMouseEndY)
2401 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2404 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2405 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2406 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2408 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2410 Handle(Graphic3d_Camera) aCamera = Camera();
2412 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
2413 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
2415 // ensure that zoom will not be too small or too big.
2416 Standard_Real aCoef = aDZoom;
2417 if (aViewWidth < aCoef * Precision::Confusion())
2419 aCoef = aViewWidth / Precision::Confusion();
2421 else if (aViewWidth > aCoef * 1e12)
2423 aCoef = aViewWidth / 1e12;
2425 if (aViewHeight < aCoef * Precision::Confusion())
2427 aCoef = aViewHeight / Precision::Confusion();
2429 else if (aViewHeight > aCoef * 1e12)
2431 aCoef = aViewHeight / 1e12;
2434 Standard_Real aZoomAtPointXv = 0.0;
2435 Standard_Real aZoomAtPointYv = 0.0;
2436 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2438 Standard_Real aDxv = aZoomAtPointXv / aCoef;
2439 Standard_Real aDyv = aZoomAtPointYv / aCoef;
2441 aCamera->SetScale (aCamera->Scale() / aCoef);
2442 Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2446 SetImmediateUpdate (wasUpdateEnabled);
2451 //=============================================================================
2452 //function : AxialScale
2454 //=============================================================================
2455 void V3d_View::AxialScale (const Standard_Integer Dx,
2456 const Standard_Integer Dy,
2457 const V3d_TypeOfAxe Axis)
2459 if( Dx != 0. || Dy != 0. ) {
2460 Standard_Real Sx, Sy, Sz;
2461 AxialScale( Sx, Sy, Sz );
2462 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2463 dscale = (Dx > 0) ? dscale : 1./dscale;
2464 if( Axis == V3d_X ) Sx = dscale;
2465 if( Axis == V3d_Y ) Sy = dscale;
2466 if( Axis == V3d_Z ) Sz = dscale;
2467 SetAxialScale( Sx, Sy, Sz );
2471 //=============================================================================
2474 //=============================================================================
2475 void V3d_View::FitAll(const Standard_Real theXmin,
2476 const Standard_Real theYmin,
2477 const Standard_Real theXmax,
2478 const Standard_Real theYmax)
2480 Handle(Graphic3d_Camera) aCamera = Camera();
2481 Standard_Real anAspect = aCamera->Aspect();
2483 Standard_Real aFitSizeU = Abs (theXmax - theXmin);
2484 Standard_Real aFitSizeV = Abs (theYmax - theYmin);
2485 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2486 if (aFitAspect >= anAspect)
2488 aFitSizeV = aFitSizeU / anAspect;
2492 aFitSizeU = aFitSizeV * anAspect;
2495 Translate (aCamera, (theXmin + theXmax) * 0.5, (theYmin + theYmax) * 0.5);
2496 Scale (aCamera, aFitSizeU, aFitSizeV);
2503 //=============================================================================
2504 //function : StartRotation
2506 //=============================================================================
2507 void V3d_View::StartRotation(const Standard_Integer X,
2508 const Standard_Integer Y,
2509 const Standard_Real zRotationThreshold)
2514 rx = Standard_Real(Convert(x));
2515 ry = Standard_Real(Convert(y));
2517 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2518 myZRotation = Standard_False;
2519 if( zRotationThreshold > 0. ) {
2520 Standard_Real dx = Abs(sx - rx/2.);
2521 Standard_Real dy = Abs(sy - ry/2.);
2522 // if( dx > rx/3. || dy > ry/3. ) myZRotation = Standard_True;
2523 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2524 if( dx > dd || dy > dd ) myZRotation = Standard_True;
2529 //=============================================================================
2530 //function : Rotation
2532 //=============================================================================
2533 void V3d_View::Rotation(const Standard_Integer X,
2534 const Standard_Integer Y)
2536 if( rx == 0. || ry == 0. ) {
2540 Standard_Real dx=0.,dy=0.,dz=0.;
2542 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2543 atan2(sx-rx/2.,ry/2.-sy);
2545 dx = (Standard_Real(X) - sx) * M_PI / rx;
2546 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2549 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2552 //=============================================================================
2553 //function : SetComputedMode
2555 //=============================================================================
2556 void V3d_View::SetComputedMode (const Standard_Boolean theMode)
2562 myView->SetComputedMode (Standard_True);
2567 myView->SetComputedMode (Standard_False);
2571 //=============================================================================
2572 //function : ComputedMode
2574 //=============================================================================
2575 Standard_Boolean V3d_View::ComputedMode() const
2577 return myView->ComputedMode();
2580 //=============================================================================
2581 //function : SetBackFacingModel
2583 //=============================================================================
2584 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel theModel)
2586 myView->SetBackfacingModel (static_cast<Graphic3d_TypeOfBackfacingModel> (theModel));
2590 //=============================================================================
2591 //function : BackFacingModel
2593 //=============================================================================
2594 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2596 return static_cast<V3d_TypeOfBackfacingModel> (myView->BackfacingModel());
2599 //=============================================================================
2602 //=============================================================================
2603 void V3d_View::Init()
2605 myComputedMode = MyViewer->ComputedMode();
2606 if (!myComputedMode || !MyViewer->DefaultComputedMode())
2608 SetComputedMode (Standard_False);
2612 //=============================================================================
2615 //=============================================================================
2616 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2617 const Graphic3d_BufferType& theBufferType)
2619 Standard_Integer aWinWidth, aWinHeight;
2620 MyWindow->Size (aWinWidth, aWinHeight);
2621 Image_AlienPixMap anImage;
2623 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2626 //=============================================================================
2627 //function : ToPixMap
2629 //=============================================================================
2630 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
2631 const V3d_ImageDumpOptions& theParams)
2633 Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
2634 if (aTargetSize.x() != 0
2635 && aTargetSize.y() != 0)
2637 // allocate image buffer for dumping
2638 if (theImage.IsEmpty()
2639 || theImage.SizeX() != Standard_Size(aTargetSize.x())
2640 || theImage.SizeY() != Standard_Size(aTargetSize.y()))
2642 Image_Format aFormat = Image_Format_UNKNOWN;
2643 switch (theParams.BufferType)
2645 case Graphic3d_BT_RGB: aFormat = Image_Format_RGB; break;
2646 case Graphic3d_BT_RGBA: aFormat = Image_Format_RGBA; break;
2647 case Graphic3d_BT_Depth: aFormat = Image_Format_GrayF; break;
2648 case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF; break;
2651 if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
2653 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y()
2654 + " for view dump", Message_Fail);
2655 return Standard_False;
2659 if (theImage.IsEmpty())
2661 Message::DefaultMessenger()->Send (TCollection_AsciiString ("V3d_View::ToPixMap() has been called without image dimensions"), Message_Fail);
2662 return Standard_False;
2664 aTargetSize.x() = (Standard_Integer )theImage.SizeX();
2665 aTargetSize.y() = (Standard_Integer )theImage.SizeY();
2667 Handle(Standard_Transient) aFBOPtr;
2668 Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
2669 Graphic3d_Vec2i aFBOVPSize = aTargetSize;
2671 bool isTiling = false;
2672 if (theParams.TileSize > 0)
2674 if (aFBOVPSize.x() > theParams.TileSize
2675 || aFBOVPSize.y() > theParams.TileSize)
2677 aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
2678 aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
2683 Graphic3d_Vec2i aPrevFBOVPSize;
2684 if (!aPrevFBOPtr.IsNull())
2686 Graphic3d_Vec2i aPrevFBOSizeMax;
2687 myView->FBOGetDimensions (aPrevFBOPtr,
2688 aPrevFBOVPSize.x(), aPrevFBOVPSize.y(),
2689 aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
2690 if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
2691 && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
2693 aFBOPtr = aPrevFBOPtr;
2697 if (aFBOPtr.IsNull())
2699 Standard_Integer aMaxTexSizeX = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeX);
2700 Standard_Integer aMaxTexSizeY = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeY);
2701 if (theParams.TileSize > aMaxTexSizeX
2702 || theParams.TileSize > aMaxTexSizeY)
2704 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
2705 + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")", Message_Fail);
2706 return Standard_False;
2709 if (aFBOVPSize.x() > aMaxTexSizeX
2710 || aFBOVPSize.y() > aMaxTexSizeY)
2712 if (MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_IsWorkaroundFBO))
2714 Message::DefaultMessenger ()->Send (TCollection_AsciiString ("Warning, workaround for Intel driver problem with empty FBO for images with big width is applyed."), Message_Warning);
2716 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Info, tiling image dump is used, image size (")
2717 + aFBOVPSize.x() + "x" + aFBOVPSize.y() + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")", Message_Info);
2718 aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSizeX);
2719 aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSizeY);
2723 // Try to create hardware accelerated buffer
2724 aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
2726 myView->SetFBO (aFBOPtr);
2728 if (aFBOPtr.IsNull())
2730 // try to use on-screen buffer
2731 Graphic3d_Vec2i aWinSize;
2732 MyWindow->Size (aWinSize.x(), aWinSize.y());
2733 if (aFBOVPSize.x() != aWinSize.x()
2734 || aFBOVPSize.y() != aWinSize.y())
2738 aFBOVPSize = aWinSize;
2740 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning, on screen buffer is used for image dump - content might be invalid"), Message_Warning);
2743 // backup camera parameters
2744 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2745 Handle(Graphic3d_Camera) aCamera = Camera();
2746 aStoreMapping->Copy (aCamera);
2747 if (aCamera->IsStereo())
2749 switch (theParams.StereoOptions)
2753 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2756 case V3d_SDO_LEFT_EYE:
2758 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2761 case V3d_SDO_RIGHT_EYE:
2763 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2766 case V3d_SDO_BLENDED:
2768 break; // dump as is
2772 if (theParams.ToAdjustAspect)
2774 aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
2778 // render immediate structures into back buffer rather than front
2779 const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
2781 Standard_Boolean isSuccess = Standard_True;
2784 if (!aFBOPtr.IsNull())
2786 myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
2789 isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
2793 Image_PixMap aTilePixMap;
2794 aTilePixMap.SetTopDown (theImage.IsTopDown());
2796 Graphic3d_Vec2i anOffset (0, 0);
2797 for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
2800 for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
2802 Graphic3d_CameraTile aTileUncropped;
2803 aTileUncropped.Offset = anOffset;
2804 aTileUncropped.TotalSize = aTargetSize;
2805 aTileUncropped.TileSize = aFBOVPSize;
2806 const Graphic3d_CameraTile aTile = aTileUncropped.Cropped();
2807 if (aTile.TileSize.x() < 1
2808 || aTile.TileSize.y() < 1)
2813 const Standard_Integer aLeft = aTile.Offset.x();
2814 Standard_Integer aBottom = aTile.Offset.y();
2815 if (theImage.IsTopDown())
2817 const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
2818 aBottom = aTargetSize.y() - aTop;
2820 aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
2821 + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
2822 aTile.TileSize.x(), aTile.TileSize.y(),
2823 theImage.SizeRowBytes());
2825 if (!aFBOPtr.IsNull())
2827 aCamera->SetTile (aTile);
2828 myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
2832 // no API to resize viewport of on-screen buffer - render uncropped
2833 aCamera->SetTile (aTileUncropped);
2836 isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
2850 myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
2851 aCamera->Copy (aStoreMapping);
2852 if (aFBOPtr != aPrevFBOPtr)
2854 myView->FBORelease (aFBOPtr);
2856 else if (!aPrevFBOPtr.IsNull())
2858 myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
2860 myView->SetFBO (aPrevFBOPtr);
2864 //=============================================================================
2865 //function : ImmediateUpdate
2867 //=============================================================================
2868 void V3d_View::ImmediateUpdate() const
2870 if (myImmediateUpdate)
2876 //=============================================================================
2877 //function : SetImmediateUpdate
2879 //=============================================================================
2880 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2882 Standard_Boolean aPreviousMode = myImmediateUpdate;
2883 myImmediateUpdate = theImmediateUpdate;
2884 return aPreviousMode;
2887 // =======================================================================
2888 // function : SetCamera
2890 // =======================================================================
2891 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2893 myView->SetCamera (theCamera);
2898 // =======================================================================
2899 // function : GetCamera
2901 // =======================================================================
2902 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
2904 return myView->Camera();
2907 // =======================================================================
2908 // function : FitMinMax
2909 // purpose : Internal
2910 // =======================================================================
2911 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
2912 const Bnd_Box& theBox,
2913 const Standard_Real theMargin,
2914 const Standard_Real theResolution,
2915 const Standard_Boolean theToEnlargeIfLine) const
2917 // Check bounding box for validness
2918 if (theBox.IsVoid())
2920 return Standard_False; // bounding box is out of bounds...
2923 // Apply "axial scaling" to the bounding points.
2924 // It is not the best approach to make this scaling as a part of fit all operation,
2925 // but the axial scale is integrated into camera orientation matrix and the other
2926 // option is to perform frustum plane adjustment algorithm in view camera space,
2927 // which will lead to a number of additional world-view space conversions and
2928 // loosing precision as well.
2929 gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (theCamera->AxialScale());
2930 gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (theCamera->AxialScale());
2932 if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
2934 return Standard_False; // nothing to fit all
2937 // Prepare camera frustum planes.
2938 NCollection_Array1<gp_Pln> aFrustumPlane (1, 6);
2939 theCamera->Frustum (aFrustumPlane.ChangeValue (1),
2940 aFrustumPlane.ChangeValue (2),
2941 aFrustumPlane.ChangeValue (3),
2942 aFrustumPlane.ChangeValue (4),
2943 aFrustumPlane.ChangeValue (5),
2944 aFrustumPlane.ChangeValue (6));
2946 // Prepare camera up, side, direction vectors.
2947 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
2948 gp_Dir aCamDir = theCamera->Direction();
2949 gp_Dir aCamSide = aCamDir ^ aCamUp;
2951 // Prepare scene bounding box parameters.
2952 gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
2954 NCollection_Array1<gp_Pnt> aBndCorner (1, 8);
2955 aBndCorner.ChangeValue (1) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
2956 aBndCorner.ChangeValue (2) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
2957 aBndCorner.ChangeValue (3) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
2958 aBndCorner.ChangeValue (4) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
2959 aBndCorner.ChangeValue (5) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
2960 aBndCorner.ChangeValue (6) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
2961 aBndCorner.ChangeValue (7) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
2962 aBndCorner.ChangeValue (8) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
2964 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
2965 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
2966 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
2967 // set up perspective-correct camera projection matching the bounding box.
2968 // These steps support non-asymmetric transformations of view-projection space provided by camera.
2969 // The zooming can be done by calculating view plane size matching the bounding box at center of
2970 // the bounding box. The only limitation here is that the scale of camera should define size of
2971 // its view plane passing through the camera center, and the center of camera should be on the
2972 // same line with the center of bounding box.
2974 // The following method is applied:
2975 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
2976 // 2) Determine new location of frustum planes, "matching" the bounding box.
2977 // 3) Determine new camera projection vector using the normalized asymmetry.
2978 // 4) Determine new zooming in view space.
2980 // 1. Determine normalized projection asymmetry (if any).
2981 Standard_Real anAssymX = Tan (( aCamSide).Angle (aFrustumPlane (1).Axis().Direction()))
2982 - Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction()));
2983 Standard_Real anAssymY = Tan (( aCamUp) .Angle (aFrustumPlane (3).Axis().Direction()))
2984 - Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction()));
2986 // 2. Determine how far should be the frustum planes placed from center
2987 // of bounding box, in order to match the bounding box closely.
2988 NCollection_Array1<Standard_Real> aFitDistance (1, 6);
2989 aFitDistance.ChangeValue (1) = 0.0;
2990 aFitDistance.ChangeValue (2) = 0.0;
2991 aFitDistance.ChangeValue (3) = 0.0;
2992 aFitDistance.ChangeValue (4) = 0.0;
2993 aFitDistance.ChangeValue (5) = 0.0;
2994 aFitDistance.ChangeValue (6) = 0.0;
2996 for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
2998 // Measure distances from center of bounding box to its corners towards the frustum plane.
2999 const gp_Dir& aPlaneN = aFrustumPlane.ChangeValue (anI).Axis().Direction();
3001 Standard_Real& aFitDist = aFitDistance.ChangeValue (anI);
3003 for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
3005 aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner (aJ)).Dot (aPlaneN));
3008 // The center of camera is placed on the same line with center of bounding box.
3009 // The view plane section crosses the bounding box at its center.
3010 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3011 // into view section size between the point and the frustum plane.
3013 // /|\ right half of frame //
3015 // point o<-- distance * coeff -->//---- (view plane section)
3024 aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan ( aCamSide .Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
3025 aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
3026 aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan ( aCamUp .Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
3027 aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
3028 aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan ( aCamDir .Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
3029 aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan ((-aCamDir) .Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
3031 Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
3032 Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
3033 Standard_Real aViewSizeZv = aFitDistance (5) + aFitDistance (6);
3035 // 3. Place center of camera on the same line with center of bounding
3036 // box applying corresponding projection asymmetry (if any).
3037 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3038 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3039 Standard_Real anOffsetXv = (aFitDistance (2) - aFitDistance (1)) * 0.5 + anAssymXv;
3040 Standard_Real anOffsetYv = (aFitDistance (4) - aFitDistance (3)) * 0.5 + anAssymYv;
3041 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3042 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3043 gp_Pnt aCamNewCenter = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3045 gp_Trsf aCenterTrsf;
3046 aCenterTrsf.SetTranslation (theCamera->Center(), aCamNewCenter);
3047 theCamera->Transform (aCenterTrsf);
3048 theCamera->SetDistance (aFitDistance (6) + aFitDistance (5));
3050 // Bounding box collapses to a point or thin line going in depth of the screen
3051 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3053 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3055 return Standard_True; // This is just one point or line and zooming has no effect.
3058 // Looking along line and "theToEnlargeIfLine" is requested.
3059 // Fit view to see whole scene on rotation.
3060 aViewSizeXv = aViewSizeZv;
3061 aViewSizeYv = aViewSizeZv;
3064 Scale (theCamera, aViewSizeXv, aViewSizeYv);
3066 const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
3068 Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
3070 return Standard_True;
3073 // =======================================================================
3075 // purpose : Internal
3076 // =======================================================================
3077 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3078 const Standard_Real theSizeXv,
3079 const Standard_Real theSizeYv) const
3081 Standard_Real anAspect = theCamera->Aspect();
3084 theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
3088 theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
3092 // =======================================================================
3093 // function : Translate
3094 // purpose : Internal
3095 // =======================================================================
3096 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3097 const Standard_Real theDXv,
3098 const Standard_Real theDYv) const
3100 const gp_Pnt& aCenter = theCamera->Center();
3101 const gp_Dir& aDir = theCamera->Direction();
3102 const gp_Dir& anUp = theCamera->Up();
3103 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3105 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3106 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3107 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3109 aPanTrsf.SetTranslation (aCameraPan);
3111 theCamera->Transform (aPanTrsf);
3114 // =======================================================================
3115 // function : DiagnosticInformation
3117 // =======================================================================
3118 void V3d_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
3119 Graphic3d_DiagnosticInfo theFlags) const
3121 myView->DiagnosticInformation (theDict, theFlags);
3124 //=======================================================================
3125 //function : StatisticInformation
3127 //=======================================================================
3128 void V3d_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
3130 myView->StatisticInformation (theDict);
3133 // =======================================================================
3134 // function : StatisticInformation
3136 // =======================================================================
3137 TCollection_AsciiString V3d_View::StatisticInformation() const
3139 return myView->StatisticInformation();
3142 //=============================================================================
3143 //function : RenderingParams
3145 //=============================================================================
3146 const Graphic3d_RenderingParams& V3d_View::RenderingParams() const
3148 return myView->RenderingParams();
3151 //=============================================================================
3152 //function : ChangeRenderingParams
3154 //=============================================================================
3155 Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams()
3157 return myView->ChangeRenderingParams();