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 <Graphic3d_Vector.hxx>
31 #include <Image_AlienPixMap.hxx>
32 #include <Message.hxx>
33 #include <Message_Messenger.hxx>
34 #include <NCollection_Array1.hxx>
35 #include <Precision.hxx>
36 #include <Quantity_Color.hxx>
37 #include <Standard_Assert.hxx>
38 #include <Standard_DivideByZero.hxx>
39 #include <Standard_ErrorHandler.hxx>
40 #include <Standard_MultiplyDefined.hxx>
41 #include <Standard_ShortReal.hxx>
42 #include <Standard_Type.hxx>
43 #include <Standard_TypeMismatch.hxx>
44 #include <TColgp_Array1OfPnt.hxx>
45 #include <TColStd_Array2OfReal.hxx>
46 #include <TColStd_HSequenceOfInteger.hxx>
48 #include <V3d_BadValue.hxx>
49 #include <V3d_Light.hxx>
50 #include <V3d_StereoDumpOptions.hxx>
51 #include <V3d_UnMapped.hxx>
52 #include <V3d_Viewer.hxx>
54 IMPLEMENT_STANDARD_RTTIEXT(V3d_View,MMgt_TShared)
56 #define DEUXPI (2. * M_PI)
60 static const Standard_Integer THE_NB_BOUND_POINTS = 8;
63 //=============================================================================
64 //function : Constructor
66 //=============================================================================
67 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType)
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 : MyViewer (theViewer.operator->()),
119 SwitchSetFront(Standard_False),
120 myZRotation (Standard_False),
123 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
125 myView->CopySettings (theView->View());
127 myDefaultCamera = new Graphic3d_Camera();
129 myImmediateUpdate = Standard_False;
130 SetAutoZFitMode (theView->AutoZFitMode(), theView->AutoZFitScaleFactor());
131 SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
132 SetViewMappingDefault();
133 SetViewOrientationDefault();
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);
197 //=============================================================================
200 //=============================================================================
201 void V3d_View::Remove() const
203 MyViewer->DelView (this);
205 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
209 //=============================================================================
212 //=============================================================================
213 void V3d_View::Update() const
215 if (!myView->IsDefined()
216 || !myView->IsActive())
226 //=============================================================================
229 //=============================================================================
230 void V3d_View::Redraw() const
232 if (!myView->IsDefined()
233 || !myView->IsActive())
238 Handle(Graphic3d_GraphicDriver) aGraphicDriver = MyViewer->Driver();
239 Handle(Graphic3d_StructureManager) aStructureMgr = MyViewer->StructureManager();
240 for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
242 if (aGraphicDriver->IsDeviceLost())
244 aStructureMgr->RecomputeStructures();
245 aGraphicDriver->ResetDeviceLostFlag();
252 if (!aGraphicDriver->IsDeviceLost())
259 //=============================================================================
260 //function : RedrawImmediate
262 //=============================================================================
263 void V3d_View::RedrawImmediate() const
265 if (!myView->IsDefined()
266 || !myView->IsActive())
271 myView->RedrawImmediate();
274 //=============================================================================
275 //function : Invalidate
277 //=============================================================================
278 void V3d_View::Invalidate() const
280 if (!myView->IsDefined())
285 myView->Invalidate();
288 //=============================================================================
289 //function : IsInvalidated
291 //=============================================================================
292 Standard_Boolean V3d_View::IsInvalidated() const
294 return !myView->IsDefined()
295 || myView->IsInvalidated();
298 // ========================================================================
299 // function : SetAutoZFitMode
301 // ========================================================================
302 void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn,
303 const Standard_Real theScaleFactor)
305 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
306 myAutoZFitScaleFactor = theScaleFactor;
307 myAutoZFitIsOn = theIsOn;
310 // ========================================================================
311 // function : AutoZFitMode
313 // ========================================================================
314 Standard_Boolean V3d_View::AutoZFitMode() const
316 return myAutoZFitIsOn;
319 // ========================================================================
320 // function : AutoZFitScaleFactor
322 // ========================================================================
323 Standard_Real V3d_View::AutoZFitScaleFactor() const
325 return myAutoZFitScaleFactor;
328 //=============================================================================
329 //function : AutoZFit
331 //=============================================================================
332 void V3d_View::AutoZFit() const
339 ZFitAll (myAutoZFitScaleFactor);
342 //=============================================================================
345 //=============================================================================
346 void V3d_View::ZFitAll (const Standard_Real theScaleFactor) const
348 Bnd_Box aMinMaxBox = myView->MinMaxValues (Standard_False); // applicative min max boundaries
349 Bnd_Box aGraphicBox = myView->MinMaxValues (Standard_True); // real graphical boundaries (not accounting infinite flag).
351 myView->Camera()->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
354 //=============================================================================
357 //=============================================================================
358 Standard_Boolean V3d_View::IsEmpty() const
360 Standard_Boolean TheStatus = Standard_True ;
361 if( myView->IsDefined() ) {
362 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
363 if( Nstruct > 0 ) TheStatus = Standard_False ;
368 //=============================================================================
369 //function : UpdateLights
371 //=============================================================================
372 void V3d_View::UpdateLights() const
374 Graphic3d_ListOfCLight aLights;
375 for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
377 aLights.Append (anActiveLightIter.Value()->Light());
379 myView->SetLights (aLights);
383 //=============================================================================
384 //function : DoMapping
386 //=============================================================================
387 void V3d_View::DoMapping()
389 if (!myView->IsDefined())
394 myView->Window()->DoMapping();
397 //=============================================================================
398 //function : MustBeResized
400 //=============================================================================
401 void V3d_View::MustBeResized()
403 if (!myView->IsDefined())
415 //=============================================================================
416 //function : SetBackgroundColor
418 //=============================================================================
419 void V3d_View::SetBackgroundColor (const Quantity_TypeOfColor theType,
420 const Standard_Real theV1,
421 const Standard_Real theV2,
422 const Standard_Real theV3)
424 Standard_Real aV1 = Max (Min (theV1, 1.0), 0.0);
425 Standard_Real aV2 = Max (Min (theV2, 1.0), 0.0);
426 Standard_Real aV3 = Max (Min (theV3, 1.0), 0.0);
428 SetBackgroundColor (Quantity_Color (aV1, aV2, aV3, theType));
431 //=============================================================================
432 //function : SetBackgroundColor
434 //=============================================================================
435 void V3d_View::SetBackgroundColor (const Quantity_Color& theColor)
437 myView->SetBackground (Aspect_Background (theColor));
439 if (myImmediateUpdate)
445 //=============================================================================
446 //function : SetBackgroundColor
448 //=============================================================================
449 void V3d_View::SetBackgroundColor (const Quantity_NameOfColor theName)
451 SetBackgroundColor (Quantity_Color (theName));
454 //=============================================================================
455 //function : SetBgGradientColors
457 //=============================================================================
458 void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
459 const Quantity_Color& theColor2,
460 const Aspect_GradientFillMethod theFillStyle,
461 const Standard_Boolean theToUpdate)
463 Aspect_GradientBackground aGradientBg (theColor1, theColor2, theFillStyle);
465 myView->SetGradientBackground (aGradientBg);
467 if (myImmediateUpdate || theToUpdate)
473 //=============================================================================
474 //function : SetBgGradientColors
476 //=============================================================================
477 void V3d_View::SetBgGradientColors (const Quantity_NameOfColor theColor1,
478 const Quantity_NameOfColor theColor2,
479 const Aspect_GradientFillMethod theFillStyle,
480 const Standard_Boolean theToUpdate)
482 Quantity_Color aColor1 (theColor1);
483 Quantity_Color aColor2 (theColor2);
485 SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
488 //=============================================================================
489 //function : SetBgGradientStyle
491 //=============================================================================
492 void V3d_View::SetBgGradientStyle (const Aspect_GradientFillMethod theFillStyle, const Standard_Boolean theToUpdate)
494 Quantity_Color aColor1;
495 Quantity_Color aColor2;
496 GradientBackground().Colors (aColor1, aColor2);
498 SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
501 //=============================================================================
502 //function : SetBackgroundImage
504 //=============================================================================
505 void V3d_View::SetBackgroundImage (const Standard_CString theFileName,
506 const Aspect_FillMethod theFillStyle,
507 const Standard_Boolean theToUpdate)
509 myView->SetBackgroundImage (theFileName);
510 myView->SetBackgroundImageStyle (theFillStyle);
512 if (myImmediateUpdate || theToUpdate)
518 //=============================================================================
519 //function : SetBgImageStyle
521 //=============================================================================
522 void V3d_View::SetBgImageStyle (const Aspect_FillMethod theFillStyle, const Standard_Boolean theToUpdate)
524 myView->SetBackgroundImageStyle (theFillStyle);
526 if (myImmediateUpdate || theToUpdate)
532 //=============================================================================
535 //=============================================================================
536 void V3d_View::SetAxis(const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Real Vx, const Standard_Real Vy, const Standard_Real Vz)
538 Standard_Real D,Nx = Vx,Ny = Vy,Nz = Vz ;
540 D = Sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) ;
541 V3d_BadValue_Raise_if ( D <= 0. , "V3d_View::SetAxis, bad axis");
542 Nx /= D ; Ny /= D ; Nz /= D ;
543 MyDefaultViewPoint.SetCoord(X,Y,Z) ;
544 MyDefaultViewAxis.SetCoord(Nx,Ny,Nz) ;
547 //=============================================================================
548 //function : SetShadingModel
550 //=============================================================================
551 void V3d_View::SetShadingModel (const V3d_TypeOfShadingModel theShadingModel)
553 myView->SetShadingModel (static_cast<Graphic3d_TypeOfShadingModel> (theShadingModel));
556 //=============================================================================
557 //function : SetTextureEnv
559 //=============================================================================
560 void V3d_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTexture)
562 myView->SetTextureEnv (theTexture);
564 if (myImmediateUpdate)
570 //=============================================================================
571 //function : SetVisualization
573 //=============================================================================
574 void V3d_View::SetVisualization (const V3d_TypeOfVisualization theType)
576 myView->SetVisualizationType (static_cast <Graphic3d_TypeOfVisualization> (theType));
578 if (myImmediateUpdate)
584 //=============================================================================
585 //function : SetFront
587 //=============================================================================
588 void V3d_View::SetFront()
590 gp_Ax3 a = MyViewer->PrivilegedPlane();
591 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
593 a.Direction().Coord(vx,vy,vz);
594 a.YDirection().Coord(xu,yu,zu);
595 a.Location().Coord(xo,yo,zo);
597 Handle(Graphic3d_Camera) aCamera = Camera();
599 aCamera->SetCenter (gp_Pnt (xo, yo, zo));
603 aCamera->SetDirection (gp_Dir (vx, vy, vz));
607 aCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
610 aCamera->SetUp (gp_Dir (xu, yu, zu));
614 SwitchSetFront = !SwitchSetFront;
619 //=============================================================================
622 //=============================================================================
623 void V3d_View::Rotate (const Standard_Real ax,
624 const Standard_Real ay,
625 const Standard_Real az,
626 const Standard_Boolean Start)
628 Standard_Real Ax = ax;
629 Standard_Real Ay = ay;
630 Standard_Real Az = az;
632 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
633 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
634 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
635 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
636 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
637 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
639 Handle(Graphic3d_Camera) aCamera = Camera();
643 myCamStartOpUp = aCamera->Up();
644 myCamStartOpEye = aCamera->Eye();
645 myCamStartOpCenter = aCamera->Center();
648 aCamera->SetUp (myCamStartOpUp);
649 aCamera->SetEye (myCamStartOpEye);
650 aCamera->SetCenter (myCamStartOpCenter);
652 // rotate camera around 3 initial axes
653 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
654 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
655 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
656 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
658 gp_Trsf aRot[3], aTrsf;
659 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
660 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
661 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
662 aTrsf.Multiply (aRot[0]);
663 aTrsf.Multiply (aRot[1]);
664 aTrsf.Multiply (aRot[2]);
666 aCamera->Transform (aTrsf);
673 //=============================================================================
676 //=============================================================================
677 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
678 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
681 Standard_Real Ax = ax ;
682 Standard_Real Ay = ay ;
683 Standard_Real Az = az ;
685 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
686 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
687 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
688 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
689 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
690 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
692 Handle(Graphic3d_Camera) aCamera = Camera();
696 myGravityReferencePoint.SetCoord (X, Y, Z);
697 myCamStartOpUp = aCamera->Up();
698 myCamStartOpEye = aCamera->Eye();
699 myCamStartOpCenter = aCamera->Center();
702 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
704 aCamera->SetUp (myCamStartOpUp);
705 aCamera->SetEye (myCamStartOpEye);
706 aCamera->SetCenter (myCamStartOpCenter);
708 // rotate camera around 3 initial axes
709 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
711 gp_Dir aZAxis (aCamera->Direction().Reversed());
712 gp_Dir aYAxis (aCamera->Up());
713 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
715 gp_Trsf aRot[3], aTrsf;
716 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
717 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
718 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
719 aTrsf.Multiply (aRot[0]);
720 aTrsf.Multiply (aRot[1]);
721 aTrsf.Multiply (aRot[2]);
723 aCamera->Transform (aTrsf);
730 //=============================================================================
733 //=============================================================================
734 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
738 Rotate(angle,0.,0.,Start);
741 Rotate(0.,angle,0.,Start);
744 Rotate(0.,0.,angle,Start);
749 //=============================================================================
752 //=============================================================================
753 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
754 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
756 Standard_Real Angle = angle ;
758 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
759 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
761 Handle(Graphic3d_Camera) aCamera = Camera();
765 myGravityReferencePoint.SetCoord (X, Y, Z);
766 myCamStartOpUp = aCamera->Up();
767 myCamStartOpEye = aCamera->Eye();
768 myCamStartOpCenter = aCamera->Center();
772 myViewAxis.SetCoord(1.,0.,0.) ;
775 myViewAxis.SetCoord(0.,1.,0.) ;
778 myViewAxis.SetCoord(0.,0.,1.) ;
782 myCamStartOpUp = aCamera->Up();
783 myCamStartOpEye = aCamera->Eye();
784 myCamStartOpCenter = aCamera->Center();
787 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
789 aCamera->SetUp (myCamStartOpUp);
790 aCamera->SetEye (myCamStartOpEye);
791 aCamera->SetCenter (myCamStartOpCenter);
793 // rotate camera around passed axis
795 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
796 gp_Dir aRAxis ((Axe == V3d_X) ? 1.0 : 0.0,
797 (Axe == V3d_Y) ? 1.0 : 0.0,
798 (Axe == V3d_Z) ? 1.0 : 0.0);
800 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
802 aCamera->Transform (aRotation);
809 //=============================================================================
812 //=============================================================================
813 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
815 Standard_Real Angle = angle;
817 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
818 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
820 Handle(Graphic3d_Camera) aCamera = Camera();
823 myCamStartOpUp = aCamera->Up();
824 myCamStartOpEye = aCamera->Eye();
825 myCamStartOpCenter = aCamera->Center();
828 const Graphic3d_Vertex& aPnt = MyDefaultViewPoint;
829 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
831 aCamera->SetUp (myCamStartOpUp);
832 aCamera->SetEye (myCamStartOpEye);
833 aCamera->SetCenter (myCamStartOpCenter);
836 gp_Pnt aRCenter (aPnt.X(), aPnt.Y(), aPnt.Z());
837 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
838 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
840 aCamera->Transform (aRotation);
847 //=============================================================================
850 //=============================================================================
851 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
853 Standard_Real Ax = ax;
854 Standard_Real Ay = ay;
855 Standard_Real Az = az;
857 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
858 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
859 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
860 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
861 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
862 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
864 Handle(Graphic3d_Camera) aCamera = Camera();
867 myCamStartOpUp = aCamera->Up();
868 myCamStartOpEye = aCamera->Eye();
869 myCamStartOpCenter = aCamera->Center();
872 aCamera->SetUp (myCamStartOpUp);
873 aCamera->SetEye (myCamStartOpEye);
874 aCamera->SetCenter (myCamStartOpCenter);
876 // rotate camera around 3 initial axes
877 gp_Pnt aRCenter = aCamera->Eye();
878 gp_Dir aZAxis (aCamera->Direction().Reversed());
879 gp_Dir aYAxis (aCamera->Up());
880 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
882 gp_Trsf aRot[3], aTrsf;
883 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
884 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
885 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
886 aTrsf.Multiply (aRot[0]);
887 aTrsf.Multiply (aRot[1]);
888 aTrsf.Multiply (aRot[2]);
890 aCamera->Transform (aTrsf);
897 //=============================================================================
900 //=============================================================================
901 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
905 Turn(angle,0.,0.,Start);
908 Turn(0.,angle,0.,Start);
911 Turn(0.,0.,angle,Start);
916 //=============================================================================
919 //=============================================================================
920 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
922 Standard_Real Angle = angle ;
924 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
925 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
927 Handle(Graphic3d_Camera) aCamera = Camera();
930 myCamStartOpUp = aCamera->Up();
931 myCamStartOpEye = aCamera->Eye();
932 myCamStartOpCenter = aCamera->Center();
935 aCamera->SetUp (myCamStartOpUp);
936 aCamera->SetEye (myCamStartOpEye);
937 aCamera->SetCenter (myCamStartOpCenter);
939 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
942 gp_Pnt aRCenter = aCamera->Eye();
943 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
944 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
946 aCamera->Transform (aRotation);
953 //=============================================================================
954 //function : SetTwist
956 //=============================================================================
957 void V3d_View::SetTwist(const Standard_Real angle)
959 Standard_Real Angle = angle ;
960 Standard_Boolean TheStatus;
962 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
963 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
965 Handle(Graphic3d_Camera) aCamera = Camera();
967 gp_Dir aReferencePlane (aCamera->Direction().Reversed());
970 anUp = gp_Dir (0.0, 0.0, 1.0);
972 TheStatus = ScreenAxis(aReferencePlane, anUp,
973 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
975 anUp = gp_Dir (0.0, 1.0, 0.0);
976 TheStatus = ScreenAxis(aReferencePlane, anUp,
977 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
980 anUp = gp_Dir (1.0, 0.0, 0.0);
981 TheStatus = ScreenAxis(aReferencePlane, anUp,
982 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
985 V3d_BadValue_Raise_if( !TheStatus,"V3d_ViewSetTwist, alignment of Eye,At,Up,");
987 gp_Pnt aRCenter = aCamera->Center();
988 gp_Dir aZAxis (aCamera->Direction().Reversed());
991 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
993 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
994 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
996 aCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
997 aCamera->Transform (aTrsf);
1004 //=============================================================================
1007 //=============================================================================
1008 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1010 Standard_Real aTwistBefore = Twist();
1012 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1014 Handle(Graphic3d_Camera) aCamera = Camera();
1016 aCamera->SetEye (gp_Pnt (X, Y, Z));
1018 SetTwist (aTwistBefore);
1022 SetImmediateUpdate (wasUpdateEnabled);
1027 //=============================================================================
1028 //function : SetDepth
1030 //=============================================================================
1031 void V3d_View::SetDepth(const Standard_Real Depth)
1033 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1035 Handle(Graphic3d_Camera) aCamera = Camera();
1039 // Move eye using center (target) as anchor.
1040 aCamera->SetDistance (Depth);
1044 // Move the view ref point instead of the eye.
1045 gp_Vec aDir (aCamera->Direction());
1046 gp_Pnt aCameraEye = aCamera->Eye();
1047 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1049 aCamera->SetCenter (aCameraCenter);
1057 //=============================================================================
1058 //function : SetProj
1060 //=============================================================================
1061 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1063 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1064 "V3d_View::SetProj, null projection vector");
1066 Standard_Real aTwistBefore = Twist();
1068 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1070 Camera()->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1072 SetTwist(aTwistBefore);
1076 SetImmediateUpdate (wasUpdateEnabled);
1081 //=============================================================================
1082 //function : SetProj
1084 //=============================================================================
1085 void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1087 Standard_Real Xpn=0;
1088 Standard_Real Ypn=0;
1089 Standard_Real Zpn=0;
1091 switch (Orientation) {
1102 const Graphic3d_Vector& aBck = V3d::GetProjAxis (Orientation);
1104 // retain camera panning from origin when switching projection
1105 Handle(Graphic3d_Camera) aCamera = Camera();
1107 gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
1108 Standard_Real aPanX = anOriginVCS.X();
1109 Standard_Real aPanY = anOriginVCS.Y();
1111 aCamera->SetCenter (gp_Pnt (0, 0, 0));
1112 aCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1113 aCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
1114 aCamera->OrthogonalizeUp();
1116 Panning (aPanX, aPanY);
1123 //=============================================================================
1126 //=============================================================================
1127 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1129 Standard_Real aTwistBefore = Twist();
1131 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1133 Camera()->SetCenter (gp_Pnt (X, Y, Z));
1135 SetTwist (aTwistBefore);
1139 SetImmediateUpdate (wasUpdateEnabled);
1144 //=============================================================================
1147 //=============================================================================
1148 void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standard_Real Vz)
1150 Standard_Boolean TheStatus ;
1151 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0. ,
1152 "V3d_View::SetUp, nullUp vector");
1154 Handle(Graphic3d_Camera) aCamera = Camera();
1156 gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1157 gp_Dir anUp (Vx, Vy, Vz);
1159 TheStatus = ScreenAxis(aReferencePlane,anUp,
1160 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1162 anUp = gp_Dir (0.0, 0.0, 1.0);
1163 TheStatus = ScreenAxis(aReferencePlane,anUp,
1164 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1167 anUp = gp_Dir (0.0, 1.0, 0.0);
1168 TheStatus = ScreenAxis(aReferencePlane,anUp,
1169 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1172 anUp = gp_Dir (1.0, 0.0, 0.0);
1173 TheStatus = ScreenAxis(aReferencePlane,anUp,
1174 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1176 V3d_BadValue_Raise_if( !TheStatus,"V3d_View::Setup, alignment of Eye,At,Up");
1178 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1179 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1181 aCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1188 //=============================================================================
1191 //=============================================================================
1192 void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
1194 Standard_Boolean TheStatus ;
1196 Handle(Graphic3d_Camera) aCamera = Camera();
1198 gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1201 const Graphic3d_Vector& aViewReferenceUp = V3d::GetProjAxis(Orientation) ;
1202 anUp = gp_Dir (aViewReferenceUp.X(), aViewReferenceUp.Y(), aViewReferenceUp.Z());
1204 TheStatus = ScreenAxis(aReferencePlane,anUp,
1205 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1207 anUp = gp_Dir (0.,0.,1.);
1208 TheStatus = ScreenAxis(aReferencePlane,anUp,
1209 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1212 anUp = gp_Dir (0.,1.,0.);
1213 TheStatus = ScreenAxis(aReferencePlane,anUp,
1214 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1217 anUp = gp_Dir (1.,0.,0.);
1218 TheStatus = ScreenAxis(aReferencePlane,anUp,
1219 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1221 V3d_BadValue_Raise_if( !TheStatus, "V3d_View::SetUp, alignment of Eye,At,Up");
1223 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1224 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1226 aCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1233 //=============================================================================
1234 //function : SetViewOrientationDefault
1236 //=============================================================================
1237 void V3d_View::SetViewOrientationDefault()
1239 myDefaultCamera->CopyOrientationData (Camera());
1242 //=======================================================================
1243 //function : SetViewMappingDefault
1245 //=======================================================================
1246 void V3d_View::SetViewMappingDefault()
1248 myDefaultCamera->CopyMappingData (Camera());
1251 //=============================================================================
1252 //function : ResetViewOrientation
1254 //=============================================================================
1255 void V3d_View::ResetViewOrientation()
1257 Camera()->CopyOrientationData (myDefaultCamera);
1264 //=======================================================================
1265 //function : ResetViewMapping
1267 //=======================================================================
1268 void V3d_View::ResetViewMapping()
1270 Camera()->CopyMappingData (myDefaultCamera);
1277 //=============================================================================
1280 //=============================================================================
1281 void V3d_View::Reset (const Standard_Boolean theToUpdate)
1283 Camera()->Copy (myDefaultCamera);
1287 SwitchSetFront = Standard_False;
1289 if (myImmediateUpdate || theToUpdate)
1295 //=======================================================================
1296 //function : SetCenter
1298 //=======================================================================
1299 void V3d_View::SetCenter (const Standard_Integer theXp,
1300 const Standard_Integer theYp)
1302 Standard_Real aXv, aYv;
1303 Convert (theXp, theYp, aXv, aYv);
1304 Translate (Camera(), aXv, aYv);
1309 //=============================================================================
1310 //function : SetSize
1312 //=============================================================================
1313 void V3d_View::SetSize (const Standard_Real theSize)
1315 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1317 Handle(Graphic3d_Camera) aCamera = Camera();
1319 aCamera->SetScale (aCamera->Aspect() >= 1.0 ? theSize / aCamera->Aspect() : theSize);
1326 //=============================================================================
1327 //function : SetZSize
1329 //=============================================================================
1330 void V3d_View::SetZSize (const Standard_Real theSize)
1332 Handle(Graphic3d_Camera) aCamera = Camera();
1334 Standard_Real Zmax = theSize / 2.;
1336 Standard_Real aDistance = aCamera->Distance();
1343 // ShortReal precision factor used to add meaningful tolerance to
1344 // ZNear, ZFar values in order to avoid equality after type conversion
1345 // to ShortReal matrices type.
1346 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1348 Standard_Real aZFar = Zmax + aDistance * 2.0;
1349 Standard_Real aZNear = -Zmax + aDistance;
1350 aZNear -= Abs (aZNear) * aPrecision;
1351 aZFar += Abs (aZFar) * aPrecision;
1353 if (!aCamera->IsOrthographic())
1355 if (aZFar < aPrecision)
1357 // Invalid case when both values are negative
1358 aZNear = aPrecision;
1359 aZFar = aPrecision * 2.0;
1361 else if (aZNear < Abs (aZFar) * aPrecision)
1363 // Z is less than 0.0, try to fix it using any appropriate z-scale
1364 aZNear = Abs (aZFar) * aPrecision;
1368 // If range is too small
1369 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1371 aZFar = aZNear + Abs (aZFar) * aPrecision;
1374 aCamera->SetZRange (aZNear, aZFar);
1376 if (myImmediateUpdate)
1382 //=============================================================================
1383 //function : SetZoom
1385 //=============================================================================
1386 void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1388 V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
1390 Handle(Graphic3d_Camera) aCamera = Camera();
1394 myCamStartOpEye = aCamera->Eye();
1395 myCamStartOpCenter = aCamera->Center();
1398 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
1399 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
1401 // ensure that zoom will not be too small or too big
1402 Standard_Real coef = Coef;
1403 if (aViewWidth < coef * Precision::Confusion())
1405 coef = aViewWidth / Precision::Confusion();
1407 else if (aViewWidth > coef * 1e12)
1409 coef = aViewWidth / 1e12;
1411 if (aViewHeight < coef * Precision::Confusion())
1413 coef = aViewHeight / Precision::Confusion();
1415 else if (aViewHeight > coef * 1e12)
1417 coef = aViewHeight / 1e12;
1420 aCamera->SetEye (myCamStartOpEye);
1421 aCamera->SetCenter (myCamStartOpCenter);
1422 aCamera->SetScale (aCamera->Scale() / Coef);
1429 //=============================================================================
1430 //function : SetScale
1432 //=============================================================================
1433 void V3d_View::SetScale( const Standard_Real Coef )
1435 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1437 Handle(Graphic3d_Camera) aCamera = Camera();
1439 Standard_Real aDefaultScale = myDefaultCamera->Scale();
1440 aCamera->SetAspect (myDefaultCamera->Aspect());
1441 aCamera->SetScale (aDefaultScale / Coef);
1448 //=============================================================================
1449 //function : SetAxialScale
1451 //=============================================================================
1452 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1454 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1456 Camera()->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1461 //=============================================================================
1462 //function : SetRatio
1464 //=============================================================================
1465 void V3d_View::SetRatio()
1467 if (MyWindow.IsNull())
1472 Standard_Integer aWidth = 0;
1473 Standard_Integer aHeight = 0;
1474 MyWindow->Size (aWidth, aHeight);
1475 if (aWidth > 0 && aHeight > 0)
1477 Standard_Real aRatio = static_cast<Standard_Real> (aWidth) /
1478 static_cast<Standard_Real> (aHeight);
1480 Camera() ->SetAspect (aRatio);
1481 myDefaultCamera->SetAspect (aRatio);
1485 //=============================================================================
1488 //=============================================================================
1489 void V3d_View::FitAll (const Quantity_Coefficient theMargin, const Standard_Boolean theToUpdate)
1491 FitAll (myView->MinMaxValues(), theMargin, theToUpdate);
1494 //=============================================================================
1497 //=============================================================================
1498 void V3d_View::FitAll (const Bnd_Box& theBox, const Quantity_Coefficient theMargin, const Standard_Boolean theToUpdate)
1500 Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1502 if (myView->NumberOfDisplayedStructures() == 0)
1507 if (!FitMinMax (Camera(), theBox, theMargin, 10.0 * Precision::Confusion()))
1514 if (myImmediateUpdate || theToUpdate)
1520 //=============================================================================
1521 //function : DepthFitAll
1523 //=============================================================================
1524 void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1525 const Quantity_Coefficient Margin)
1527 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1528 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1529 Standard_Real Dx,Dy,Dz,Size;
1531 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1533 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1538 Bnd_Box aBox = myView->MinMaxValues();
1544 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1545 Project (Xmin,Ymin,Zmin,U,V,W) ;
1546 Project (Xmax,Ymax,Zmax,U1,V1,W1) ;
1547 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1548 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1549 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1550 Project (Xmin,Ymin,Zmax,U,V,W) ;
1551 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1552 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1553 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1554 Project (Xmax,Ymin,Zmax,U,V,W) ;
1555 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1556 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1557 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1558 Project (Xmax,Ymin,Zmin,U,V,W) ;
1559 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1560 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1561 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1562 Project (Xmax,Ymax,Zmin,U,V,W) ;
1563 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1564 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1565 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1566 Project (Xmin,Ymax,Zmax,U,V,W) ;
1567 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1568 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1569 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1570 Project (Xmin,Ymax,Zmin,U,V,W) ;
1571 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1572 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1573 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1576 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1577 Dz = 2.*Wmax + Margin * Wmax;
1579 // Compute depth value
1580 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1581 Dx += Margin * Dx; Dy += Margin * Dy;
1582 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1585 SetDepth( Aspect * Size / 2.);
1591 //=============================================================================
1592 //function : WindowFitAll
1594 //=============================================================================
1595 void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1596 const Standard_Integer Ymin,
1597 const Standard_Integer Xmax,
1598 const Standard_Integer Ymax)
1600 WindowFit(Xmin,Ymin,Xmax,Ymax);
1603 //=======================================================================
1604 //function : WindowFit
1606 //=======================================================================
1607 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1608 const Standard_Integer theMinYp,
1609 const Standard_Integer theMaxXp,
1610 const Standard_Integer theMaxYp)
1612 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1614 Handle(Graphic3d_Camera) aCamera = Camera();
1616 if (!aCamera->IsOrthographic())
1618 // normalize view coordinates
1619 Standard_Integer aWinWidth, aWinHeight;
1620 MyWindow->Size (aWinWidth, aWinHeight);
1622 // z coordinate of camera center
1623 Standard_Real aDepth = aCamera->Project (aCamera->Center()).Z();
1625 // camera projection coordinate are in NDC which are normalized [-1, 1]
1626 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1627 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1628 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1629 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1631 // compute camera panning
1632 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1633 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1634 gp_Pnt aPanTo = aCamera->ConvertProj2View (aFitCenter);
1635 gp_Pnt aPanFrom = aCamera->ConvertProj2View (aScreenCenter);
1636 gp_Vec aPanVec (aPanFrom, aPanTo);
1638 // compute section size
1639 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1640 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1641 gp_Pnt aViewBotLeft = aCamera->ConvertProj2View (aFitBotLeft);
1642 gp_Pnt aViewTopRight = aCamera->ConvertProj2View (aFitTopRight);
1644 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1645 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1647 Translate (aCamera, aPanVec.X(), -aPanVec.Y());
1648 Scale (aCamera, aUSize, aVSize);
1653 Standard_Real aX1, aY1, aX2, aY2;
1654 Convert (theMinXp, theMinYp, aX1, aY1);
1655 Convert (theMaxXp, theMaxYp, aX2, aY2);
1656 FitAll (aX1, aY1, aX2, aY2);
1659 SetImmediateUpdate (wasUpdateEnabled);
1664 //=======================================================================
1665 //function : ConvertToGrid
1667 //=======================================================================
1668 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1669 const Standard_Integer Yp,
1672 Standard_Real& Zg) const
1674 Graphic3d_Vertex aVrp;
1675 Standard_Real anX, anY, aZ;
1676 Convert (Xp, Yp, anX, anY, aZ);
1677 aVrp.SetCoord (anX, anY, aZ);
1679 if( MyViewer->Grid()->IsActive() ) {
1680 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1681 aNewVrp.Coord (Xg,Yg,Zg) ;
1683 aVrp.Coord (Xg,Yg,Zg) ;
1686 //=======================================================================
1687 //function : ConvertToGrid
1689 //=======================================================================
1690 void V3d_View::ConvertToGrid(const Standard_Real X,
1691 const Standard_Real Y,
1692 const Standard_Real Z,
1695 Standard_Real& Zg) const
1697 if( MyViewer->Grid()->IsActive() ) {
1698 Graphic3d_Vertex aVrp (X,Y,Z) ;
1699 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1700 aNewVrp.Coord(Xg,Yg,Zg) ;
1702 Xg = X; Yg = Y; Zg = Z;
1706 //=======================================================================
1707 //function : Convert
1709 //=======================================================================
1710 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1712 Standard_Integer aDxw, aDyw ;
1714 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1716 MyWindow->Size (aDxw, aDyw);
1717 Standard_Real aValue;
1719 gp_Pnt aViewDims = Camera()->ViewDimensions();
1720 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1725 //=======================================================================
1726 //function : Convert
1728 //=======================================================================
1729 void V3d_View::Convert(const Standard_Integer Xp,
1730 const Standard_Integer Yp,
1732 Standard_Real& Yv) const
1734 Standard_Integer aDxw, aDyw;
1736 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1738 MyWindow->Size (aDxw, aDyw);
1740 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1741 aPoint = Camera()->ConvertProj2View (aPoint);
1747 //=======================================================================
1748 //function : Convert
1750 //=======================================================================
1751 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1753 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1755 Standard_Integer aDxw, aDyw;
1756 MyWindow->Size (aDxw, aDyw);
1758 gp_Pnt aViewDims = Camera()->ViewDimensions();
1759 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1764 //=======================================================================
1765 //function : Convert
1767 //=======================================================================
1768 void V3d_View::Convert(const Standard_Real Xv,
1769 const Standard_Real Yv,
1770 Standard_Integer& Xp,
1771 Standard_Integer& Yp) const
1773 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1775 Standard_Integer aDxw, aDyw;
1776 MyWindow->Size (aDxw, aDyw);
1778 gp_Pnt aPoint (Xv, Yv, 0.0);
1779 aPoint = Camera()->ConvertView2Proj (aPoint);
1780 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1782 Xp = RealToInt (aPoint.X());
1783 Yp = RealToInt (aPoint.Y());
1786 //=======================================================================
1787 //function : Convert
1789 //=======================================================================
1790 void V3d_View::Convert(const Standard_Integer Xp,
1791 const Standard_Integer Yp,
1794 Standard_Real& Z) const
1796 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1797 Standard_Integer aHeight, aWidth;
1798 MyWindow->Size (aWidth, aHeight);
1800 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1801 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1802 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1804 gp_Pnt aResult = Camera()->UnProject (gp_Pnt (anX, anY, aZ));
1811 //=======================================================================
1812 //function : ConvertWithProj
1814 //=======================================================================
1815 void V3d_View::ConvertWithProj(const Standard_Integer Xp,
1816 const Standard_Integer Yp,
1822 Standard_Real& Dz) const
1824 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1825 Standard_Integer aHeight, aWidth;
1826 MyWindow->Size (aWidth, aHeight);
1828 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1829 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1830 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1832 Handle(Graphic3d_Camera) aCamera = Camera();
1834 gp_Pnt aResult = aCamera->UnProject (gp_Pnt (anX, anY, aZ));
1840 Graphic3d_Vertex aVrp;
1841 aVrp.SetCoord (X, Y, Z);
1843 aResult = aCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1845 Graphic3d_Vec3d aNormDir;
1846 aNormDir.x() = X - aResult.X();
1847 aNormDir.y() = Y - aResult.Y();
1848 aNormDir.z() = Z - aResult.Z();
1849 aNormDir.Normalize();
1856 //=======================================================================
1857 //function : Convert
1859 //=======================================================================
1860 void V3d_View::Convert(const Standard_Real X,
1861 const Standard_Real Y,
1862 const Standard_Real Z,
1863 Standard_Integer& Xp,
1864 Standard_Integer& Yp) const
1866 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1867 Standard_Integer aHeight, aWidth;
1868 MyWindow->Size (aWidth, aHeight);
1870 gp_Pnt aPoint = Camera()->Project (gp_Pnt (X, Y, Z));
1872 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1873 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1876 //=======================================================================
1877 //function : Project
1879 //=======================================================================
1880 void V3d_View::Project (const Standard_Real theX,
1881 const Standard_Real theY,
1882 const Standard_Real theZ,
1883 Standard_Real& theXp,
1884 Standard_Real& theYp) const
1887 Project (theX, theY, theZ, theXp, theYp, aZp);
1890 //=======================================================================
1891 //function : Project
1893 //=======================================================================
1894 void V3d_View::Project (const Standard_Real theX,
1895 const Standard_Real theY,
1896 const Standard_Real theZ,
1897 Standard_Real& theXp,
1898 Standard_Real& theYp,
1899 Standard_Real& theZp) const
1901 Handle(Graphic3d_Camera) aCamera = Camera();
1903 gp_XYZ aViewSpaceDimensions = aCamera->ViewDimensions();
1904 Standard_Real aXSize = aViewSpaceDimensions.X();
1905 Standard_Real aYSize = aViewSpaceDimensions.Y();
1906 Standard_Real aZSize = aViewSpaceDimensions.Z();
1908 gp_Pnt aPoint = aCamera->Project (gp_Pnt (theX, theY, theZ));
1910 // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
1911 theXp = aPoint.X() * aXSize * 0.5;
1912 theYp = aPoint.Y() * aYSize * 0.5;
1913 theZp = aPoint.Z() * aZSize * 0.5;
1916 //=======================================================================
1917 //function : BackgroundColor
1919 //=======================================================================
1920 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1923 Standard_Real& V3) const
1925 Quantity_Color C = BackgroundColor() ;
1926 C.Values(V1,V2,V3,Type) ;
1929 //=======================================================================
1930 //function : BackgroundColor
1932 //=======================================================================
1933 Quantity_Color V3d_View::BackgroundColor() const
1935 return myView->Background().Color() ;
1938 //=======================================================================
1939 //function : GradientBackgroundColors
1941 //=======================================================================
1942 void V3d_View::GradientBackgroundColors (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1944 myView->GradientBackground().Colors (theColor1, theColor2);
1947 //=======================================================================
1948 //function : GradientBackground
1950 //=======================================================================
1951 Aspect_GradientBackground V3d_View::GradientBackground() const
1953 return myView->GradientBackground();
1956 //=======================================================================
1959 //=======================================================================
1960 Standard_Real V3d_View::Scale() const
1962 return myDefaultCamera->Scale() / Camera()->Scale();
1965 //=======================================================================
1966 //function : AxialScale
1968 //=======================================================================
1969 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1971 gp_Pnt anAxialScale = Camera()->AxialScale();
1972 Sx = anAxialScale.X();
1973 Sy = anAxialScale.Y();
1974 Sz = anAxialScale.Z();
1977 //=======================================================================
1980 //=======================================================================
1981 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1983 gp_Pnt aViewDims = Camera()->ViewDimensions();
1985 Width = aViewDims.X();
1986 Height = aViewDims.Y();
1989 //=======================================================================
1992 //=======================================================================
1993 Standard_Real V3d_View::ZSize() const
1995 gp_Pnt aViewDims = Camera()->ViewDimensions();
1997 return aViewDims.Z();
2000 //=======================================================================
2003 //=======================================================================
2004 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
2005 Standard_Real& Vmin,
2006 Standard_Real& Umax,
2007 Standard_Real& Vmax) const
2009 Standard_Real Wmin,Wmax,U,V,W ;
2010 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
2012 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
2015 Bnd_Box aBox = myView->MinMaxValues();
2016 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2017 Project (Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
2018 Project (Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
2019 Project (Xmin,Ymin,Zmax,U,V,W) ;
2020 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2021 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2022 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2023 Project (Xmax,Ymin,Zmax,U,V,W) ;
2024 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2025 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2026 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2027 Project (Xmax,Ymin,Zmin,U,V,W) ;
2028 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2029 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2030 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2031 Project (Xmax,Ymax,Zmin,U,V,W) ;
2032 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2033 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2034 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2035 Project (Xmin,Ymax,Zmax,U,V,W) ;
2036 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2037 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2038 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2039 Project (Xmin,Ymax,Zmin,U,V,W) ;
2040 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2041 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2042 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2047 //=======================================================================
2050 //=======================================================================
2051 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
2052 Standard_Real& Ymin,
2053 Standard_Real& Zmin,
2054 Standard_Real& Xmax,
2055 Standard_Real& Ymax,
2056 Standard_Real& Zmax) const
2059 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
2060 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
2063 Bnd_Box aBox = myView->MinMaxValues();
2064 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2069 //=======================================================================
2070 //function : Gravity
2072 //=======================================================================
2073 void V3d_View::Gravity (Standard_Real& theX,
2074 Standard_Real& theY,
2075 Standard_Real& theZ) const
2077 Graphic3d_MapOfStructure aSetOfStructures;
2078 myView->DisplayedStructures (aSetOfStructures);
2080 Standard_Boolean hasSelection = Standard_False;
2081 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2082 aStructIter.More(); aStructIter.Next())
2084 if (aStructIter.Key()->IsHighlighted()
2085 && aStructIter.Key()->IsVisible())
2087 hasSelection = Standard_True;
2092 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
2093 Standard_Integer aNbPoints = 0;
2094 gp_XYZ aResult (0.0, 0.0, 0.0);
2095 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2096 aStructIter.More(); aStructIter.Next())
2098 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2099 if (!aStruct->IsVisible()
2100 || aStruct->IsInfinite()
2101 || (hasSelection && !aStruct->IsHighlighted()))
2106 const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox();
2107 if (!aBox.IsValid())
2112 // skip transformation-persistent objects
2113 if (!aStruct->TransformPersistence().IsNull())
2118 // use camera projection to find gravity point
2119 Xmin = aBox.CornerMin().x();
2120 Ymin = aBox.CornerMin().y();
2121 Zmin = aBox.CornerMin().z();
2122 Xmax = aBox.CornerMax().x();
2123 Ymax = aBox.CornerMax().y();
2124 Zmax = aBox.CornerMax().z();
2125 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2127 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2128 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2129 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2130 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2133 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2135 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2136 const gp_Pnt aProjected = Camera()->Project (aBndPnt);
2137 if (Abs (aProjected.X()) <= 1.0
2138 && Abs (aProjected.Y()) <= 1.0)
2140 aResult += aBndPnt.XYZ();
2148 // fallback - just use bounding box of entire scene
2149 Bnd_Box aBox = myView->MinMaxValues();
2152 aBox.Get (Xmin, Ymin, Zmin,
2154 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2156 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2157 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2158 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2159 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2162 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2164 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2165 aResult += aBndPnt.XYZ();
2173 aResult /= aNbPoints;
2180 //=======================================================================
2183 //=======================================================================
2184 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2186 gp_Pnt aCameraEye = Camera()->Eye();
2192 //=============================================================================
2193 //function : FocalReferencePoint
2195 //=============================================================================
2196 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2201 //=============================================================================
2202 //function : ProjReferenceAxe
2204 //=============================================================================
2205 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2206 const Standard_Integer Ypix,
2212 Standard_Real& VZ) const
2214 Standard_Real Xo,Yo,Zo;
2216 Convert (Xpix, Ypix, XP, YP, ZP);
2217 if ( Type() == V3d_PERSPECTIVE )
2219 FocalReferencePoint (Xo,Yo,Zo);
2230 //=============================================================================
2233 //=============================================================================
2234 Standard_Real V3d_View::Depth() const
2236 return Camera()->Distance();
2239 //=============================================================================
2242 //=============================================================================
2243 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2245 gp_Dir aCameraDir = Camera()->Direction().Reversed();
2246 Dx = aCameraDir.X();
2247 Dy = aCameraDir.Y();
2248 Dz = aCameraDir.Z();
2251 //=============================================================================
2254 //=============================================================================
2255 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2257 gp_Pnt aCameraCenter = Camera()->Center();
2258 X = aCameraCenter.X();
2259 Y = aCameraCenter.Y();
2260 Z = aCameraCenter.Z();
2263 //=============================================================================
2266 //=============================================================================
2267 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2269 gp_Dir aCameraUp = Camera()->Up();
2275 //=============================================================================
2278 //=============================================================================
2279 Standard_Real V3d_View::Twist() const
2281 Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2282 Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
2283 Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
2284 Standard_Boolean TheStatus ;
2286 gp_Dir aReferencePlane (Camera()->Direction().Reversed());
2290 anUp = gp_Dir (0.,0.,1.) ;
2291 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2293 anUp = gp_Dir (0.,1.,0.) ;
2294 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2297 anUp = gp_Dir (1.,0.,0.) ;
2298 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2300 Yaxis.Coord(X0,Y0,Z0) ;
2303 /* Compute Cross Vector From Up & Origin */
2304 pvx = Y0*Zup - Z0*Yup ;
2305 pvy = Z0*Xup - X0*Zup ;
2306 pvz = X0*Yup - Y0*Xup ;
2307 pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2308 sca = X0*Xup + Y0*Yup + Z0*Zup ;
2311 if( angle > 1. ) angle = 1. ;
2312 else if( angle < -1. ) angle = -1. ;
2313 angle = asin(angle) ;
2314 if( sca < 0. ) angle = M_PI - angle ;
2315 if( angle > 0. && angle < M_PI ) {
2316 sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2317 if( sca < 0. ) angle = DEUXPI - angle ;
2322 //=============================================================================
2323 //function : ShadingModel
2325 //=============================================================================
2326 V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2328 return static_cast<V3d_TypeOfShadingModel> (myView->ShadingModel());
2331 //=============================================================================
2332 //function : TextureEnv
2334 //=============================================================================
2335 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2337 return myView->TextureEnv();
2340 //=============================================================================
2341 //function : Visualization
2343 //=============================================================================
2344 V3d_TypeOfVisualization V3d_View::Visualization() const
2346 return static_cast<V3d_TypeOfVisualization> (myView->VisualizationType());
2349 //=============================================================================
2352 //=============================================================================
2353 Handle(V3d_Viewer) V3d_View::Viewer() const
2358 //=============================================================================
2359 //function : IfWindow
2361 //=============================================================================
2362 Standard_Boolean V3d_View::IfWindow() const
2364 return myView->IsDefined();
2367 //=============================================================================
2370 //=============================================================================
2371 Handle(Aspect_Window) V3d_View::Window() const
2376 //=============================================================================
2379 //=============================================================================
2380 V3d_TypeOfView V3d_View::Type() const
2382 return Camera()->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2385 //=============================================================================
2386 //function : SetFocale
2388 //=============================================================================
2389 void V3d_View::SetFocale( const Standard_Real focale )
2391 Handle(Graphic3d_Camera) aCamera = Camera();
2393 if (aCamera->IsOrthographic())
2398 Standard_Real aFOVyRad = ATan (focale / (aCamera->Distance() * 2.0));
2400 aCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2405 //=============================================================================
2408 //=============================================================================
2409 Standard_Real V3d_View::Focale() const
2411 Handle(Graphic3d_Camera) aCamera = Camera();
2413 if (aCamera->IsOrthographic())
2418 return aCamera->Distance() * 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
2421 //=============================================================================
2424 //=============================================================================
2425 Handle(Graphic3d_CView) V3d_View::View() const
2430 //=============================================================================
2431 //function : ScreenAxis
2433 //=============================================================================
2434 Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2436 Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2437 Standard_Real dx1, dy1, dz1, xx, yy, zz;
2439 Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2440 Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2441 xx = Yup*Zpn - Zup*Ypn;
2442 yy = Zup*Xpn - Xup*Zpn;
2443 zz = Xup*Ypn - Yup*Xpn;
2444 Xaxe.SetCoord (xx, yy, zz);
2445 if (Xaxe.LengthZero()) return Standard_False;
2447 Xaxe.Coord(dx1, dy1, dz1);
2448 xx = Ypn*dz1 - Zpn*dy1;
2449 yy = Zpn*dx1 - Xpn*dz1;
2450 zz = Xpn*dy1 - Ypn*dx1;
2451 Yaxe.SetCoord (xx, yy, zz) ;
2452 if (Yaxe.LengthZero()) return Standard_False;
2455 Zaxe.SetCoord (Xpn, Ypn, Zpn);
2457 return Standard_True;
2460 //=============================================================================
2461 //function : TrsPoint
2463 //=============================================================================
2464 Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2466 Graphic3d_Vertex PP ;
2467 Standard_Real X,Y,Z,XX,YY,ZZ ;
2470 Standard_Integer lr, ur, lc, uc;
2471 lr = Matrix.LowerRow ();
2472 ur = Matrix.UpperRow ();
2473 lc = Matrix.LowerCol ();
2474 uc = Matrix.UpperCol ();
2475 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
2477 PP.SetCoord(X,Y,Z) ;
2481 XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2482 Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2484 YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2485 Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2487 ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2488 Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2489 PP.SetCoord(XX,YY,ZZ) ;
2493 //=======================================================================
2496 //=======================================================================
2497 void V3d_View::Pan (const Standard_Integer theDXp,
2498 const Standard_Integer theDYp,
2499 const Quantity_Factor theZoomFactor,
2500 const Standard_Boolean theToStart)
2502 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2505 //=======================================================================
2506 //function : Panning
2508 //=======================================================================
2509 void V3d_View::Panning (const Standard_Real theDXv,
2510 const Standard_Real theDYv,
2511 const Quantity_Factor theZoomFactor,
2512 const Standard_Boolean theToStart)
2514 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2516 Handle(Graphic3d_Camera) aCamera = Camera();
2520 myCamStartOpEye = aCamera->Eye();
2521 myCamStartOpCenter = aCamera->Center();
2524 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2526 gp_Pnt aViewDims = aCamera->ViewDimensions();
2528 aCamera->SetEye (myCamStartOpEye);
2529 aCamera->SetCenter (myCamStartOpCenter);
2530 Translate (aCamera, -theDXv, -theDYv);
2531 Scale (aCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2533 SetImmediateUpdate (wasUpdateEnabled);
2538 //=======================================================================
2541 //=======================================================================
2542 void V3d_View::Zoom (const Standard_Integer theXp1,
2543 const Standard_Integer theYp1,
2544 const Standard_Integer theXp2,
2545 const Standard_Integer theYp2)
2547 Standard_Integer aDx = theXp2 - theXp1;
2548 Standard_Integer aDy = theYp2 - theYp1;
2549 if (aDx != 0 || aDy != 0)
2551 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2552 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2553 SetZoom (aCoeff, Standard_True);
2557 //=======================================================================
2558 //function : StartZoomAtPoint
2560 //=======================================================================
2561 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2562 const Standard_Integer theYp)
2564 MyZoomAtPointX = theXp;
2565 MyZoomAtPointY = theYp;
2568 //=======================================================================
2569 //function : ZoomAtPoint
2571 //=======================================================================
2572 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2573 const Standard_Integer theMouseStartY,
2574 const Standard_Integer theMouseEndX,
2575 const Standard_Integer theMouseEndY)
2577 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2580 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2581 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2582 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2584 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2586 Handle(Graphic3d_Camera) aCamera = Camera();
2588 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
2589 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
2591 // ensure that zoom will not be too small or too big.
2592 Standard_Real aCoef = aDZoom;
2593 if (aViewWidth < aCoef * Precision::Confusion())
2595 aCoef = aViewWidth / Precision::Confusion();
2597 else if (aViewWidth > aCoef * 1e12)
2599 aCoef = aViewWidth / 1e12;
2601 if (aViewHeight < aCoef * Precision::Confusion())
2603 aCoef = aViewHeight / Precision::Confusion();
2605 else if (aViewHeight > aCoef * 1e12)
2607 aCoef = aViewHeight / 1e12;
2610 Standard_Real aZoomAtPointXv = 0.0;
2611 Standard_Real aZoomAtPointYv = 0.0;
2612 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2614 V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
2615 V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
2617 aCamera->SetScale (aCamera->Scale() / aCoef);
2618 Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2622 SetImmediateUpdate (wasUpdateEnabled);
2627 //=============================================================================
2628 //function : AxialScale
2630 //=============================================================================
2631 void V3d_View::AxialScale (const Standard_Integer Dx,
2632 const Standard_Integer Dy,
2633 const V3d_TypeOfAxe Axis)
2635 if( Dx != 0. || Dy != 0. ) {
2636 Standard_Real Sx, Sy, Sz;
2637 AxialScale( Sx, Sy, Sz );
2638 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2639 dscale = (Dx > 0) ? dscale : 1./dscale;
2640 if( Axis == V3d_X ) Sx = dscale;
2641 if( Axis == V3d_Y ) Sy = dscale;
2642 if( Axis == V3d_Z ) Sz = dscale;
2643 SetAxialScale( Sx, Sy, Sz );
2647 //=============================================================================
2650 //=============================================================================
2651 void V3d_View::FitAll(const Standard_Real theXmin,
2652 const Standard_Real theYmin,
2653 const Standard_Real theXmax,
2654 const Standard_Real theYmax)
2656 Handle(Graphic3d_Camera) aCamera = Camera();
2657 Standard_Real anAspect = aCamera->Aspect();
2659 Standard_Real aFitSizeU = Abs (theXmax - theXmin);
2660 Standard_Real aFitSizeV = Abs (theYmax - theYmin);
2661 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2662 if (aFitAspect >= anAspect)
2664 aFitSizeV = aFitSizeU / anAspect;
2668 aFitSizeU = aFitSizeV * anAspect;
2671 Translate (aCamera, (theXmin + theXmax) * 0.5, (theYmin + theYmax) * 0.5);
2672 Scale (aCamera, aFitSizeU, aFitSizeV);
2679 //=============================================================================
2680 //function : StartRotation
2682 //=============================================================================
2683 void V3d_View::StartRotation(const Standard_Integer X,
2684 const Standard_Integer Y,
2685 const Quantity_Ratio zRotationThreshold)
2690 rx = Standard_Real(Convert(x));
2691 ry = Standard_Real(Convert(y));
2693 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2694 myZRotation = Standard_False;
2695 if( zRotationThreshold > 0. ) {
2696 Standard_Real dx = Abs(sx - rx/2.);
2697 Standard_Real dy = Abs(sy - ry/2.);
2698 // if( dx > rx/3. || dy > ry/3. ) myZRotation = Standard_True;
2699 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2700 if( dx > dd || dy > dd ) myZRotation = Standard_True;
2705 //=============================================================================
2706 //function : Rotation
2708 //=============================================================================
2709 void V3d_View::Rotation(const Standard_Integer X,
2710 const Standard_Integer Y)
2712 if( rx == 0. || ry == 0. ) {
2716 Standard_Real dx=0.,dy=0.,dz=0.;
2718 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2719 atan2(sx-rx/2.,ry/2.-sy);
2721 dx = (Standard_Real(X) - sx) * M_PI / rx;
2722 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2725 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2728 //=============================================================================
2729 //function : SetComputedMode
2731 //=============================================================================
2732 void V3d_View::SetComputedMode (const Standard_Boolean theMode)
2738 myView->SetComputedMode (Standard_True);
2744 myView->SetComputedMode (Standard_False);
2749 //=============================================================================
2750 //function : ComputedMode
2752 //=============================================================================
2753 Standard_Boolean V3d_View::ComputedMode() const
2755 return myView->ComputedMode();
2758 //=============================================================================
2759 //function : SetBackFacingModel
2761 //=============================================================================
2762 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel theModel)
2764 myView->SetBackfacingModel (static_cast<Graphic3d_TypeOfBackfacingModel> (theModel));
2768 //=============================================================================
2769 //function : BackFacingModel
2771 //=============================================================================
2772 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2774 return static_cast<V3d_TypeOfBackfacingModel> (myView->BackfacingModel());
2777 //=============================================================================
2780 //=============================================================================
2781 void V3d_View::Init()
2783 myComputedMode = MyViewer->ComputedMode();
2784 if (!myComputedMode || !MyViewer->DefaultComputedMode())
2786 SetComputedMode (Standard_False);
2790 //=============================================================================
2793 //=============================================================================
2794 Standard_Boolean V3d_View::Export (const Standard_CString theFileName,
2795 const Graphic3d_ExportFormat theFormat,
2796 const Graphic3d_SortType theSortType)
2798 return myView->Export (theFileName, theFormat, theSortType);
2801 //=============================================================================
2804 //=============================================================================
2805 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2806 const Graphic3d_BufferType& theBufferType)
2808 Standard_Integer aWinWidth, aWinHeight;
2809 MyWindow->Size (aWinWidth, aWinHeight);
2810 Image_AlienPixMap anImage;
2812 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2815 //=============================================================================
2816 //function : ToPixMap
2818 //=============================================================================
2819 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
2820 const V3d_ImageDumpOptions& theParams)
2822 Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
2823 if (aTargetSize.x() != 0
2824 && aTargetSize.y() != 0)
2826 // allocate image buffer for dumping
2827 if (theImage.IsEmpty()
2828 || theImage.SizeX() != Standard_Size(aTargetSize.x())
2829 || theImage.SizeY() != Standard_Size(aTargetSize.y()))
2831 Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
2832 switch (theParams.BufferType)
2834 case Graphic3d_BT_RGB: aFormat = Image_PixMap::ImgRGB; break;
2835 case Graphic3d_BT_RGBA: aFormat = Image_PixMap::ImgRGBA; break;
2836 case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
2839 if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
2841 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y()
2842 + " for view dump", Message_Fail);
2843 return Standard_False;
2847 if (theImage.IsEmpty())
2849 Message::DefaultMessenger()->Send (TCollection_AsciiString ("V3d_View::ToPixMap() has been called without image dimensions"), Message_Fail);
2850 return Standard_False;
2852 aTargetSize.x() = (Standard_Integer )theImage.SizeX();
2853 aTargetSize.y() = (Standard_Integer )theImage.SizeY();
2855 Handle(Standard_Transient) aFBOPtr;
2856 Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
2857 Graphic3d_Vec2i aFBOVPSize = aTargetSize;
2859 bool isTiling = false;
2860 if (theParams.TileSize > 0)
2862 if (aFBOVPSize.x() > theParams.TileSize
2863 || aFBOVPSize.y() > theParams.TileSize)
2865 aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
2866 aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
2871 Graphic3d_Vec2i aPrevFBOVPSize;
2872 if (!aPrevFBOPtr.IsNull())
2874 Graphic3d_Vec2i aPrevFBOSizeMax;
2875 myView->FBOGetDimensions (aPrevFBOPtr,
2876 aPrevFBOVPSize.x(), aPrevFBOVPSize.y(),
2877 aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
2878 if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
2879 && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
2881 aFBOPtr = aPrevFBOPtr;
2885 if (aFBOPtr.IsNull())
2887 Standard_Integer aMaxTexSize = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxTextureSize);
2888 if (theParams.TileSize > aMaxTexSize)
2890 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
2891 + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSize + ")", Message_Fail);
2892 return Standard_False;
2895 if (aFBOVPSize.x() > aMaxTexSize
2896 || aFBOVPSize.y() > aMaxTexSize)
2898 aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSize);
2899 aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSize);
2903 // Try to create hardware accelerated buffer
2904 aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
2906 myView->SetFBO (aFBOPtr);
2908 if (aFBOPtr.IsNull())
2910 // try to use on-screen buffer
2911 Graphic3d_Vec2i aWinSize;
2912 MyWindow->Size (aWinSize.x(), aWinSize.y());
2913 if (aFBOVPSize.x() != aWinSize.x()
2914 || aFBOVPSize.y() != aWinSize.y())
2918 aFBOVPSize = aWinSize;
2920 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning, on screen buffer is used for image dump - content might be invalid"), Message_Warning);
2923 // backup camera parameters
2924 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2925 Handle(Graphic3d_Camera) aCamera = Camera();
2926 aStoreMapping->Copy (aCamera);
2927 if (aCamera->IsStereo())
2929 switch (theParams.StereoOptions)
2933 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2936 case V3d_SDO_LEFT_EYE:
2938 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2941 case V3d_SDO_RIGHT_EYE:
2943 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2946 case V3d_SDO_BLENDED:
2948 break; // dump as is
2952 if (theParams.ToAdjustAspect)
2954 aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
2958 // render immediate structures into back buffer rather than front
2959 const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
2961 Standard_Boolean isSuccess = Standard_True;
2964 if (!aFBOPtr.IsNull())
2966 myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
2969 isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
2973 Image_PixMap aTilePixMap;
2974 aTilePixMap.SetTopDown (theImage.IsTopDown());
2976 Graphic3d_Vec2i anOffset (0, 0);
2977 for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
2980 for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
2982 Graphic3d_CameraTile aTile;
2983 aTile.Offset = anOffset;
2984 aTile.TotalSize = aTargetSize;
2985 aTile.TileSize = aFBOVPSize;
2986 if (!aFBOPtr.IsNull())
2988 // crop corners in case of FBO
2989 // (no API to resize viewport of on-screen buffer - keep uncropped in this case)
2990 aTile = aTile.Cropped();
2992 if (aTile.TileSize.x() < 1
2993 || aTile.TileSize.y() < 1)
2998 const Standard_Integer aLeft = aTile.Offset.x();
2999 Standard_Integer aBottom = aTile.Offset.y();
3000 if (theImage.IsTopDown())
3002 const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
3003 aBottom = aTargetSize.y() - aTop;
3005 aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
3006 + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
3007 aTile.TileSize.x(), aTile.TileSize.y(),
3008 theImage.SizeRowBytes());
3010 aCamera->SetTile (aTile);
3011 if (!aFBOPtr.IsNull())
3013 myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
3016 isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
3030 myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
3031 aCamera->Copy (aStoreMapping);
3032 if (aFBOPtr != aPrevFBOPtr)
3034 myView->FBORelease (aFBOPtr);
3036 else if (!aPrevFBOPtr.IsNull())
3038 myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
3040 myView->SetFBO (aPrevFBOPtr);
3044 //=============================================================================
3045 //function : ImmediateUpdate
3047 //=============================================================================
3048 void V3d_View::ImmediateUpdate() const
3050 if (myImmediateUpdate)
3056 //=============================================================================
3057 //function : SetImmediateUpdate
3059 //=============================================================================
3060 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
3062 Standard_Boolean aPreviousMode = myImmediateUpdate;
3063 myImmediateUpdate = theImmediateUpdate;
3064 return aPreviousMode;
3067 // =======================================================================
3068 // function : SetCamera
3070 // =======================================================================
3071 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
3073 myView->SetCamera (theCamera);
3078 // =======================================================================
3079 // function : GetCamera
3081 // =======================================================================
3082 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
3084 return myView->Camera();
3087 // =======================================================================
3088 // function : FitMinMax
3089 // purpose : Internal
3090 // =======================================================================
3091 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
3092 const Bnd_Box& theBox,
3093 const Standard_Real theMargin,
3094 const Standard_Real theResolution,
3095 const Standard_Boolean theToEnlargeIfLine) const
3097 // Check bounding box for validness
3098 if (theBox.IsVoid())
3100 return Standard_False; // bounding box is out of bounds...
3103 // Apply "axial scaling" to the bounding points.
3104 // It is not the best approach to make this scaling as a part of fit all operation,
3105 // but the axial scale is integrated into camera orientation matrix and the other
3106 // option is to perform frustum plane adjustment algorithm in view camera space,
3107 // which will lead to a number of additional world-view space conversions and
3108 // loosing precision as well.
3109 gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (theCamera->AxialScale());
3110 gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (theCamera->AxialScale());
3112 if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
3114 return Standard_False; // nothing to fit all
3117 // Prepare camera frustum planes.
3118 NCollection_Array1<gp_Pln> aFrustumPlane (1, 6);
3119 theCamera->Frustum (aFrustumPlane.ChangeValue (1),
3120 aFrustumPlane.ChangeValue (2),
3121 aFrustumPlane.ChangeValue (3),
3122 aFrustumPlane.ChangeValue (4),
3123 aFrustumPlane.ChangeValue (5),
3124 aFrustumPlane.ChangeValue (6));
3126 // Prepare camera up, side, direction vectors.
3127 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3128 gp_Dir aCamDir = theCamera->Direction();
3129 gp_Dir aCamSide = aCamDir ^ aCamUp;
3131 // Prepare scene bounding box parameters.
3132 gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
3134 NCollection_Array1<gp_Pnt> aBndCorner (1, 8);
3135 aBndCorner.ChangeValue (1) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
3136 aBndCorner.ChangeValue (2) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
3137 aBndCorner.ChangeValue (3) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
3138 aBndCorner.ChangeValue (4) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
3139 aBndCorner.ChangeValue (5) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
3140 aBndCorner.ChangeValue (6) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
3141 aBndCorner.ChangeValue (7) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
3142 aBndCorner.ChangeValue (8) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
3144 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3145 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3146 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3147 // set up perspective-correct camera projection matching the bounding box.
3148 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3149 // The zooming can be done by calculating view plane size matching the bounding box at center of
3150 // the bounding box. The only limitation here is that the scale of camera should define size of
3151 // its view plane passing through the camera center, and the center of camera should be on the
3152 // same line with the center of bounding box.
3154 // The following method is applied:
3155 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3156 // 2) Determine new location of frustum planes, "matching" the bounding box.
3157 // 3) Determine new camera projection vector using the normalized asymmetry.
3158 // 4) Determine new zooming in view space.
3160 // 1. Determine normalized projection asymmetry (if any).
3161 Standard_Real anAssymX = Tan (( aCamSide).Angle (aFrustumPlane (1).Axis().Direction()))
3162 - Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction()));
3163 Standard_Real anAssymY = Tan (( aCamUp) .Angle (aFrustumPlane (3).Axis().Direction()))
3164 - Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction()));
3166 // 2. Determine how far should be the frustum planes placed from center
3167 // of bounding box, in order to match the bounding box closely.
3168 NCollection_Array1<Standard_Real> aFitDistance (1, 6);
3169 aFitDistance.ChangeValue (1) = 0.0;
3170 aFitDistance.ChangeValue (2) = 0.0;
3171 aFitDistance.ChangeValue (3) = 0.0;
3172 aFitDistance.ChangeValue (4) = 0.0;
3173 aFitDistance.ChangeValue (5) = 0.0;
3174 aFitDistance.ChangeValue (6) = 0.0;
3176 for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
3178 // Measure distances from center of bounding box to its corners towards the frustum plane.
3179 const gp_Dir& aPlaneN = aFrustumPlane.ChangeValue (anI).Axis().Direction();
3181 Standard_Real& aFitDist = aFitDistance.ChangeValue (anI);
3183 for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
3185 aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner (aJ)).Dot (aPlaneN));
3188 // The center of camera is placed on the same line with center of bounding box.
3189 // The view plane section crosses the bounding box at its center.
3190 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3191 // into view section size between the point and the frustum plane.
3193 // /|\ right half of frame //
3195 // point o<-- distance * coeff -->//---- (view plane section)
3204 aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan ( aCamSide .Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
3205 aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
3206 aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan ( aCamUp .Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
3207 aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
3208 aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan ( aCamDir .Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
3209 aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan ((-aCamDir) .Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
3211 Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
3212 Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
3213 Standard_Real aViewSizeZv = aFitDistance (5) + aFitDistance (6);
3215 // 3. Place center of camera on the same line with center of bounding
3216 // box applying corresponding projection asymmetry (if any).
3217 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3218 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3219 Standard_Real anOffsetXv = (aFitDistance (2) - aFitDistance (1)) * 0.5 + anAssymXv;
3220 Standard_Real anOffsetYv = (aFitDistance (4) - aFitDistance (3)) * 0.5 + anAssymYv;
3221 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3222 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3223 gp_Pnt aCamNewCenter = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3225 gp_Trsf aCenterTrsf;
3226 aCenterTrsf.SetTranslation (theCamera->Center(), aCamNewCenter);
3227 theCamera->Transform (aCenterTrsf);
3228 theCamera->SetDistance (aFitDistance (6) + aFitDistance (5));
3230 // Bounding box collapses to a point or thin line going in depth of the screen
3231 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3233 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3235 return Standard_True; // This is just one point or line and zooming has no effect.
3238 // Looking along line and "theToEnlargeIfLine" is requested.
3239 // Fit view to see whole scene on rotation.
3240 aViewSizeXv = aViewSizeZv;
3241 aViewSizeYv = aViewSizeZv;
3244 Scale (theCamera, aViewSizeXv, aViewSizeYv);
3246 const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
3248 Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
3250 return Standard_True;
3253 // =======================================================================
3255 // purpose : Internal
3256 // =======================================================================
3257 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3258 const Standard_Real theSizeXv,
3259 const Standard_Real theSizeYv) const
3261 Standard_Real anAspect = theCamera->Aspect();
3264 theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
3268 theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
3272 // =======================================================================
3273 // function : Translate
3274 // purpose : Internal
3275 // =======================================================================
3276 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3277 const Standard_Real theDXv,
3278 const Standard_Real theDYv) const
3280 const gp_Pnt& aCenter = theCamera->Center();
3281 const gp_Dir& aDir = theCamera->Direction();
3282 const gp_Dir& anUp = theCamera->Up();
3283 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3285 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3286 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3287 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3289 aPanTrsf.SetTranslation (aCameraPan);
3291 theCamera->Transform (aPanTrsf);
3294 // =======================================================================
3295 // function : IsCullingEnabled
3297 // =======================================================================
3298 Standard_Boolean V3d_View::IsCullingEnabled() const
3300 return myView->IsCullingEnabled();
3303 // =======================================================================
3304 // function : SetFrustumCulling
3306 // =======================================================================
3307 void V3d_View::SetFrustumCulling (const Standard_Boolean theToClip)
3309 myView->SetCullingEnabled (theToClip);
3312 // =======================================================================
3313 // function : DiagnosticInformation
3315 // =======================================================================
3316 void V3d_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
3317 Graphic3d_DiagnosticInfo theFlags) const
3319 myView->DiagnosticInformation (theDict, theFlags);
3322 //=============================================================================
3323 //function : RenderingParams
3325 //=============================================================================
3326 const Graphic3d_RenderingParams& V3d_View::RenderingParams() const
3328 return myView->RenderingParams();
3331 //=============================================================================
3332 //function : ChangeRenderingParams
3334 //=============================================================================
3335 Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams()
3337 return myView->ChangeRenderingParams();