1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <V3d_View.hxx>
16 #include <Aspect_GradientBackground.hxx>
17 #include <Aspect_Grid.hxx>
18 #include <Aspect_Window.hxx>
19 #include <Bnd_Box.hxx>
23 #include <Graphic3d_AspectMarker3d.hxx>
24 #include <Graphic3d_GraphicDriver.hxx>
25 #include <Graphic3d_Group.hxx>
26 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
27 #include <Graphic3d_MapOfStructure.hxx>
28 #include <Graphic3d_Structure.hxx>
29 #include <Graphic3d_TextureEnv.hxx>
30 #include <Image_AlienPixMap.hxx>
31 #include <Message.hxx>
32 #include <Message_Messenger.hxx>
33 #include <NCollection_Array1.hxx>
34 #include <Precision.hxx>
35 #include <Quantity_Color.hxx>
36 #include <Standard_Assert.hxx>
37 #include <Standard_DivideByZero.hxx>
38 #include <Standard_ErrorHandler.hxx>
39 #include <Standard_MultiplyDefined.hxx>
40 #include <Standard_ShortReal.hxx>
41 #include <Standard_Type.hxx>
42 #include <Standard_TypeMismatch.hxx>
43 #include <TColgp_Array1OfPnt.hxx>
44 #include <TColStd_Array2OfReal.hxx>
45 #include <TColStd_HSequenceOfInteger.hxx>
47 #include <V3d_BadValue.hxx>
48 #include <V3d_Light.hxx>
49 #include <V3d_StereoDumpOptions.hxx>
50 #include <V3d_UnMapped.hxx>
51 #include <V3d_Viewer.hxx>
53 IMPLEMENT_STANDARD_RTTIEXT(V3d_View,Standard_Transient)
55 #define DEUXPI (2. * M_PI)
59 static const Standard_Integer THE_NB_BOUND_POINTS = 8;
62 //=============================================================================
63 //function : Constructor
65 //=============================================================================
66 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType)
67 : myIsInvalidatedImmediate (Standard_True),
68 MyViewer (theViewer.operator->()),
69 SwitchSetFront (Standard_False),
70 myZRotation (Standard_False),
71 myTrihedron (new V3d_Trihedron()),
74 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
76 myView->SetBackground (theViewer->GetBackgroundColor());
77 myView->SetGradientBackground (theViewer->GetGradientBackground());
79 ChangeRenderingParams() = theViewer->DefaultRenderingParams();
82 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
83 aCamera->SetFOVy (45.0);
84 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
85 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
86 aCamera->SetProjectionType ((theType == V3d_ORTHOGRAPHIC)
87 ? Graphic3d_Camera::Projection_Orthographic
88 : Graphic3d_Camera::Projection_Perspective);
90 myDefaultCamera = new Graphic3d_Camera();
92 myImmediateUpdate = Standard_False;
93 SetAutoZFitMode (Standard_True, 1.0);
94 SetBackFacingModel (V3d_TOBM_AUTOMATIC);
96 SetAxis (0.,0.,0.,1.,1.,1.);
97 SetVisualization (theViewer->DefaultVisualization());
98 SetShadingModel (theViewer->DefaultShadingModel());
101 SetProj (theViewer->DefaultViewProj());
102 SetSize (theViewer->DefaultViewSize());
103 Standard_Real zsize = theViewer->DefaultViewSize();
105 SetDepth (theViewer->DefaultViewSize() / 2.0);
106 SetViewMappingDefault();
107 SetViewOrientationDefault();
108 theViewer->AddView (this);
110 myImmediateUpdate = Standard_True;
113 //=============================================================================
114 //function : Constructor
116 //=============================================================================
117 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
118 : myIsInvalidatedImmediate (Standard_True),
119 MyViewer (theViewer.operator->()),
120 SwitchSetFront(Standard_False),
121 myZRotation (Standard_False),
124 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
126 myView->CopySettings (theView->View());
127 myDefaultViewPoint = theView->myDefaultViewPoint;
128 myDefaultViewAxis = theView->myDefaultViewAxis;
130 myDefaultCamera = new Graphic3d_Camera (theView->DefaultCamera());
132 myImmediateUpdate = Standard_False;
133 SetAutoZFitMode (theView->AutoZFitMode(), theView->AutoZFitScaleFactor());
134 theViewer->AddView (this);
136 myImmediateUpdate = Standard_True;
139 //=============================================================================
140 //function : Destructor
142 //=============================================================================
143 V3d_View::~V3d_View()
145 if (!myView->IsRemoved())
151 //=============================================================================
152 //function : SetMagnify
154 //=============================================================================
155 void V3d_View::SetMagnify (const Handle(Aspect_Window)& theWindow,
156 const Handle(V3d_View)& thePreviousView,
157 const Standard_Integer theX1,
158 const Standard_Integer theY1,
159 const Standard_Integer theX2,
160 const Standard_Integer theY2)
162 if (!myView->IsRemoved() && !myView->IsDefined())
164 Standard_Real aU1, aV1, aU2, aV2;
165 thePreviousView->Convert (theX1, theY1, aU1, aV1);
166 thePreviousView->Convert (theX2, theY2, aU2, aV2);
167 myView->SetWindow (theWindow);
168 FitAll (aU1, aV1, aU2, aV2);
169 MyViewer->SetViewOn (this);
170 MyWindow = theWindow;
173 SetViewMappingDefault();
177 //=============================================================================
178 //function : SetWindow
180 //=============================================================================
181 void V3d_View::SetWindow (const Handle(Aspect_Window)& theWindow,
182 const Aspect_RenderingContext theContext)
184 if (myView->IsRemoved())
189 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
190 MyWindow = theWindow;
191 myView->SetWindow (theWindow, theContext);
192 MyViewer->SetViewOn (this);
194 if (myImmediateUpdate)
200 //=============================================================================
203 //=============================================================================
204 void V3d_View::Remove() const
206 if (!MyGrid.IsNull())
210 if (!myTrihedron.IsNull())
212 myTrihedron->Erase();
215 MyViewer->DelView (this);
217 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
221 //=============================================================================
224 //=============================================================================
225 void V3d_View::Update() const
227 if (!myView->IsDefined()
228 || !myView->IsActive())
233 myIsInvalidatedImmediate = Standard_False;
239 //=============================================================================
242 //=============================================================================
243 void V3d_View::Redraw() const
245 if (!myView->IsDefined()
246 || !myView->IsActive())
251 myIsInvalidatedImmediate = Standard_False;
252 Handle(Graphic3d_StructureManager) aStructureMgr = MyViewer->StructureManager();
253 for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
255 if (aStructureMgr->IsDeviceLost())
257 aStructureMgr->RecomputeStructures();
264 if (!aStructureMgr->IsDeviceLost())
271 //=============================================================================
272 //function : RedrawImmediate
274 //=============================================================================
275 void V3d_View::RedrawImmediate() const
277 if (!myView->IsDefined()
278 || !myView->IsActive())
283 myIsInvalidatedImmediate = Standard_False;
284 myView->RedrawImmediate();
287 //=============================================================================
288 //function : Invalidate
290 //=============================================================================
291 void V3d_View::Invalidate() const
293 if (!myView->IsDefined())
298 myView->Invalidate();
301 //=============================================================================
302 //function : IsInvalidated
304 //=============================================================================
305 Standard_Boolean V3d_View::IsInvalidated() const
307 return !myView->IsDefined()
308 || myView->IsInvalidated();
311 // ========================================================================
312 // function : SetAutoZFitMode
314 // ========================================================================
315 void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn,
316 const Standard_Real theScaleFactor)
318 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
319 myAutoZFitScaleFactor = theScaleFactor;
320 myAutoZFitIsOn = theIsOn;
323 //=============================================================================
324 //function : AutoZFit
326 //=============================================================================
327 void V3d_View::AutoZFit() const
334 ZFitAll (myAutoZFitScaleFactor);
337 //=============================================================================
340 //=============================================================================
341 void V3d_View::ZFitAll (const Standard_Real theScaleFactor) const
343 Bnd_Box aMinMaxBox = myView->MinMaxValues (Standard_False); // applicative min max boundaries
344 Bnd_Box aGraphicBox = myView->MinMaxValues (Standard_True); // real graphical boundaries (not accounting infinite flag).
346 myView->Camera()->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
349 //=============================================================================
352 //=============================================================================
353 Standard_Boolean V3d_View::IsEmpty() const
355 Standard_Boolean TheStatus = Standard_True ;
356 if( myView->IsDefined() ) {
357 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
358 if( Nstruct > 0 ) TheStatus = Standard_False ;
363 //=============================================================================
364 //function : UpdateLights
366 //=============================================================================
367 void V3d_View::UpdateLights() const
369 Handle(Graphic3d_LightSet) aLights = new Graphic3d_LightSet();
370 for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
372 aLights->Add (anActiveLightIter.Value());
374 myView->SetLights (aLights);
377 //=============================================================================
378 //function : DoMapping
380 //=============================================================================
381 void V3d_View::DoMapping()
383 if (!myView->IsDefined())
388 myView->Window()->DoMapping();
391 //=============================================================================
392 //function : MustBeResized
394 //=============================================================================
395 void V3d_View::MustBeResized()
397 if (!myView->IsDefined())
405 if (myImmediateUpdate)
411 //=============================================================================
412 //function : SetBackgroundColor
414 //=============================================================================
415 void V3d_View::SetBackgroundColor (const Quantity_TypeOfColor theType,
416 const Standard_Real theV1,
417 const Standard_Real theV2,
418 const Standard_Real theV3)
420 Standard_Real aV1 = Max (Min (theV1, 1.0), 0.0);
421 Standard_Real aV2 = Max (Min (theV2, 1.0), 0.0);
422 Standard_Real aV3 = Max (Min (theV3, 1.0), 0.0);
424 SetBackgroundColor (Quantity_Color (aV1, aV2, aV3, theType));
427 //=============================================================================
428 //function : SetBackgroundColor
430 //=============================================================================
431 void V3d_View::SetBackgroundColor (const Quantity_Color& theColor)
433 myView->SetBackground (Aspect_Background (theColor));
435 if (myImmediateUpdate)
441 //=============================================================================
442 //function : SetBgGradientColors
444 //=============================================================================
445 void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
446 const Quantity_Color& theColor2,
447 const Aspect_GradientFillMethod theFillStyle,
448 const Standard_Boolean theToUpdate)
450 Aspect_GradientBackground aGradientBg (theColor1, theColor2, theFillStyle);
452 myView->SetGradientBackground (aGradientBg);
454 if (myImmediateUpdate || theToUpdate)
460 //=============================================================================
461 //function : SetBgGradientStyle
463 //=============================================================================
464 void V3d_View::SetBgGradientStyle (const Aspect_GradientFillMethod theFillStyle, const Standard_Boolean theToUpdate)
466 Quantity_Color aColor1;
467 Quantity_Color aColor2;
468 GradientBackground().Colors (aColor1, aColor2);
470 SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
473 //=============================================================================
474 //function : SetBackgroundImage
476 //=============================================================================
477 void V3d_View::SetBackgroundImage (const Standard_CString theFileName,
478 const Aspect_FillMethod theFillStyle,
479 const Standard_Boolean theToUpdate)
481 myView->SetBackgroundImage (theFileName);
482 myView->SetBackgroundImageStyle (theFillStyle);
484 if (myImmediateUpdate || theToUpdate)
490 //=============================================================================
491 //function : SetBgImageStyle
493 //=============================================================================
494 void V3d_View::SetBgImageStyle (const Aspect_FillMethod theFillStyle, const Standard_Boolean theToUpdate)
496 myView->SetBackgroundImageStyle (theFillStyle);
498 if (myImmediateUpdate || theToUpdate)
504 //=============================================================================
505 //function : SetBackgroundCubeMap
507 //=============================================================================
508 void V3d_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
509 Standard_Boolean theToUpdatePBREnv,
510 Standard_Boolean theToUpdate)
512 myView->SetBackgroundCubeMap (theCubeMap, theToUpdatePBREnv);
513 if (myImmediateUpdate || theToUpdate)
519 //=============================================================================
520 //function : GeneratePBREnvironment
522 //=============================================================================
523 void V3d_View::GeneratePBREnvironment (Standard_Boolean theToUpdate)
525 myView->GeneratePBREnvironment();
526 if (myImmediateUpdate || theToUpdate)
532 //=============================================================================
533 //function : ClearPBREnvironment
535 //=============================================================================
536 void V3d_View::ClearPBREnvironment (Standard_Boolean theToUpdate)
538 myView->ClearPBREnvironment();
539 if (myImmediateUpdate || theToUpdate)
545 //=============================================================================
548 //=============================================================================
549 void V3d_View::SetAxis (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
550 const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
552 myDefaultViewPoint.SetCoord (theX, theY, theZ);
553 myDefaultViewAxis.SetCoord (theVx, theVy, theVz);
556 //=============================================================================
557 //function : SetShadingModel
559 //=============================================================================
560 void V3d_View::SetShadingModel (const Graphic3d_TypeOfShadingModel theShadingModel)
562 myView->SetShadingModel (theShadingModel);
565 //=============================================================================
566 //function : SetTextureEnv
568 //=============================================================================
569 void V3d_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTexture)
571 myView->SetTextureEnv (theTexture);
573 if (myImmediateUpdate)
579 //=============================================================================
580 //function : SetVisualization
582 //=============================================================================
583 void V3d_View::SetVisualization (const V3d_TypeOfVisualization theType)
585 myView->SetVisualizationType (static_cast <Graphic3d_TypeOfVisualization> (theType));
587 if (myImmediateUpdate)
593 //=============================================================================
594 //function : SetFront
596 //=============================================================================
597 void V3d_View::SetFront()
599 gp_Ax3 a = MyViewer->PrivilegedPlane();
600 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
602 a.Direction().Coord(vx,vy,vz);
603 a.YDirection().Coord(xu,yu,zu);
604 a.Location().Coord(xo,yo,zo);
606 Handle(Graphic3d_Camera) aCamera = Camera();
608 aCamera->SetCenter (gp_Pnt (xo, yo, zo));
612 aCamera->SetDirection (gp_Dir (vx, vy, vz));
616 aCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
619 aCamera->SetUp (gp_Dir (xu, yu, zu));
623 SwitchSetFront = !SwitchSetFront;
628 //=============================================================================
631 //=============================================================================
632 void V3d_View::Rotate (const Standard_Real ax,
633 const Standard_Real ay,
634 const Standard_Real az,
635 const Standard_Boolean Start)
637 Standard_Real Ax = ax;
638 Standard_Real Ay = ay;
639 Standard_Real Az = az;
641 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
642 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
643 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
644 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
645 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
646 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
648 Handle(Graphic3d_Camera) aCamera = Camera();
652 myCamStartOpUp = aCamera->Up();
653 myCamStartOpDir = aCamera->Direction();
654 myCamStartOpEye = aCamera->Eye();
655 myCamStartOpCenter = aCamera->Center();
658 aCamera->SetUp (myCamStartOpUp);
659 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
660 aCamera->SetDirectionFromEye (myCamStartOpDir);
662 // rotate camera around 3 initial axes
663 gp_Dir aBackDir = -myCamStartOpDir;
664 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
665 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
666 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
668 gp_Trsf aRot[3], aTrsf;
669 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
670 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
671 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
672 aTrsf.Multiply (aRot[0]);
673 aTrsf.Multiply (aRot[1]);
674 aTrsf.Multiply (aRot[2]);
676 aCamera->Transform (aTrsf);
683 //=============================================================================
686 //=============================================================================
687 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
688 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
691 Standard_Real Ax = ax ;
692 Standard_Real Ay = ay ;
693 Standard_Real Az = az ;
695 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
696 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
697 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
698 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
699 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
700 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
702 Handle(Graphic3d_Camera) aCamera = Camera();
706 myGravityReferencePoint.SetCoord (X, Y, Z);
707 myCamStartOpUp = aCamera->Up();
708 myCamStartOpDir = aCamera->Direction();
709 myCamStartOpEye = aCamera->Eye();
710 myCamStartOpCenter = aCamera->Center();
713 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
715 aCamera->SetUp (myCamStartOpUp);
716 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
717 aCamera->SetDirectionFromEye (myCamStartOpDir);
719 // rotate camera around 3 initial axes
720 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
722 gp_Dir aZAxis (aCamera->Direction().Reversed());
723 gp_Dir aYAxis (aCamera->Up());
724 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
726 gp_Trsf aRot[3], aTrsf;
727 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
728 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
729 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
730 aTrsf.Multiply (aRot[0]);
731 aTrsf.Multiply (aRot[1]);
732 aTrsf.Multiply (aRot[2]);
734 aCamera->Transform (aTrsf);
741 //=============================================================================
744 //=============================================================================
745 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
749 Rotate(angle,0.,0.,Start);
752 Rotate(0.,angle,0.,Start);
755 Rotate(0.,0.,angle,Start);
760 //=============================================================================
763 //=============================================================================
764 void V3d_View::Rotate (const V3d_TypeOfAxe theAxe, const Standard_Real theAngle,
765 const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ, const Standard_Boolean theStart)
767 Standard_Real anAngle = theAngle;
769 if (anAngle > 0.0) while (anAngle > DEUXPI) anAngle -= DEUXPI;
770 else if (anAngle < 0.0) while (anAngle < -DEUXPI) anAngle += DEUXPI;
772 Handle(Graphic3d_Camera) aCamera = Camera();
776 myGravityReferencePoint.SetCoord (theX, theY, theZ);
777 myCamStartOpUp = aCamera->Up();
778 myCamStartOpDir = aCamera->Direction();
779 myCamStartOpEye = aCamera->Eye();
780 myCamStartOpCenter = aCamera->Center();
783 case V3d_X: myViewAxis = gp::DX(); break;
784 case V3d_Y: myViewAxis = gp::DY(); break;
785 case V3d_Z: myViewAxis = gp::DZ(); break;
789 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
791 aCamera->SetUp (myCamStartOpUp);
792 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
793 aCamera->SetDirectionFromEye (myCamStartOpDir);
795 // rotate camera around passed axis
797 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
798 gp_Dir aRAxis ((theAxe == V3d_X) ? 1.0 : 0.0,
799 (theAxe == V3d_Y) ? 1.0 : 0.0,
800 (theAxe == V3d_Z) ? 1.0 : 0.0);
802 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), anAngle);
804 aCamera->Transform (aRotation);
811 //=============================================================================
814 //=============================================================================
815 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
817 Standard_Real Angle = angle;
819 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
820 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
822 Handle(Graphic3d_Camera) aCamera = Camera();
826 myCamStartOpUp = aCamera->Up();
827 myCamStartOpDir = aCamera->Direction();
828 myCamStartOpEye = aCamera->Eye();
829 myCamStartOpCenter = aCamera->Center();
832 aCamera->SetUp (myCamStartOpUp);
833 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
834 aCamera->SetDirectionFromEye (myCamStartOpDir);
837 gp_Pnt aRCenter (myDefaultViewPoint);
838 gp_Dir aRAxis (myDefaultViewAxis);
839 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
841 aCamera->Transform (aRotation);
848 //=============================================================================
851 //=============================================================================
852 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
854 Standard_Real Ax = ax;
855 Standard_Real Ay = ay;
856 Standard_Real Az = az;
858 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
859 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
860 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
861 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
862 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
863 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
865 Handle(Graphic3d_Camera) aCamera = Camera();
869 myCamStartOpUp = aCamera->Up();
870 myCamStartOpDir = aCamera->Direction();
871 myCamStartOpEye = aCamera->Eye();
872 myCamStartOpCenter = aCamera->Center();
875 aCamera->SetUp (myCamStartOpUp);
876 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
877 aCamera->SetDirectionFromEye (myCamStartOpDir);
879 // rotate camera around 3 initial axes
880 gp_Pnt aRCenter = aCamera->Eye();
881 gp_Dir aZAxis (aCamera->Direction().Reversed());
882 gp_Dir aYAxis (aCamera->Up());
883 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
885 gp_Trsf aRot[3], aTrsf;
886 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
887 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
888 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
889 aTrsf.Multiply (aRot[0]);
890 aTrsf.Multiply (aRot[1]);
891 aTrsf.Multiply (aRot[2]);
893 aCamera->Transform (aTrsf);
900 //=============================================================================
903 //=============================================================================
904 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
908 Turn(angle,0.,0.,Start);
911 Turn(0.,angle,0.,Start);
914 Turn(0.,0.,angle,Start);
919 //=============================================================================
922 //=============================================================================
923 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
925 Standard_Real Angle = angle ;
927 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
928 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
930 Handle(Graphic3d_Camera) aCamera = Camera();
934 myCamStartOpUp = aCamera->Up();
935 myCamStartOpDir = aCamera->Direction();
936 myCamStartOpEye = aCamera->Eye();
937 myCamStartOpCenter = aCamera->Center();
940 aCamera->SetUp (myCamStartOpUp);
941 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
942 aCamera->SetDirectionFromEye (myCamStartOpDir);
945 gp_Pnt aRCenter = aCamera->Eye();
946 gp_Dir aRAxis (myDefaultViewAxis);
947 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
949 aCamera->Transform (aRotation);
956 //=============================================================================
957 //function : SetTwist
959 //=============================================================================
960 void V3d_View::SetTwist(const Standard_Real angle)
962 Standard_Real Angle = angle ;
964 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
965 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
967 Handle(Graphic3d_Camera) aCamera = Camera();
969 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
970 if (!screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
971 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
972 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
974 throw V3d_BadValue ("V3d_ViewSetTwist, alignment of Eye,At,Up,");
977 gp_Pnt aRCenter = aCamera->Center();
978 gp_Dir aZAxis (aCamera->Direction().Reversed());
981 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
983 aCamera->SetUp (gp_Dir (myYscreenAxis));
984 aCamera->Transform (aTrsf);
991 //=============================================================================
994 //=============================================================================
995 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
997 Standard_Real aTwistBefore = Twist();
999 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1001 Handle(Graphic3d_Camera) aCamera = Camera();
1003 aCamera->SetEye (gp_Pnt (X, Y, Z));
1005 SetTwist (aTwistBefore);
1009 SetImmediateUpdate (wasUpdateEnabled);
1014 //=============================================================================
1015 //function : SetDepth
1017 //=============================================================================
1018 void V3d_View::SetDepth(const Standard_Real Depth)
1020 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1022 Handle(Graphic3d_Camera) aCamera = Camera();
1026 // Move eye using center (target) as anchor.
1027 aCamera->SetDistance (Depth);
1031 // Move the view ref point instead of the eye.
1032 gp_Vec aDir (aCamera->Direction());
1033 gp_Pnt aCameraEye = aCamera->Eye();
1034 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1036 aCamera->SetCenter (aCameraCenter);
1044 //=============================================================================
1045 //function : SetProj
1047 //=============================================================================
1048 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1050 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1051 "V3d_View::SetProj, null projection vector");
1053 Standard_Real aTwistBefore = Twist();
1055 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1057 Camera()->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1059 SetTwist(aTwistBefore);
1063 SetImmediateUpdate (wasUpdateEnabled);
1068 //=============================================================================
1069 //function : SetProj
1071 //=============================================================================
1072 void V3d_View::SetProj (const V3d_TypeOfOrientation theOrientation,
1073 const Standard_Boolean theIsYup)
1075 Graphic3d_Vec3d anUp = theIsYup ? Graphic3d_Vec3d (0.0, 1.0, 0.0) : Graphic3d_Vec3d (0.0, 0.0, 1.0);
1078 if (theOrientation == V3d_Ypos
1079 || theOrientation == V3d_Yneg)
1081 anUp.SetValues (0.0, 0.0, -1.0);
1086 if (theOrientation == V3d_Zpos)
1088 anUp.SetValues (0.0, 1.0, 0.0);
1090 else if (theOrientation == V3d_Zneg)
1092 anUp.SetValues (0.0, -1.0, 0.0);
1096 const gp_Dir aBck = V3d::GetProjAxis (theOrientation);
1098 // retain camera panning from origin when switching projection
1099 const Handle(Graphic3d_Camera)& aCamera = Camera();
1100 const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
1102 const Standard_Real aNewDist = aCamera->Eye().Distance (gp_Pnt (0, 0, 0));
1103 aCamera->SetEyeAndCenter (gp_XYZ (0, 0, 0) + aBck.XYZ() * aNewDist,
1105 aCamera->SetDirectionFromEye (-aBck);
1106 aCamera->SetUp (gp_Dir (anUp.x(), anUp.y(), anUp.z()));
1107 aCamera->OrthogonalizeUp();
1109 Panning (anOriginVCS.X(), anOriginVCS.Y());
1116 //=============================================================================
1119 //=============================================================================
1120 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1122 Standard_Real aTwistBefore = Twist();
1124 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1126 Camera()->SetCenter (gp_Pnt (X, Y, Z));
1128 SetTwist (aTwistBefore);
1132 SetImmediateUpdate (wasUpdateEnabled);
1137 //=============================================================================
1140 //=============================================================================
1141 void V3d_View::SetUp (const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
1143 Handle(Graphic3d_Camera) aCamera = Camera();
1145 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1146 const gp_Dir anUp (theVx, theVy, theVz);
1147 if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis)
1148 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1149 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1150 && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1152 throw V3d_BadValue ("V3d_View::Setup, alignment of Eye,At,Up");
1155 aCamera->SetUp (gp_Dir (myYscreenAxis));
1162 //=============================================================================
1165 //=============================================================================
1166 void V3d_View::SetUp (const V3d_TypeOfOrientation theOrientation)
1168 Handle(Graphic3d_Camera) aCamera = Camera();
1170 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1171 const gp_Dir anUp = V3d::GetProjAxis (theOrientation);
1172 if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis)
1173 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1174 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1175 && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1177 throw V3d_BadValue ("V3d_View::SetUp, alignment of Eye,At,Up");
1180 aCamera->SetUp (gp_Dir (myYscreenAxis));
1187 //=============================================================================
1188 //function : SetViewOrientationDefault
1190 //=============================================================================
1191 void V3d_View::SetViewOrientationDefault()
1193 myDefaultCamera->CopyOrientationData (Camera());
1196 //=======================================================================
1197 //function : SetViewMappingDefault
1199 //=======================================================================
1200 void V3d_View::SetViewMappingDefault()
1202 myDefaultCamera->CopyMappingData (Camera());
1205 //=============================================================================
1206 //function : ResetViewOrientation
1208 //=============================================================================
1209 void V3d_View::ResetViewOrientation()
1211 Camera()->CopyOrientationData (myDefaultCamera);
1218 //=======================================================================
1219 //function : ResetViewMapping
1221 //=======================================================================
1222 void V3d_View::ResetViewMapping()
1224 Camera()->CopyMappingData (myDefaultCamera);
1231 //=============================================================================
1234 //=============================================================================
1235 void V3d_View::Reset (const Standard_Boolean theToUpdate)
1237 Camera()->Copy (myDefaultCamera);
1241 SwitchSetFront = Standard_False;
1243 if (myImmediateUpdate || theToUpdate)
1249 //=======================================================================
1250 //function : SetCenter
1252 //=======================================================================
1253 void V3d_View::SetCenter (const Standard_Integer theXp,
1254 const Standard_Integer theYp)
1256 Standard_Real aXv, aYv;
1257 Convert (theXp, theYp, aXv, aYv);
1258 Translate (Camera(), aXv, aYv);
1263 //=============================================================================
1264 //function : SetSize
1266 //=============================================================================
1267 void V3d_View::SetSize (const Standard_Real theSize)
1269 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1271 Handle(Graphic3d_Camera) aCamera = Camera();
1273 aCamera->SetScale (aCamera->Aspect() >= 1.0 ? theSize / aCamera->Aspect() : theSize);
1280 //=============================================================================
1281 //function : SetZSize
1283 //=============================================================================
1284 void V3d_View::SetZSize (const Standard_Real theSize)
1286 Handle(Graphic3d_Camera) aCamera = Camera();
1288 Standard_Real Zmax = theSize / 2.;
1290 Standard_Real aDistance = aCamera->Distance();
1297 // ShortReal precision factor used to add meaningful tolerance to
1298 // ZNear, ZFar values in order to avoid equality after type conversion
1299 // to ShortReal matrices type.
1300 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1302 Standard_Real aZFar = Zmax + aDistance * 2.0;
1303 Standard_Real aZNear = -Zmax + aDistance;
1304 aZNear -= Abs (aZNear) * aPrecision;
1305 aZFar += Abs (aZFar) * aPrecision;
1307 if (!aCamera->IsOrthographic())
1309 if (aZFar < aPrecision)
1311 // Invalid case when both values are negative
1312 aZNear = aPrecision;
1313 aZFar = aPrecision * 2.0;
1315 else if (aZNear < Abs (aZFar) * aPrecision)
1317 // Z is less than 0.0, try to fix it using any appropriate z-scale
1318 aZNear = Abs (aZFar) * aPrecision;
1322 // If range is too small
1323 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1325 aZFar = aZNear + Abs (aZFar) * aPrecision;
1328 aCamera->SetZRange (aZNear, aZFar);
1330 if (myImmediateUpdate)
1336 //=============================================================================
1337 //function : SetZoom
1339 //=============================================================================
1340 void V3d_View::SetZoom (const Standard_Real theCoef,const Standard_Boolean theToStart)
1342 V3d_BadValue_Raise_if (theCoef <= 0., "V3d_View::SetZoom, bad coefficient");
1344 Handle(Graphic3d_Camera) aCamera = Camera();
1348 myCamStartOpEye = aCamera->Eye();
1349 myCamStartOpCenter = aCamera->Center();
1352 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
1353 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
1355 // ensure that zoom will not be too small or too big
1356 Standard_Real aCoef = theCoef;
1357 if (aViewWidth < aCoef * Precision::Confusion())
1359 aCoef = aViewWidth / Precision::Confusion();
1361 else if (aViewWidth > aCoef * 1e12)
1363 aCoef = aViewWidth / 1e12;
1365 if (aViewHeight < aCoef * Precision::Confusion())
1367 aCoef = aViewHeight / Precision::Confusion();
1369 else if (aViewHeight > aCoef * 1e12)
1371 aCoef = aViewHeight / 1e12;
1374 aCamera->SetEye (myCamStartOpEye);
1375 aCamera->SetCenter (myCamStartOpCenter);
1376 aCamera->SetScale (aCamera->Scale() / aCoef);
1383 //=============================================================================
1384 //function : SetScale
1386 //=============================================================================
1387 void V3d_View::SetScale( const Standard_Real Coef )
1389 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1391 Handle(Graphic3d_Camera) aCamera = Camera();
1393 Standard_Real aDefaultScale = myDefaultCamera->Scale();
1394 aCamera->SetAspect (myDefaultCamera->Aspect());
1395 aCamera->SetScale (aDefaultScale / Coef);
1402 //=============================================================================
1403 //function : SetAxialScale
1405 //=============================================================================
1406 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1408 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1410 Camera()->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1415 //=============================================================================
1416 //function : SetRatio
1418 //=============================================================================
1419 void V3d_View::SetRatio()
1421 if (MyWindow.IsNull())
1426 Standard_Integer aWidth = 0;
1427 Standard_Integer aHeight = 0;
1428 MyWindow->Size (aWidth, aHeight);
1429 if (aWidth > 0 && aHeight > 0)
1431 Standard_Real aRatio = static_cast<Standard_Real> (aWidth) /
1432 static_cast<Standard_Real> (aHeight);
1434 Camera() ->SetAspect (aRatio);
1435 myDefaultCamera->SetAspect (aRatio);
1439 //=============================================================================
1442 //=============================================================================
1443 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1445 FitAll (myView->MinMaxValues(), theMargin, theToUpdate);
1448 //=============================================================================
1451 //=============================================================================
1452 void V3d_View::FitAll (const Bnd_Box& theBox, const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1454 Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1456 if (myView->NumberOfDisplayedStructures() == 0)
1461 if (!FitMinMax (Camera(), theBox, theMargin, 10.0 * Precision::Confusion()))
1468 if (myImmediateUpdate || theToUpdate)
1474 //=============================================================================
1475 //function : DepthFitAll
1477 //=============================================================================
1478 void V3d_View::DepthFitAll(const Standard_Real Aspect,
1479 const Standard_Real Margin)
1481 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1482 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1483 Standard_Real Dx,Dy,Dz,Size;
1485 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1487 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1492 Bnd_Box aBox = myView->MinMaxValues();
1498 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1499 Project (Xmin,Ymin,Zmin,U,V,W) ;
1500 Project (Xmax,Ymax,Zmax,U1,V1,W1) ;
1501 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1502 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1503 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1504 Project (Xmin,Ymin,Zmax,U,V,W) ;
1505 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1506 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1507 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1508 Project (Xmax,Ymin,Zmax,U,V,W) ;
1509 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1510 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1511 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1512 Project (Xmax,Ymin,Zmin,U,V,W) ;
1513 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1514 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1515 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1516 Project (Xmax,Ymax,Zmin,U,V,W) ;
1517 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1518 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1519 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1520 Project (Xmin,Ymax,Zmax,U,V,W) ;
1521 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1522 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1523 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1524 Project (Xmin,Ymax,Zmin,U,V,W) ;
1525 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1526 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1527 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1530 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1531 Dz = 2.*Wmax + Margin * Wmax;
1533 // Compute depth value
1534 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1535 Dx += Margin * Dx; Dy += Margin * Dy;
1536 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1539 SetDepth( Aspect * Size / 2.);
1545 //=======================================================================
1546 //function : WindowFit
1548 //=======================================================================
1549 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1550 const Standard_Integer theMinYp,
1551 const Standard_Integer theMaxXp,
1552 const Standard_Integer theMaxYp)
1554 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1556 Handle(Graphic3d_Camera) aCamera = Camera();
1558 if (!aCamera->IsOrthographic())
1560 // normalize view coordinates
1561 Standard_Integer aWinWidth, aWinHeight;
1562 MyWindow->Size (aWinWidth, aWinHeight);
1564 // z coordinate of camera center
1565 Standard_Real aDepth = aCamera->Project (aCamera->Center()).Z();
1567 // camera projection coordinate are in NDC which are normalized [-1, 1]
1568 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1569 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1570 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1571 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1573 // compute camera panning
1574 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1575 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1576 gp_Pnt aPanTo = aCamera->ConvertProj2View (aFitCenter);
1577 gp_Pnt aPanFrom = aCamera->ConvertProj2View (aScreenCenter);
1578 gp_Vec aPanVec (aPanFrom, aPanTo);
1580 // compute section size
1581 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1582 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1583 gp_Pnt aViewBotLeft = aCamera->ConvertProj2View (aFitBotLeft);
1584 gp_Pnt aViewTopRight = aCamera->ConvertProj2View (aFitTopRight);
1586 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1587 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1589 Translate (aCamera, aPanVec.X(), -aPanVec.Y());
1590 Scale (aCamera, aUSize, aVSize);
1595 Standard_Real aX1, aY1, aX2, aY2;
1596 Convert (theMinXp, theMinYp, aX1, aY1);
1597 Convert (theMaxXp, theMaxYp, aX2, aY2);
1598 FitAll (aX1, aY1, aX2, aY2);
1601 SetImmediateUpdate (wasUpdateEnabled);
1606 //=======================================================================
1607 //function : ConvertToGrid
1609 //=======================================================================
1610 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1611 const Standard_Integer Yp,
1614 Standard_Real& Zg) const
1616 Graphic3d_Vertex aVrp;
1617 Standard_Real anX, anY, aZ;
1618 Convert (Xp, Yp, anX, anY, aZ);
1619 aVrp.SetCoord (anX, anY, aZ);
1621 if( MyViewer->Grid()->IsActive() ) {
1622 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1623 aNewVrp.Coord (Xg,Yg,Zg) ;
1625 aVrp.Coord (Xg,Yg,Zg) ;
1628 //=======================================================================
1629 //function : ConvertToGrid
1631 //=======================================================================
1632 void V3d_View::ConvertToGrid(const Standard_Real X,
1633 const Standard_Real Y,
1634 const Standard_Real Z,
1637 Standard_Real& Zg) const
1639 if( MyViewer->Grid()->IsActive() ) {
1640 Graphic3d_Vertex aVrp (X,Y,Z) ;
1641 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1642 aNewVrp.Coord(Xg,Yg,Zg) ;
1644 Xg = X; Yg = Y; Zg = Z;
1648 //=======================================================================
1649 //function : Convert
1651 //=======================================================================
1652 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1654 Standard_Integer aDxw, aDyw ;
1656 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1658 MyWindow->Size (aDxw, aDyw);
1659 Standard_Real aValue;
1661 gp_Pnt aViewDims = Camera()->ViewDimensions();
1662 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1667 //=======================================================================
1668 //function : Convert
1670 //=======================================================================
1671 void V3d_View::Convert(const Standard_Integer Xp,
1672 const Standard_Integer Yp,
1674 Standard_Real& Yv) const
1676 Standard_Integer aDxw, aDyw;
1678 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1680 MyWindow->Size (aDxw, aDyw);
1682 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1683 aPoint = Camera()->ConvertProj2View (aPoint);
1689 //=======================================================================
1690 //function : Convert
1692 //=======================================================================
1693 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1695 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1697 Standard_Integer aDxw, aDyw;
1698 MyWindow->Size (aDxw, aDyw);
1700 gp_Pnt aViewDims = Camera()->ViewDimensions();
1701 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1706 //=======================================================================
1707 //function : Convert
1709 //=======================================================================
1710 void V3d_View::Convert(const Standard_Real Xv,
1711 const Standard_Real Yv,
1712 Standard_Integer& Xp,
1713 Standard_Integer& Yp) const
1715 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1717 Standard_Integer aDxw, aDyw;
1718 MyWindow->Size (aDxw, aDyw);
1720 gp_Pnt aPoint (Xv, Yv, 0.0);
1721 aPoint = Camera()->ConvertView2Proj (aPoint);
1722 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1724 Xp = RealToInt (aPoint.X());
1725 Yp = RealToInt (aPoint.Y());
1728 //=======================================================================
1729 //function : Convert
1731 //=======================================================================
1732 void V3d_View::Convert(const Standard_Integer Xp,
1733 const Standard_Integer Yp,
1736 Standard_Real& Z) const
1738 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1739 Standard_Integer aHeight, aWidth;
1740 MyWindow->Size (aWidth, aHeight);
1742 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1743 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1744 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1746 gp_Pnt aResult = Camera()->UnProject (gp_Pnt (anX, anY, aZ));
1753 //=======================================================================
1754 //function : ConvertWithProj
1756 //=======================================================================
1757 void V3d_View::ConvertWithProj(const Standard_Integer theXp,
1758 const Standard_Integer theYp,
1759 Standard_Real& theX,
1760 Standard_Real& theY,
1761 Standard_Real& theZ,
1762 Standard_Real& theDx,
1763 Standard_Real& theDy,
1764 Standard_Real& theDz) const
1766 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1767 Standard_Integer aHeight = 0, aWidth = 0;
1768 MyWindow->Size (aWidth, aHeight);
1770 const Standard_Real anX = 2.0 * theXp / aWidth - 1.0;
1771 const Standard_Real anY = 2.0 * (aHeight - 1 - theYp) / aHeight - 1.0;
1772 const Standard_Real aZ = 2.0 * 0.0 - 1.0;
1774 const Handle(Graphic3d_Camera)& aCamera = Camera();
1775 const gp_Pnt aResult1 = aCamera->UnProject (gp_Pnt (anX, anY, aZ));
1776 const gp_Pnt aResult2 = aCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1778 theX = aResult1.X();
1779 theY = aResult1.Y();
1780 theZ = aResult1.Z();
1781 Graphic3d_Vec3d aNormDir (theX - aResult2.X(),
1782 theY - aResult2.Y(),
1783 theZ - aResult2.Z());
1784 aNormDir.Normalize();
1786 theDx = aNormDir.x();
1787 theDy = aNormDir.y();
1788 theDz = aNormDir.z();
1791 //=======================================================================
1792 //function : Convert
1794 //=======================================================================
1795 void V3d_View::Convert(const Standard_Real X,
1796 const Standard_Real Y,
1797 const Standard_Real Z,
1798 Standard_Integer& Xp,
1799 Standard_Integer& Yp) const
1801 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1802 Standard_Integer aHeight, aWidth;
1803 MyWindow->Size (aWidth, aHeight);
1805 gp_Pnt aPoint = Camera()->Project (gp_Pnt (X, Y, Z));
1807 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1808 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1811 //=======================================================================
1812 //function : Project
1814 //=======================================================================
1815 void V3d_View::Project (const Standard_Real theX,
1816 const Standard_Real theY,
1817 const Standard_Real theZ,
1818 Standard_Real& theXp,
1819 Standard_Real& theYp) const
1822 Project (theX, theY, theZ, theXp, theYp, aZp);
1825 //=======================================================================
1826 //function : Project
1828 //=======================================================================
1829 void V3d_View::Project (const Standard_Real theX,
1830 const Standard_Real theY,
1831 const Standard_Real theZ,
1832 Standard_Real& theXp,
1833 Standard_Real& theYp,
1834 Standard_Real& theZp) const
1836 Handle(Graphic3d_Camera) aCamera = Camera();
1838 gp_XYZ aViewSpaceDimensions = aCamera->ViewDimensions();
1839 Standard_Real aXSize = aViewSpaceDimensions.X();
1840 Standard_Real aYSize = aViewSpaceDimensions.Y();
1841 Standard_Real aZSize = aViewSpaceDimensions.Z();
1843 gp_Pnt aPoint = aCamera->Project (gp_Pnt (theX, theY, theZ));
1845 // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
1846 theXp = aPoint.X() * aXSize * 0.5;
1847 theYp = aPoint.Y() * aYSize * 0.5;
1848 theZp = aPoint.Z() * aZSize * 0.5;
1851 //=======================================================================
1852 //function : BackgroundColor
1854 //=======================================================================
1855 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1858 Standard_Real& V3) const
1860 Quantity_Color C = BackgroundColor() ;
1861 C.Values(V1,V2,V3,Type) ;
1864 //=======================================================================
1865 //function : BackgroundColor
1867 //=======================================================================
1868 Quantity_Color V3d_View::BackgroundColor() const
1870 return myView->Background().Color() ;
1873 //=======================================================================
1874 //function : GradientBackgroundColors
1876 //=======================================================================
1877 void V3d_View::GradientBackgroundColors (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1879 myView->GradientBackground().Colors (theColor1, theColor2);
1882 //=======================================================================
1883 //function : GradientBackground
1885 //=======================================================================
1886 Aspect_GradientBackground V3d_View::GradientBackground() const
1888 return myView->GradientBackground();
1891 //=======================================================================
1894 //=======================================================================
1895 Standard_Real V3d_View::Scale() const
1897 return myDefaultCamera->Scale() / Camera()->Scale();
1900 //=======================================================================
1901 //function : AxialScale
1903 //=======================================================================
1904 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1906 gp_Pnt anAxialScale = Camera()->AxialScale();
1907 Sx = anAxialScale.X();
1908 Sy = anAxialScale.Y();
1909 Sz = anAxialScale.Z();
1912 //=======================================================================
1915 //=======================================================================
1916 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1918 gp_Pnt aViewDims = Camera()->ViewDimensions();
1920 Width = aViewDims.X();
1921 Height = aViewDims.Y();
1924 //=======================================================================
1927 //=======================================================================
1928 Standard_Real V3d_View::ZSize() const
1930 gp_Pnt aViewDims = Camera()->ViewDimensions();
1932 return aViewDims.Z();
1935 //=======================================================================
1938 //=======================================================================
1939 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
1940 Standard_Real& Vmin,
1941 Standard_Real& Umax,
1942 Standard_Real& Vmax) const
1944 Standard_Real Wmin,Wmax,U,V,W ;
1945 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
1947 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1950 Bnd_Box aBox = myView->MinMaxValues();
1951 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1952 Project (Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
1953 Project (Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
1954 Project (Xmin,Ymin,Zmax,U,V,W) ;
1955 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1956 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1957 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1958 Project (Xmax,Ymin,Zmax,U,V,W) ;
1959 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1960 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1961 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1962 Project (Xmax,Ymin,Zmin,U,V,W) ;
1963 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1964 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1965 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1966 Project (Xmax,Ymax,Zmin,U,V,W) ;
1967 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1968 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1969 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1970 Project (Xmin,Ymax,Zmax,U,V,W) ;
1971 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1972 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1973 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1974 Project (Xmin,Ymax,Zmin,U,V,W) ;
1975 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1976 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1977 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1982 //=======================================================================
1985 //=======================================================================
1986 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
1987 Standard_Real& Ymin,
1988 Standard_Real& Zmin,
1989 Standard_Real& Xmax,
1990 Standard_Real& Ymax,
1991 Standard_Real& Zmax) const
1994 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
1995 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1998 Bnd_Box aBox = myView->MinMaxValues();
1999 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2004 //=======================================================================
2005 //function : GravityPoint
2007 //=======================================================================
2008 gp_Pnt V3d_View::GravityPoint() const
2010 Graphic3d_MapOfStructure aSetOfStructures;
2011 myView->DisplayedStructures (aSetOfStructures);
2013 Standard_Boolean hasSelection = Standard_False;
2014 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2015 aStructIter.More(); aStructIter.Next())
2017 if (aStructIter.Key()->IsHighlighted()
2018 && aStructIter.Key()->IsVisible())
2020 hasSelection = Standard_True;
2025 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
2026 Standard_Integer aNbPoints = 0;
2027 gp_XYZ aResult (0.0, 0.0, 0.0);
2028 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2029 aStructIter.More(); aStructIter.Next())
2031 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2032 if (!aStruct->IsVisible()
2033 || aStruct->IsInfinite()
2034 || (hasSelection && !aStruct->IsHighlighted()))
2039 const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox();
2040 if (!aBox.IsValid())
2045 // skip transformation-persistent objects
2046 if (!aStruct->TransformPersistence().IsNull())
2051 // use camera projection to find gravity point
2052 Xmin = aBox.CornerMin().x();
2053 Ymin = aBox.CornerMin().y();
2054 Zmin = aBox.CornerMin().z();
2055 Xmax = aBox.CornerMax().x();
2056 Ymax = aBox.CornerMax().y();
2057 Zmax = aBox.CornerMax().z();
2058 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2060 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2061 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2062 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2063 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2066 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2068 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2069 const gp_Pnt aProjected = Camera()->Project (aBndPnt);
2070 if (Abs (aProjected.X()) <= 1.0
2071 && Abs (aProjected.Y()) <= 1.0)
2073 aResult += aBndPnt.XYZ();
2081 // fallback - just use bounding box of entire scene
2082 Bnd_Box aBox = myView->MinMaxValues();
2085 aBox.Get (Xmin, Ymin, Zmin,
2087 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2089 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2090 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2091 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2092 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2095 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2097 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2098 aResult += aBndPnt.XYZ();
2106 aResult /= aNbPoints;
2112 //=======================================================================
2115 //=======================================================================
2116 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2118 gp_Pnt aCameraEye = Camera()->Eye();
2124 //=============================================================================
2125 //function : ProjReferenceAxe
2127 //=============================================================================
2128 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2129 const Standard_Integer Ypix,
2135 Standard_Real& VZ) const
2137 Standard_Real Xo,Yo,Zo;
2139 Convert (Xpix, Ypix, XP, YP, ZP);
2140 if ( Type() == V3d_PERSPECTIVE )
2142 FocalReferencePoint (Xo,Yo,Zo);
2153 //=============================================================================
2156 //=============================================================================
2157 Standard_Real V3d_View::Depth() const
2159 return Camera()->Distance();
2162 //=============================================================================
2165 //=============================================================================
2166 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2168 gp_Dir aCameraDir = Camera()->Direction().Reversed();
2169 Dx = aCameraDir.X();
2170 Dy = aCameraDir.Y();
2171 Dz = aCameraDir.Z();
2174 //=============================================================================
2177 //=============================================================================
2178 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2180 gp_Pnt aCameraCenter = Camera()->Center();
2181 X = aCameraCenter.X();
2182 Y = aCameraCenter.Y();
2183 Z = aCameraCenter.Z();
2186 //=============================================================================
2189 //=============================================================================
2190 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2192 gp_Dir aCameraUp = Camera()->Up();
2198 //=============================================================================
2201 //=============================================================================
2202 Standard_Real V3d_View::Twist() const
2204 gp_Vec Xaxis, Yaxis, Zaxis;
2205 const gp_Dir aReferencePlane (Camera()->Direction().Reversed());
2206 if (!screenAxis (aReferencePlane, gp::DZ(), Xaxis, Yaxis, Zaxis)
2207 && !screenAxis (aReferencePlane, gp::DY(), Xaxis, Yaxis, Zaxis)
2208 && !screenAxis (aReferencePlane, gp::DX(), Xaxis, Yaxis, Zaxis))
2213 // Compute Cross Vector From Up & Origin
2214 const gp_Dir aCameraUp = Camera()->Up();
2215 const gp_XYZ aP = Yaxis.XYZ().Crossed (aCameraUp.XYZ());
2218 Standard_Real anAngle = ASin (Max (Min (aP.Modulus(), 1.0), -1.0));
2219 if (Yaxis.Dot (aCameraUp.XYZ()) < 0.0)
2221 anAngle = M_PI - anAngle;
2226 const gp_Dir aProjDir = Camera()->Direction().Reversed();
2227 if (aP.Dot (aProjDir.XYZ()) < 0.0)
2229 anAngle = DEUXPI - anAngle;
2235 //=============================================================================
2236 //function : ShadingModel
2238 //=============================================================================
2239 Graphic3d_TypeOfShadingModel V3d_View::ShadingModel() const
2241 return myView->ShadingModel();
2244 //=============================================================================
2245 //function : TextureEnv
2247 //=============================================================================
2248 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2250 return myView->TextureEnv();
2253 //=============================================================================
2254 //function : Visualization
2256 //=============================================================================
2257 V3d_TypeOfVisualization V3d_View::Visualization() const
2259 return static_cast<V3d_TypeOfVisualization> (myView->VisualizationType());
2262 //=============================================================================
2263 //function : IfWindow
2265 //=============================================================================
2266 Standard_Boolean V3d_View::IfWindow() const
2268 return myView->IsDefined();
2271 //=============================================================================
2274 //=============================================================================
2275 V3d_TypeOfView V3d_View::Type() const
2277 return Camera()->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2280 //=============================================================================
2281 //function : SetFocale
2283 //=============================================================================
2284 void V3d_View::SetFocale( const Standard_Real focale )
2286 Handle(Graphic3d_Camera) aCamera = Camera();
2288 if (aCamera->IsOrthographic())
2293 Standard_Real aFOVyRad = ATan (focale / (aCamera->Distance() * 2.0));
2295 aCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2300 //=============================================================================
2303 //=============================================================================
2304 Standard_Real V3d_View::Focale() const
2306 Handle(Graphic3d_Camera) aCamera = Camera();
2308 if (aCamera->IsOrthographic())
2313 return aCamera->Distance() * 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
2316 //=============================================================================
2317 //function : screenAxis
2319 //=============================================================================
2320 Standard_Boolean V3d_View::screenAxis (const gp_Dir& theVpn, const gp_Dir& theVup,
2321 gp_Vec& theXaxe, gp_Vec& theYaxe, gp_Vec& theZaxe)
2323 theXaxe = theVup.XYZ().Crossed (theVpn.XYZ());
2324 if (theXaxe.Magnitude() <= gp::Resolution())
2326 return Standard_False;
2328 theXaxe.Normalize();
2330 theYaxe = theVpn.XYZ().Crossed (theXaxe.XYZ());
2331 if (theYaxe.Magnitude() <= gp::Resolution())
2333 return Standard_False;
2335 theYaxe.Normalize();
2337 theZaxe = theVpn.XYZ();
2338 theZaxe.Normalize();
2339 return Standard_True;
2342 //=============================================================================
2343 //function : TrsPoint
2345 //=============================================================================
2346 gp_XYZ V3d_View::TrsPoint (const Graphic3d_Vertex& thePnt, const TColStd_Array2OfReal& theMat)
2349 const Standard_Integer lr = theMat.LowerRow();
2350 const Standard_Integer ur = theMat.UpperRow();
2351 const Standard_Integer lc = theMat.LowerCol();
2352 const Standard_Integer uc = theMat.UpperCol();
2353 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4))
2355 return gp_XYZ (thePnt.X(), thePnt.Y(), thePnt.Z());
2358 Standard_Real X, Y, Z;
2359 thePnt.Coord (X,Y,Z);
2360 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);
2361 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);
2362 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);
2363 return gp_XYZ (XX, YY, ZZ);
2366 //=======================================================================
2369 //=======================================================================
2370 void V3d_View::Pan (const Standard_Integer theDXp,
2371 const Standard_Integer theDYp,
2372 const Standard_Real theZoomFactor,
2373 const Standard_Boolean theToStart)
2375 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2378 //=======================================================================
2379 //function : Panning
2381 //=======================================================================
2382 void V3d_View::Panning (const Standard_Real theDXv,
2383 const Standard_Real theDYv,
2384 const Standard_Real theZoomFactor,
2385 const Standard_Boolean theToStart)
2387 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2389 Handle(Graphic3d_Camera) aCamera = Camera();
2393 myCamStartOpDir = aCamera->Direction();
2394 myCamStartOpEye = aCamera->Eye();
2395 myCamStartOpCenter = aCamera->Center();
2398 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2400 gp_Pnt aViewDims = aCamera->ViewDimensions();
2402 aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
2403 aCamera->SetDirectionFromEye (myCamStartOpDir);
2404 Translate (aCamera, -theDXv, -theDYv);
2405 Scale (aCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2407 SetImmediateUpdate (wasUpdateEnabled);
2412 //=======================================================================
2415 //=======================================================================
2416 void V3d_View::Zoom (const Standard_Integer theXp1,
2417 const Standard_Integer theYp1,
2418 const Standard_Integer theXp2,
2419 const Standard_Integer theYp2)
2421 Standard_Integer aDx = theXp2 - theXp1;
2422 Standard_Integer aDy = theYp2 - theYp1;
2423 if (aDx != 0 || aDy != 0)
2425 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2426 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2427 SetZoom (aCoeff, Standard_True);
2431 //=======================================================================
2432 //function : StartZoomAtPoint
2434 //=======================================================================
2435 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2436 const Standard_Integer theYp)
2438 MyZoomAtPointX = theXp;
2439 MyZoomAtPointY = theYp;
2442 //=======================================================================
2443 //function : ZoomAtPoint
2445 //=======================================================================
2446 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2447 const Standard_Integer theMouseStartY,
2448 const Standard_Integer theMouseEndX,
2449 const Standard_Integer theMouseEndY)
2451 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2454 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2455 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2456 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2458 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2460 Handle(Graphic3d_Camera) aCamera = Camera();
2462 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
2463 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
2465 // ensure that zoom will not be too small or too big.
2466 Standard_Real aCoef = aDZoom;
2467 if (aViewWidth < aCoef * Precision::Confusion())
2469 aCoef = aViewWidth / Precision::Confusion();
2471 else if (aViewWidth > aCoef * 1e12)
2473 aCoef = aViewWidth / 1e12;
2475 if (aViewHeight < aCoef * Precision::Confusion())
2477 aCoef = aViewHeight / Precision::Confusion();
2479 else if (aViewHeight > aCoef * 1e12)
2481 aCoef = aViewHeight / 1e12;
2484 Standard_Real aZoomAtPointXv = 0.0;
2485 Standard_Real aZoomAtPointYv = 0.0;
2486 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2488 Standard_Real aDxv = aZoomAtPointXv / aCoef;
2489 Standard_Real aDyv = aZoomAtPointYv / aCoef;
2491 aCamera->SetScale (aCamera->Scale() / aCoef);
2492 Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2496 SetImmediateUpdate (wasUpdateEnabled);
2501 //=============================================================================
2502 //function : AxialScale
2504 //=============================================================================
2505 void V3d_View::AxialScale (const Standard_Integer Dx,
2506 const Standard_Integer Dy,
2507 const V3d_TypeOfAxe Axis)
2509 if( Dx != 0. || Dy != 0. ) {
2510 Standard_Real Sx, Sy, Sz;
2511 AxialScale( Sx, Sy, Sz );
2512 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2513 dscale = (Dx > 0) ? dscale : 1./dscale;
2514 if( Axis == V3d_X ) Sx = dscale;
2515 if( Axis == V3d_Y ) Sy = dscale;
2516 if( Axis == V3d_Z ) Sz = dscale;
2517 SetAxialScale( Sx, Sy, Sz );
2521 //=============================================================================
2524 //=============================================================================
2525 void V3d_View::FitAll(const Standard_Real theXmin,
2526 const Standard_Real theYmin,
2527 const Standard_Real theXmax,
2528 const Standard_Real theYmax)
2530 Handle(Graphic3d_Camera) aCamera = Camera();
2531 Standard_Real anAspect = aCamera->Aspect();
2533 Standard_Real aFitSizeU = Abs (theXmax - theXmin);
2534 Standard_Real aFitSizeV = Abs (theYmax - theYmin);
2535 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2536 if (aFitAspect >= anAspect)
2538 aFitSizeV = aFitSizeU / anAspect;
2542 aFitSizeU = aFitSizeV * anAspect;
2545 Translate (aCamera, (theXmin + theXmax) * 0.5, (theYmin + theYmax) * 0.5);
2546 Scale (aCamera, aFitSizeU, aFitSizeV);
2553 //=============================================================================
2554 //function : StartRotation
2556 //=============================================================================
2557 void V3d_View::StartRotation(const Standard_Integer X,
2558 const Standard_Integer Y,
2559 const Standard_Real zRotationThreshold)
2564 rx = Standard_Real(Convert(x));
2565 ry = Standard_Real(Convert(y));
2566 myRotateGravity = GravityPoint();
2567 Rotate (0.0, 0.0, 0.0,
2568 myRotateGravity.X(), myRotateGravity.Y(), myRotateGravity.Z(),
2570 myZRotation = Standard_False;
2571 if( zRotationThreshold > 0. ) {
2572 Standard_Real dx = Abs(sx - rx/2.);
2573 Standard_Real dy = Abs(sy - ry/2.);
2574 // if( dx > rx/3. || dy > ry/3. ) myZRotation = Standard_True;
2575 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2576 if( dx > dd || dy > dd ) myZRotation = Standard_True;
2581 //=============================================================================
2582 //function : Rotation
2584 //=============================================================================
2585 void V3d_View::Rotation(const Standard_Integer X,
2586 const Standard_Integer Y)
2588 if( rx == 0. || ry == 0. ) {
2592 Standard_Real dx=0.,dy=0.,dz=0.;
2594 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2595 atan2(sx-rx/2.,ry/2.-sy);
2597 dx = (Standard_Real(X) - sx) * M_PI / rx;
2598 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2602 myRotateGravity.X(), myRotateGravity.Y(), myRotateGravity.Z(),
2606 //=============================================================================
2607 //function : SetComputedMode
2609 //=============================================================================
2610 void V3d_View::SetComputedMode (const Standard_Boolean theMode)
2616 myView->SetComputedMode (Standard_True);
2621 myView->SetComputedMode (Standard_False);
2625 //=============================================================================
2626 //function : ComputedMode
2628 //=============================================================================
2629 Standard_Boolean V3d_View::ComputedMode() const
2631 return myView->ComputedMode();
2634 //=============================================================================
2635 //function : SetBackFacingModel
2637 //=============================================================================
2638 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel theModel)
2640 myView->SetBackfacingModel (static_cast<Graphic3d_TypeOfBackfacingModel> (theModel));
2644 //=============================================================================
2645 //function : BackFacingModel
2647 //=============================================================================
2648 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2650 return static_cast<V3d_TypeOfBackfacingModel> (myView->BackfacingModel());
2653 //=============================================================================
2656 //=============================================================================
2657 void V3d_View::Init()
2659 myComputedMode = MyViewer->ComputedMode();
2660 if (!myComputedMode || !MyViewer->DefaultComputedMode())
2662 SetComputedMode (Standard_False);
2666 //=============================================================================
2669 //=============================================================================
2670 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2671 const Graphic3d_BufferType& theBufferType)
2673 Standard_Integer aWinWidth, aWinHeight;
2674 MyWindow->Size (aWinWidth, aWinHeight);
2675 Image_AlienPixMap anImage;
2677 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2680 //=============================================================================
2681 //function : ToPixMap
2683 //=============================================================================
2684 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
2685 const V3d_ImageDumpOptions& theParams)
2687 Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
2688 if (aTargetSize.x() != 0
2689 && aTargetSize.y() != 0)
2691 // allocate image buffer for dumping
2692 if (theImage.IsEmpty()
2693 || theImage.SizeX() != Standard_Size(aTargetSize.x())
2694 || theImage.SizeY() != Standard_Size(aTargetSize.y()))
2696 Image_Format aFormat = Image_Format_UNKNOWN;
2697 switch (theParams.BufferType)
2699 case Graphic3d_BT_RGB: aFormat = Image_Format_RGB; break;
2700 case Graphic3d_BT_RGBA: aFormat = Image_Format_RGBA; break;
2701 case Graphic3d_BT_Depth: aFormat = Image_Format_GrayF; break;
2702 case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF; break;
2705 if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
2707 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y()
2708 + " for view dump", Message_Fail);
2709 return Standard_False;
2713 if (theImage.IsEmpty())
2715 Message::DefaultMessenger()->Send (TCollection_AsciiString ("V3d_View::ToPixMap() has been called without image dimensions"), Message_Fail);
2716 return Standard_False;
2718 aTargetSize.x() = (Standard_Integer )theImage.SizeX();
2719 aTargetSize.y() = (Standard_Integer )theImage.SizeY();
2721 Handle(Standard_Transient) aFBOPtr;
2722 Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
2723 Graphic3d_Vec2i aFBOVPSize = aTargetSize;
2725 bool isTiling = false;
2726 if (theParams.TileSize > 0)
2728 if (aFBOVPSize.x() > theParams.TileSize
2729 || aFBOVPSize.y() > theParams.TileSize)
2731 aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
2732 aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
2737 Graphic3d_Vec2i aPrevFBOVPSize;
2738 if (!aPrevFBOPtr.IsNull())
2740 Graphic3d_Vec2i aPrevFBOSizeMax;
2741 myView->FBOGetDimensions (aPrevFBOPtr,
2742 aPrevFBOVPSize.x(), aPrevFBOVPSize.y(),
2743 aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
2744 if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
2745 && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
2747 aFBOPtr = aPrevFBOPtr;
2751 if (aFBOPtr.IsNull())
2753 Standard_Integer aMaxTexSizeX = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeX);
2754 Standard_Integer aMaxTexSizeY = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeY);
2755 if (theParams.TileSize > aMaxTexSizeX
2756 || theParams.TileSize > aMaxTexSizeY)
2758 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
2759 + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")", Message_Fail);
2760 return Standard_False;
2763 if (aFBOVPSize.x() > aMaxTexSizeX
2764 || aFBOVPSize.y() > aMaxTexSizeY)
2766 if (MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_IsWorkaroundFBO))
2768 Message::DefaultMessenger ()->Send (TCollection_AsciiString ("Warning, workaround for Intel driver problem with empty FBO for images with big width is applyed."), Message_Warning);
2770 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Info, tiling image dump is used, image size (")
2771 + aFBOVPSize.x() + "x" + aFBOVPSize.y() + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")", Message_Info);
2772 aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSizeX);
2773 aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSizeY);
2777 // Try to create hardware accelerated buffer
2778 aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
2780 myView->SetFBO (aFBOPtr);
2782 if (aFBOPtr.IsNull())
2784 // try to use on-screen buffer
2785 Graphic3d_Vec2i aWinSize;
2786 MyWindow->Size (aWinSize.x(), aWinSize.y());
2787 if (aFBOVPSize.x() != aWinSize.x()
2788 || aFBOVPSize.y() != aWinSize.y())
2792 aFBOVPSize = aWinSize;
2794 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning, on screen buffer is used for image dump - content might be invalid"), Message_Warning);
2797 // backup camera parameters
2798 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2799 Handle(Graphic3d_Camera) aCamera = Camera();
2800 aStoreMapping->Copy (aCamera);
2801 if (aCamera->IsStereo())
2803 switch (theParams.StereoOptions)
2807 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2810 case V3d_SDO_LEFT_EYE:
2812 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2815 case V3d_SDO_RIGHT_EYE:
2817 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2820 case V3d_SDO_BLENDED:
2822 break; // dump as is
2826 if (theParams.ToAdjustAspect)
2828 aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
2832 // render immediate structures into back buffer rather than front
2833 const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
2835 Standard_Boolean isSuccess = Standard_True;
2838 if (!aFBOPtr.IsNull())
2840 myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
2843 isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
2847 Image_PixMap aTilePixMap;
2848 aTilePixMap.SetTopDown (theImage.IsTopDown());
2850 Graphic3d_Vec2i anOffset (0, 0);
2851 for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
2854 for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
2856 Graphic3d_CameraTile aTileUncropped;
2857 aTileUncropped.Offset = anOffset;
2858 aTileUncropped.TotalSize = aTargetSize;
2859 aTileUncropped.TileSize = aFBOVPSize;
2860 const Graphic3d_CameraTile aTile = aTileUncropped.Cropped();
2861 if (aTile.TileSize.x() < 1
2862 || aTile.TileSize.y() < 1)
2867 const Standard_Integer aLeft = aTile.Offset.x();
2868 Standard_Integer aBottom = aTile.Offset.y();
2869 if (theImage.IsTopDown())
2871 const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
2872 aBottom = aTargetSize.y() - aTop;
2874 aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
2875 + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
2876 aTile.TileSize.x(), aTile.TileSize.y(),
2877 theImage.SizeRowBytes());
2879 if (!aFBOPtr.IsNull())
2881 aCamera->SetTile (aTile);
2882 myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
2886 // no API to resize viewport of on-screen buffer - render uncropped
2887 aCamera->SetTile (aTileUncropped);
2890 isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
2904 myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
2905 aCamera->Copy (aStoreMapping);
2906 if (aFBOPtr != aPrevFBOPtr)
2908 myView->FBORelease (aFBOPtr);
2910 else if (!aPrevFBOPtr.IsNull())
2912 myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
2914 myView->SetFBO (aPrevFBOPtr);
2918 //=============================================================================
2919 //function : ImmediateUpdate
2921 //=============================================================================
2922 void V3d_View::ImmediateUpdate() const
2924 if (myImmediateUpdate)
2930 //=============================================================================
2931 //function : SetImmediateUpdate
2933 //=============================================================================
2934 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2936 Standard_Boolean aPreviousMode = myImmediateUpdate;
2937 myImmediateUpdate = theImmediateUpdate;
2938 return aPreviousMode;
2941 // =======================================================================
2942 // function : SetCamera
2944 // =======================================================================
2945 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2947 myView->SetCamera (theCamera);
2952 // =======================================================================
2953 // function : GetCamera
2955 // =======================================================================
2956 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
2958 return myView->Camera();
2961 // =======================================================================
2962 // function : FitMinMax
2963 // purpose : Internal
2964 // =======================================================================
2965 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
2966 const Bnd_Box& theBox,
2967 const Standard_Real theMargin,
2968 const Standard_Real theResolution,
2969 const Standard_Boolean theToEnlargeIfLine) const
2971 // Check bounding box for validness
2972 if (theBox.IsVoid())
2974 return Standard_False; // bounding box is out of bounds...
2977 // Apply "axial scaling" to the bounding points.
2978 // It is not the best approach to make this scaling as a part of fit all operation,
2979 // but the axial scale is integrated into camera orientation matrix and the other
2980 // option is to perform frustum plane adjustment algorithm in view camera space,
2981 // which will lead to a number of additional world-view space conversions and
2982 // loosing precision as well.
2983 gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (theCamera->AxialScale());
2984 gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (theCamera->AxialScale());
2986 if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
2988 return Standard_False; // nothing to fit all
2991 // Prepare camera frustum planes.
2992 NCollection_Array1<gp_Pln> aFrustumPlane (1, 6);
2993 theCamera->Frustum (aFrustumPlane.ChangeValue (1),
2994 aFrustumPlane.ChangeValue (2),
2995 aFrustumPlane.ChangeValue (3),
2996 aFrustumPlane.ChangeValue (4),
2997 aFrustumPlane.ChangeValue (5),
2998 aFrustumPlane.ChangeValue (6));
3000 // Prepare camera up, side, direction vectors.
3001 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3002 gp_Dir aCamDir = theCamera->Direction();
3003 gp_Dir aCamSide = aCamDir ^ aCamUp;
3005 // Prepare scene bounding box parameters.
3006 gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
3008 NCollection_Array1<gp_Pnt> aBndCorner (1, 8);
3009 aBndCorner.ChangeValue (1) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
3010 aBndCorner.ChangeValue (2) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
3011 aBndCorner.ChangeValue (3) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
3012 aBndCorner.ChangeValue (4) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
3013 aBndCorner.ChangeValue (5) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
3014 aBndCorner.ChangeValue (6) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
3015 aBndCorner.ChangeValue (7) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
3016 aBndCorner.ChangeValue (8) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
3018 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3019 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3020 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3021 // set up perspective-correct camera projection matching the bounding box.
3022 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3023 // The zooming can be done by calculating view plane size matching the bounding box at center of
3024 // the bounding box. The only limitation here is that the scale of camera should define size of
3025 // its view plane passing through the camera center, and the center of camera should be on the
3026 // same line with the center of bounding box.
3028 // The following method is applied:
3029 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3030 // 2) Determine new location of frustum planes, "matching" the bounding box.
3031 // 3) Determine new camera projection vector using the normalized asymmetry.
3032 // 4) Determine new zooming in view space.
3034 // 1. Determine normalized projection asymmetry (if any).
3035 Standard_Real anAssymX = Tan (( aCamSide).Angle (aFrustumPlane (1).Axis().Direction()))
3036 - Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction()));
3037 Standard_Real anAssymY = Tan (( aCamUp) .Angle (aFrustumPlane (3).Axis().Direction()))
3038 - Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction()));
3040 // 2. Determine how far should be the frustum planes placed from center
3041 // of bounding box, in order to match the bounding box closely.
3042 NCollection_Array1<Standard_Real> aFitDistance (1, 6);
3043 aFitDistance.ChangeValue (1) = 0.0;
3044 aFitDistance.ChangeValue (2) = 0.0;
3045 aFitDistance.ChangeValue (3) = 0.0;
3046 aFitDistance.ChangeValue (4) = 0.0;
3047 aFitDistance.ChangeValue (5) = 0.0;
3048 aFitDistance.ChangeValue (6) = 0.0;
3050 for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
3052 // Measure distances from center of bounding box to its corners towards the frustum plane.
3053 const gp_Dir& aPlaneN = aFrustumPlane.ChangeValue (anI).Axis().Direction();
3055 Standard_Real& aFitDist = aFitDistance.ChangeValue (anI);
3057 for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
3059 aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner (aJ)).Dot (aPlaneN));
3062 // The center of camera is placed on the same line with center of bounding box.
3063 // The view plane section crosses the bounding box at its center.
3064 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3065 // into view section size between the point and the frustum plane.
3067 // /|\ right half of frame //
3069 // point o<-- distance * coeff -->//---- (view plane section)
3078 aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan ( aCamSide .Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
3079 aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
3080 aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan ( aCamUp .Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
3081 aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
3082 aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan ( aCamDir .Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
3083 aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan ((-aCamDir) .Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
3085 Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
3086 Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
3087 Standard_Real aViewSizeZv = aFitDistance (5) + aFitDistance (6);
3089 // 3. Place center of camera on the same line with center of bounding
3090 // box applying corresponding projection asymmetry (if any).
3091 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3092 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3093 Standard_Real anOffsetXv = (aFitDistance (2) - aFitDistance (1)) * 0.5 + anAssymXv;
3094 Standard_Real anOffsetYv = (aFitDistance (4) - aFitDistance (3)) * 0.5 + anAssymYv;
3095 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3096 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3097 gp_Pnt aCamNewCenter = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3099 gp_Trsf aCenterTrsf;
3100 aCenterTrsf.SetTranslation (theCamera->Center(), aCamNewCenter);
3101 theCamera->Transform (aCenterTrsf);
3102 theCamera->SetDistance (aFitDistance (6) + aFitDistance (5));
3104 // Bounding box collapses to a point or thin line going in depth of the screen
3105 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3107 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3109 return Standard_True; // This is just one point or line and zooming has no effect.
3112 // Looking along line and "theToEnlargeIfLine" is requested.
3113 // Fit view to see whole scene on rotation.
3114 aViewSizeXv = aViewSizeZv;
3115 aViewSizeYv = aViewSizeZv;
3118 Scale (theCamera, aViewSizeXv, aViewSizeYv);
3120 const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
3122 Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
3124 return Standard_True;
3127 // =======================================================================
3129 // purpose : Internal
3130 // =======================================================================
3131 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3132 const Standard_Real theSizeXv,
3133 const Standard_Real theSizeYv) const
3135 Standard_Real anAspect = theCamera->Aspect();
3138 theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
3142 theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
3146 // =======================================================================
3147 // function : Translate
3148 // purpose : Internal
3149 // =======================================================================
3150 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3151 const Standard_Real theDXv,
3152 const Standard_Real theDYv) const
3154 const gp_Pnt& aCenter = theCamera->Center();
3155 const gp_Dir& aDir = theCamera->Direction();
3156 const gp_Dir& anUp = theCamera->Up();
3157 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3159 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3160 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3161 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3163 aPanTrsf.SetTranslation (aCameraPan);
3165 theCamera->Transform (aPanTrsf);
3168 // =======================================================================
3169 // function : DiagnosticInformation
3171 // =======================================================================
3172 void V3d_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
3173 Graphic3d_DiagnosticInfo theFlags) const
3175 myView->DiagnosticInformation (theDict, theFlags);
3178 //=======================================================================
3179 //function : StatisticInformation
3181 //=======================================================================
3182 void V3d_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
3184 myView->StatisticInformation (theDict);
3187 // =======================================================================
3188 // function : StatisticInformation
3190 // =======================================================================
3191 TCollection_AsciiString V3d_View::StatisticInformation() const
3193 return myView->StatisticInformation();
3196 //=============================================================================
3197 //function : RenderingParams
3199 //=============================================================================
3200 const Graphic3d_RenderingParams& V3d_View::RenderingParams() const
3202 return myView->RenderingParams();
3205 //=============================================================================
3206 //function : ChangeRenderingParams
3208 //=============================================================================
3209 Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams()
3211 return myView->ChangeRenderingParams();