1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <V3d_View.hxx>
16 #include <Aspect_GradientBackground.hxx>
17 #include <Aspect_Grid.hxx>
18 #include <Aspect_Window.hxx>
19 #include <Bnd_Box.hxx>
23 #include <Graphic3d_AspectMarker3d.hxx>
24 #include <Graphic3d_GraphicDriver.hxx>
25 #include <Graphic3d_Group.hxx>
26 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
27 #include <Graphic3d_MapOfStructure.hxx>
28 #include <Graphic3d_Structure.hxx>
29 #include <Graphic3d_TextureEnv.hxx>
30 #include <Image_AlienPixMap.hxx>
31 #include <Message.hxx>
32 #include <Message_Messenger.hxx>
33 #include <NCollection_Array1.hxx>
34 #include <Precision.hxx>
35 #include <Quantity_Color.hxx>
36 #include <Standard_Assert.hxx>
37 #include <Standard_DivideByZero.hxx>
38 #include <Standard_ErrorHandler.hxx>
39 #include <Standard_MultiplyDefined.hxx>
40 #include <Standard_ShortReal.hxx>
41 #include <Standard_Type.hxx>
42 #include <Standard_TypeMismatch.hxx>
43 #include <TColgp_Array1OfPnt.hxx>
44 #include <TColStd_Array2OfReal.hxx>
45 #include <TColStd_HSequenceOfInteger.hxx>
47 #include <V3d_BadValue.hxx>
48 #include <V3d_Light.hxx>
49 #include <V3d_StereoDumpOptions.hxx>
50 #include <V3d_UnMapped.hxx>
51 #include <V3d_Viewer.hxx>
53 IMPLEMENT_STANDARD_RTTIEXT(V3d_View,Standard_Transient)
55 #define DEUXPI (2. * M_PI)
59 static const Standard_Integer THE_NB_BOUND_POINTS = 8;
62 //=============================================================================
63 //function : Constructor
65 //=============================================================================
66 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType)
67 : MyViewer (theViewer.operator->()),
68 SwitchSetFront (Standard_False),
69 myZRotation (Standard_False),
70 myTrihedron (new V3d_Trihedron()),
73 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
75 myView->SetBackground (theViewer->GetBackgroundColor());
76 myView->SetGradientBackground (theViewer->GetGradientBackground());
78 ChangeRenderingParams() = theViewer->DefaultRenderingParams();
81 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
82 aCamera->SetFOVy (45.0);
83 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
84 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
85 aCamera->SetProjectionType ((theType == V3d_ORTHOGRAPHIC)
86 ? Graphic3d_Camera::Projection_Orthographic
87 : Graphic3d_Camera::Projection_Perspective);
89 myDefaultCamera = new Graphic3d_Camera();
91 myImmediateUpdate = Standard_False;
92 SetAutoZFitMode (Standard_True, 1.0);
93 SetBackFacingModel (V3d_TOBM_AUTOMATIC);
95 SetAxis (0.,0.,0.,1.,1.,1.);
96 SetVisualization (theViewer->DefaultVisualization());
97 SetShadingModel (theViewer->DefaultShadingModel());
100 SetProj (theViewer->DefaultViewProj());
101 SetSize (theViewer->DefaultViewSize());
102 Standard_Real zsize = theViewer->DefaultViewSize();
104 SetDepth (theViewer->DefaultViewSize() / 2.0);
105 SetViewMappingDefault();
106 SetViewOrientationDefault();
107 theViewer->AddView (this);
109 myImmediateUpdate = Standard_True;
112 //=============================================================================
113 //function : Constructor
115 //=============================================================================
116 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
117 : MyViewer (theViewer.operator->()),
118 SwitchSetFront(Standard_False),
119 myZRotation (Standard_False),
122 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
124 myView->CopySettings (theView->View());
126 myDefaultCamera = new Graphic3d_Camera();
128 myImmediateUpdate = Standard_False;
129 SetAutoZFitMode (theView->AutoZFitMode(), theView->AutoZFitScaleFactor());
130 SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
131 SetViewMappingDefault();
132 SetViewOrientationDefault();
133 theViewer->AddView (this);
135 myImmediateUpdate = Standard_True;
138 //=============================================================================
139 //function : Destructor
141 //=============================================================================
142 V3d_View::~V3d_View()
144 if (!myView->IsRemoved())
150 //=============================================================================
151 //function : SetMagnify
153 //=============================================================================
154 void V3d_View::SetMagnify (const Handle(Aspect_Window)& theWindow,
155 const Handle(V3d_View)& thePreviousView,
156 const Standard_Integer theX1,
157 const Standard_Integer theY1,
158 const Standard_Integer theX2,
159 const Standard_Integer theY2)
161 if (!myView->IsRemoved() && !myView->IsDefined())
163 Standard_Real aU1, aV1, aU2, aV2;
164 thePreviousView->Convert (theX1, theY1, aU1, aV1);
165 thePreviousView->Convert (theX2, theY2, aU2, aV2);
166 myView->SetWindow (theWindow);
167 FitAll (aU1, aV1, aU2, aV2);
168 MyViewer->SetViewOn (this);
169 MyWindow = theWindow;
172 SetViewMappingDefault();
176 //=============================================================================
177 //function : SetWindow
179 //=============================================================================
180 void V3d_View::SetWindow (const Handle(Aspect_Window)& theWindow,
181 const Aspect_RenderingContext theContext)
183 if (myView->IsRemoved())
188 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
189 MyWindow = theWindow;
190 myView->SetWindow (theWindow, theContext);
191 MyViewer->SetViewOn (this);
196 //=============================================================================
199 //=============================================================================
200 void V3d_View::Remove() const
202 if (!MyGrid.IsNull())
206 if (!myTrihedron.IsNull())
208 myTrihedron->Erase();
211 MyViewer->DelView (this);
213 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
217 //=============================================================================
220 //=============================================================================
221 void V3d_View::Update() const
223 if (!myView->IsDefined()
224 || !myView->IsActive())
234 //=============================================================================
237 //=============================================================================
238 void V3d_View::Redraw() const
240 if (!myView->IsDefined()
241 || !myView->IsActive())
246 Handle(Graphic3d_StructureManager) aStructureMgr = MyViewer->StructureManager();
247 for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
249 if (aStructureMgr->IsDeviceLost())
251 aStructureMgr->RecomputeStructures();
258 if (!aStructureMgr->IsDeviceLost())
265 //=============================================================================
266 //function : RedrawImmediate
268 //=============================================================================
269 void V3d_View::RedrawImmediate() const
271 if (!myView->IsDefined()
272 || !myView->IsActive())
277 myView->RedrawImmediate();
280 //=============================================================================
281 //function : Invalidate
283 //=============================================================================
284 void V3d_View::Invalidate() const
286 if (!myView->IsDefined())
291 myView->Invalidate();
294 //=============================================================================
295 //function : IsInvalidated
297 //=============================================================================
298 Standard_Boolean V3d_View::IsInvalidated() const
300 return !myView->IsDefined()
301 || myView->IsInvalidated();
304 // ========================================================================
305 // function : SetAutoZFitMode
307 // ========================================================================
308 void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn,
309 const Standard_Real theScaleFactor)
311 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
312 myAutoZFitScaleFactor = theScaleFactor;
313 myAutoZFitIsOn = theIsOn;
316 // ========================================================================
317 // function : AutoZFitMode
319 // ========================================================================
320 Standard_Boolean V3d_View::AutoZFitMode() const
322 return myAutoZFitIsOn;
325 // ========================================================================
326 // function : AutoZFitScaleFactor
328 // ========================================================================
329 Standard_Real V3d_View::AutoZFitScaleFactor() const
331 return myAutoZFitScaleFactor;
334 //=============================================================================
335 //function : AutoZFit
337 //=============================================================================
338 void V3d_View::AutoZFit() const
345 ZFitAll (myAutoZFitScaleFactor);
348 //=============================================================================
351 //=============================================================================
352 void V3d_View::ZFitAll (const Standard_Real theScaleFactor) const
354 Bnd_Box aMinMaxBox = myView->MinMaxValues (Standard_False); // applicative min max boundaries
355 Bnd_Box aGraphicBox = myView->MinMaxValues (Standard_True); // real graphical boundaries (not accounting infinite flag).
357 myView->Camera()->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
360 //=============================================================================
363 //=============================================================================
364 Standard_Boolean V3d_View::IsEmpty() const
366 Standard_Boolean TheStatus = Standard_True ;
367 if( myView->IsDefined() ) {
368 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
369 if( Nstruct > 0 ) TheStatus = Standard_False ;
374 //=============================================================================
375 //function : UpdateLights
377 //=============================================================================
378 void V3d_View::UpdateLights() const
380 Handle(Graphic3d_LightSet) aLights = new Graphic3d_LightSet();
381 for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
383 aLights->Add (anActiveLightIter.Value());
385 myView->SetLights (aLights);
388 //=============================================================================
389 //function : DoMapping
391 //=============================================================================
392 void V3d_View::DoMapping()
394 if (!myView->IsDefined())
399 myView->Window()->DoMapping();
402 //=============================================================================
403 //function : MustBeResized
405 //=============================================================================
406 void V3d_View::MustBeResized()
408 if (!myView->IsDefined())
420 //=============================================================================
421 //function : SetBackgroundColor
423 //=============================================================================
424 void V3d_View::SetBackgroundColor (const Quantity_TypeOfColor theType,
425 const Standard_Real theV1,
426 const Standard_Real theV2,
427 const Standard_Real theV3)
429 Standard_Real aV1 = Max (Min (theV1, 1.0), 0.0);
430 Standard_Real aV2 = Max (Min (theV2, 1.0), 0.0);
431 Standard_Real aV3 = Max (Min (theV3, 1.0), 0.0);
433 SetBackgroundColor (Quantity_Color (aV1, aV2, aV3, theType));
436 //=============================================================================
437 //function : SetBackgroundColor
439 //=============================================================================
440 void V3d_View::SetBackgroundColor (const Quantity_Color& theColor)
442 myView->SetBackground (Aspect_Background (theColor));
444 if (myImmediateUpdate)
450 //=============================================================================
451 //function : SetBgGradientColors
453 //=============================================================================
454 void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
455 const Quantity_Color& theColor2,
456 const Aspect_GradientFillMethod theFillStyle,
457 const Standard_Boolean theToUpdate)
459 Aspect_GradientBackground aGradientBg (theColor1, theColor2, theFillStyle);
461 myView->SetGradientBackground (aGradientBg);
463 if (myImmediateUpdate || theToUpdate)
469 //=============================================================================
470 //function : SetBgGradientStyle
472 //=============================================================================
473 void V3d_View::SetBgGradientStyle (const Aspect_GradientFillMethod theFillStyle, const Standard_Boolean theToUpdate)
475 Quantity_Color aColor1;
476 Quantity_Color aColor2;
477 GradientBackground().Colors (aColor1, aColor2);
479 SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
482 //=============================================================================
483 //function : SetBackgroundImage
485 //=============================================================================
486 void V3d_View::SetBackgroundImage (const Standard_CString theFileName,
487 const Aspect_FillMethod theFillStyle,
488 const Standard_Boolean theToUpdate)
490 myView->SetBackgroundImage (theFileName);
491 myView->SetBackgroundImageStyle (theFillStyle);
493 if (myImmediateUpdate || theToUpdate)
499 //=============================================================================
500 //function : SetBgImageStyle
502 //=============================================================================
503 void V3d_View::SetBgImageStyle (const Aspect_FillMethod theFillStyle, const Standard_Boolean theToUpdate)
505 myView->SetBackgroundImageStyle (theFillStyle);
507 if (myImmediateUpdate || theToUpdate)
513 //=============================================================================
516 //=============================================================================
517 void V3d_View::SetAxis (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
518 const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
520 myDefaultViewPoint.SetCoord (theX, theY, theZ);
521 myDefaultViewAxis.SetCoord (theVx, theVy, theVz);
524 //=============================================================================
525 //function : SetShadingModel
527 //=============================================================================
528 void V3d_View::SetShadingModel (const Graphic3d_TypeOfShadingModel theShadingModel)
530 myView->SetShadingModel (theShadingModel);
533 //=============================================================================
534 //function : SetTextureEnv
536 //=============================================================================
537 void V3d_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTexture)
539 myView->SetTextureEnv (theTexture);
541 if (myImmediateUpdate)
547 //=============================================================================
548 //function : SetVisualization
550 //=============================================================================
551 void V3d_View::SetVisualization (const V3d_TypeOfVisualization theType)
553 myView->SetVisualizationType (static_cast <Graphic3d_TypeOfVisualization> (theType));
555 if (myImmediateUpdate)
561 //=============================================================================
562 //function : SetFront
564 //=============================================================================
565 void V3d_View::SetFront()
567 gp_Ax3 a = MyViewer->PrivilegedPlane();
568 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
570 a.Direction().Coord(vx,vy,vz);
571 a.YDirection().Coord(xu,yu,zu);
572 a.Location().Coord(xo,yo,zo);
574 Handle(Graphic3d_Camera) aCamera = Camera();
576 aCamera->SetCenter (gp_Pnt (xo, yo, zo));
580 aCamera->SetDirection (gp_Dir (vx, vy, vz));
584 aCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
587 aCamera->SetUp (gp_Dir (xu, yu, zu));
591 SwitchSetFront = !SwitchSetFront;
596 //=============================================================================
599 //=============================================================================
600 void V3d_View::Rotate (const Standard_Real ax,
601 const Standard_Real ay,
602 const Standard_Real az,
603 const Standard_Boolean Start)
605 Standard_Real Ax = ax;
606 Standard_Real Ay = ay;
607 Standard_Real Az = az;
609 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
610 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
611 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
612 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
613 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
614 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
616 Handle(Graphic3d_Camera) aCamera = Camera();
620 myCamStartOpUp = aCamera->Up();
621 myCamStartOpEye = aCamera->Eye();
622 myCamStartOpCenter = aCamera->Center();
625 aCamera->SetUp (myCamStartOpUp);
626 aCamera->SetEye (myCamStartOpEye);
627 aCamera->SetCenter (myCamStartOpCenter);
629 // rotate camera around 3 initial axes
630 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
631 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
632 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
633 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
635 gp_Trsf aRot[3], aTrsf;
636 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
637 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
638 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
639 aTrsf.Multiply (aRot[0]);
640 aTrsf.Multiply (aRot[1]);
641 aTrsf.Multiply (aRot[2]);
643 aCamera->Transform (aTrsf);
650 //=============================================================================
653 //=============================================================================
654 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
655 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
658 Standard_Real Ax = ax ;
659 Standard_Real Ay = ay ;
660 Standard_Real Az = az ;
662 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
663 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
664 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
665 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
666 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
667 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
669 Handle(Graphic3d_Camera) aCamera = Camera();
673 myGravityReferencePoint.SetCoord (X, Y, Z);
674 myCamStartOpUp = aCamera->Up();
675 myCamStartOpEye = aCamera->Eye();
676 myCamStartOpCenter = aCamera->Center();
679 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
681 aCamera->SetUp (myCamStartOpUp);
682 aCamera->SetEye (myCamStartOpEye);
683 aCamera->SetCenter (myCamStartOpCenter);
685 // rotate camera around 3 initial axes
686 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
688 gp_Dir aZAxis (aCamera->Direction().Reversed());
689 gp_Dir aYAxis (aCamera->Up());
690 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
692 gp_Trsf aRot[3], aTrsf;
693 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
694 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
695 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
696 aTrsf.Multiply (aRot[0]);
697 aTrsf.Multiply (aRot[1]);
698 aTrsf.Multiply (aRot[2]);
700 aCamera->Transform (aTrsf);
707 //=============================================================================
710 //=============================================================================
711 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
715 Rotate(angle,0.,0.,Start);
718 Rotate(0.,angle,0.,Start);
721 Rotate(0.,0.,angle,Start);
726 //=============================================================================
729 //=============================================================================
730 void V3d_View::Rotate (const V3d_TypeOfAxe theAxe, const Standard_Real theAngle,
731 const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ, const Standard_Boolean theStart)
733 Standard_Real anAngle = theAngle;
735 if (anAngle > 0.0) while (anAngle > DEUXPI) anAngle -= DEUXPI;
736 else if (anAngle < 0.0) while (anAngle < -DEUXPI) anAngle += DEUXPI;
738 Handle(Graphic3d_Camera) aCamera = Camera();
742 myGravityReferencePoint.SetCoord (theX, theY, theZ);
743 myCamStartOpUp = aCamera->Up();
744 myCamStartOpEye = aCamera->Eye();
745 myCamStartOpCenter = aCamera->Center();
749 case V3d_X: myViewAxis = gp::DX(); break;
750 case V3d_Y: myViewAxis = gp::DY(); break;
751 case V3d_Z: myViewAxis = gp::DZ(); break;
754 myCamStartOpUp = aCamera->Up();
755 myCamStartOpEye = aCamera->Eye();
756 myCamStartOpCenter = aCamera->Center();
759 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
761 aCamera->SetUp (myCamStartOpUp);
762 aCamera->SetEye (myCamStartOpEye);
763 aCamera->SetCenter (myCamStartOpCenter);
765 // rotate camera around passed axis
767 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
768 gp_Dir aRAxis ((theAxe == V3d_X) ? 1.0 : 0.0,
769 (theAxe == V3d_Y) ? 1.0 : 0.0,
770 (theAxe == V3d_Z) ? 1.0 : 0.0);
772 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), anAngle);
774 aCamera->Transform (aRotation);
781 //=============================================================================
784 //=============================================================================
785 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
787 Standard_Real Angle = angle;
789 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
790 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
792 Handle(Graphic3d_Camera) aCamera = Camera();
795 myCamStartOpUp = aCamera->Up();
796 myCamStartOpEye = aCamera->Eye();
797 myCamStartOpCenter = aCamera->Center();
800 aCamera->SetUp (myCamStartOpUp);
801 aCamera->SetEye (myCamStartOpEye);
802 aCamera->SetCenter (myCamStartOpCenter);
805 gp_Pnt aRCenter (myDefaultViewPoint);
806 gp_Dir aRAxis (myDefaultViewAxis);
807 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
809 aCamera->Transform (aRotation);
816 //=============================================================================
819 //=============================================================================
820 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
822 Standard_Real Ax = ax;
823 Standard_Real Ay = ay;
824 Standard_Real Az = az;
826 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
827 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
828 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
829 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
830 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
831 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
833 Handle(Graphic3d_Camera) aCamera = Camera();
836 myCamStartOpUp = aCamera->Up();
837 myCamStartOpEye = aCamera->Eye();
838 myCamStartOpCenter = aCamera->Center();
841 aCamera->SetUp (myCamStartOpUp);
842 aCamera->SetEye (myCamStartOpEye);
843 aCamera->SetCenter (myCamStartOpCenter);
845 // rotate camera around 3 initial axes
846 gp_Pnt aRCenter = aCamera->Eye();
847 gp_Dir aZAxis (aCamera->Direction().Reversed());
848 gp_Dir aYAxis (aCamera->Up());
849 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
851 gp_Trsf aRot[3], aTrsf;
852 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
853 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
854 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
855 aTrsf.Multiply (aRot[0]);
856 aTrsf.Multiply (aRot[1]);
857 aTrsf.Multiply (aRot[2]);
859 aCamera->Transform (aTrsf);
866 //=============================================================================
869 //=============================================================================
870 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
874 Turn(angle,0.,0.,Start);
877 Turn(0.,angle,0.,Start);
880 Turn(0.,0.,angle,Start);
885 //=============================================================================
888 //=============================================================================
889 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
891 Standard_Real Angle = angle ;
893 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
894 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
896 Handle(Graphic3d_Camera) aCamera = Camera();
899 myCamStartOpUp = aCamera->Up();
900 myCamStartOpEye = aCamera->Eye();
901 myCamStartOpCenter = aCamera->Center();
904 aCamera->SetUp (myCamStartOpUp);
905 aCamera->SetEye (myCamStartOpEye);
906 aCamera->SetCenter (myCamStartOpCenter);
909 gp_Pnt aRCenter = aCamera->Eye();
910 gp_Dir aRAxis (myDefaultViewAxis);
911 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
913 aCamera->Transform (aRotation);
920 //=============================================================================
921 //function : SetTwist
923 //=============================================================================
924 void V3d_View::SetTwist(const Standard_Real angle)
926 Standard_Real Angle = angle ;
928 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
929 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
931 Handle(Graphic3d_Camera) aCamera = Camera();
933 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
934 if (!screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
935 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
936 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
938 throw V3d_BadValue ("V3d_ViewSetTwist, alignment of Eye,At,Up,");
941 gp_Pnt aRCenter = aCamera->Center();
942 gp_Dir aZAxis (aCamera->Direction().Reversed());
945 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
947 aCamera->SetUp (gp_Dir (myYscreenAxis));
948 aCamera->Transform (aTrsf);
955 //=============================================================================
958 //=============================================================================
959 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
961 Standard_Real aTwistBefore = Twist();
963 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
965 Handle(Graphic3d_Camera) aCamera = Camera();
967 aCamera->SetEye (gp_Pnt (X, Y, Z));
969 SetTwist (aTwistBefore);
973 SetImmediateUpdate (wasUpdateEnabled);
978 //=============================================================================
979 //function : SetDepth
981 //=============================================================================
982 void V3d_View::SetDepth(const Standard_Real Depth)
984 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
986 Handle(Graphic3d_Camera) aCamera = Camera();
990 // Move eye using center (target) as anchor.
991 aCamera->SetDistance (Depth);
995 // Move the view ref point instead of the eye.
996 gp_Vec aDir (aCamera->Direction());
997 gp_Pnt aCameraEye = aCamera->Eye();
998 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1000 aCamera->SetCenter (aCameraCenter);
1008 //=============================================================================
1009 //function : SetProj
1011 //=============================================================================
1012 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1014 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1015 "V3d_View::SetProj, null projection vector");
1017 Standard_Real aTwistBefore = Twist();
1019 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1021 Camera()->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1023 SetTwist(aTwistBefore);
1027 SetImmediateUpdate (wasUpdateEnabled);
1032 //=============================================================================
1033 //function : SetProj
1035 //=============================================================================
1036 void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1038 Standard_Real Xpn=0;
1039 Standard_Real Ypn=0;
1040 Standard_Real Zpn=0;
1042 switch (Orientation) {
1053 const gp_Dir aBck = V3d::GetProjAxis (Orientation);
1055 // retain camera panning from origin when switching projection
1056 Handle(Graphic3d_Camera) aCamera = Camera();
1058 gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
1059 Standard_Real aPanX = anOriginVCS.X();
1060 Standard_Real aPanY = anOriginVCS.Y();
1062 aCamera->SetCenter (gp_Pnt (0, 0, 0));
1063 aCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1064 aCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
1065 aCamera->OrthogonalizeUp();
1067 Panning (aPanX, aPanY);
1074 //=============================================================================
1077 //=============================================================================
1078 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1080 Standard_Real aTwistBefore = Twist();
1082 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1084 Camera()->SetCenter (gp_Pnt (X, Y, Z));
1086 SetTwist (aTwistBefore);
1090 SetImmediateUpdate (wasUpdateEnabled);
1095 //=============================================================================
1098 //=============================================================================
1099 void V3d_View::SetUp (const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
1101 Handle(Graphic3d_Camera) aCamera = Camera();
1103 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1104 const gp_Dir anUp (theVx, theVy, theVz);
1105 if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis)
1106 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1107 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1108 && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1110 throw V3d_BadValue ("V3d_View::Setup, alignment of Eye,At,Up");
1113 aCamera->SetUp (gp_Dir (myYscreenAxis));
1120 //=============================================================================
1123 //=============================================================================
1124 void V3d_View::SetUp (const V3d_TypeOfOrientation theOrientation)
1126 Handle(Graphic3d_Camera) aCamera = Camera();
1128 const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1129 const gp_Dir anUp = V3d::GetProjAxis (theOrientation);
1130 if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis)
1131 && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1132 && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1133 && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1135 throw V3d_BadValue ("V3d_View::SetUp, alignment of Eye,At,Up");
1138 aCamera->SetUp (gp_Dir (myYscreenAxis));
1145 //=============================================================================
1146 //function : SetViewOrientationDefault
1148 //=============================================================================
1149 void V3d_View::SetViewOrientationDefault()
1151 myDefaultCamera->CopyOrientationData (Camera());
1154 //=======================================================================
1155 //function : SetViewMappingDefault
1157 //=======================================================================
1158 void V3d_View::SetViewMappingDefault()
1160 myDefaultCamera->CopyMappingData (Camera());
1163 //=============================================================================
1164 //function : ResetViewOrientation
1166 //=============================================================================
1167 void V3d_View::ResetViewOrientation()
1169 Camera()->CopyOrientationData (myDefaultCamera);
1176 //=======================================================================
1177 //function : ResetViewMapping
1179 //=======================================================================
1180 void V3d_View::ResetViewMapping()
1182 Camera()->CopyMappingData (myDefaultCamera);
1189 //=============================================================================
1192 //=============================================================================
1193 void V3d_View::Reset (const Standard_Boolean theToUpdate)
1195 Camera()->Copy (myDefaultCamera);
1199 SwitchSetFront = Standard_False;
1201 if (myImmediateUpdate || theToUpdate)
1207 //=======================================================================
1208 //function : SetCenter
1210 //=======================================================================
1211 void V3d_View::SetCenter (const Standard_Integer theXp,
1212 const Standard_Integer theYp)
1214 Standard_Real aXv, aYv;
1215 Convert (theXp, theYp, aXv, aYv);
1216 Translate (Camera(), aXv, aYv);
1221 //=============================================================================
1222 //function : SetSize
1224 //=============================================================================
1225 void V3d_View::SetSize (const Standard_Real theSize)
1227 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1229 Handle(Graphic3d_Camera) aCamera = Camera();
1231 aCamera->SetScale (aCamera->Aspect() >= 1.0 ? theSize / aCamera->Aspect() : theSize);
1238 //=============================================================================
1239 //function : SetZSize
1241 //=============================================================================
1242 void V3d_View::SetZSize (const Standard_Real theSize)
1244 Handle(Graphic3d_Camera) aCamera = Camera();
1246 Standard_Real Zmax = theSize / 2.;
1248 Standard_Real aDistance = aCamera->Distance();
1255 // ShortReal precision factor used to add meaningful tolerance to
1256 // ZNear, ZFar values in order to avoid equality after type conversion
1257 // to ShortReal matrices type.
1258 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1260 Standard_Real aZFar = Zmax + aDistance * 2.0;
1261 Standard_Real aZNear = -Zmax + aDistance;
1262 aZNear -= Abs (aZNear) * aPrecision;
1263 aZFar += Abs (aZFar) * aPrecision;
1265 if (!aCamera->IsOrthographic())
1267 if (aZFar < aPrecision)
1269 // Invalid case when both values are negative
1270 aZNear = aPrecision;
1271 aZFar = aPrecision * 2.0;
1273 else if (aZNear < Abs (aZFar) * aPrecision)
1275 // Z is less than 0.0, try to fix it using any appropriate z-scale
1276 aZNear = Abs (aZFar) * aPrecision;
1280 // If range is too small
1281 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1283 aZFar = aZNear + Abs (aZFar) * aPrecision;
1286 aCamera->SetZRange (aZNear, aZFar);
1288 if (myImmediateUpdate)
1294 //=============================================================================
1295 //function : SetZoom
1297 //=============================================================================
1298 void V3d_View::SetZoom (const Standard_Real theCoef,const Standard_Boolean theToStart)
1300 V3d_BadValue_Raise_if (theCoef <= 0., "V3d_View::SetZoom, bad coefficient");
1302 Handle(Graphic3d_Camera) aCamera = Camera();
1306 myCamStartOpEye = aCamera->Eye();
1307 myCamStartOpCenter = aCamera->Center();
1310 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
1311 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
1313 // ensure that zoom will not be too small or too big
1314 Standard_Real aCoef = theCoef;
1315 if (aViewWidth < aCoef * Precision::Confusion())
1317 aCoef = aViewWidth / Precision::Confusion();
1319 else if (aViewWidth > aCoef * 1e12)
1321 aCoef = aViewWidth / 1e12;
1323 if (aViewHeight < aCoef * Precision::Confusion())
1325 aCoef = aViewHeight / Precision::Confusion();
1327 else if (aViewHeight > aCoef * 1e12)
1329 aCoef = aViewHeight / 1e12;
1332 aCamera->SetEye (myCamStartOpEye);
1333 aCamera->SetCenter (myCamStartOpCenter);
1334 aCamera->SetScale (aCamera->Scale() / aCoef);
1341 //=============================================================================
1342 //function : SetScale
1344 //=============================================================================
1345 void V3d_View::SetScale( const Standard_Real Coef )
1347 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1349 Handle(Graphic3d_Camera) aCamera = Camera();
1351 Standard_Real aDefaultScale = myDefaultCamera->Scale();
1352 aCamera->SetAspect (myDefaultCamera->Aspect());
1353 aCamera->SetScale (aDefaultScale / Coef);
1360 //=============================================================================
1361 //function : SetAxialScale
1363 //=============================================================================
1364 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1366 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1368 Camera()->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1373 //=============================================================================
1374 //function : SetRatio
1376 //=============================================================================
1377 void V3d_View::SetRatio()
1379 if (MyWindow.IsNull())
1384 Standard_Integer aWidth = 0;
1385 Standard_Integer aHeight = 0;
1386 MyWindow->Size (aWidth, aHeight);
1387 if (aWidth > 0 && aHeight > 0)
1389 Standard_Real aRatio = static_cast<Standard_Real> (aWidth) /
1390 static_cast<Standard_Real> (aHeight);
1392 Camera() ->SetAspect (aRatio);
1393 myDefaultCamera->SetAspect (aRatio);
1397 //=============================================================================
1400 //=============================================================================
1401 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1403 FitAll (myView->MinMaxValues(), theMargin, theToUpdate);
1406 //=============================================================================
1409 //=============================================================================
1410 void V3d_View::FitAll (const Bnd_Box& theBox, const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1412 Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1414 if (myView->NumberOfDisplayedStructures() == 0)
1419 if (!FitMinMax (Camera(), theBox, theMargin, 10.0 * Precision::Confusion()))
1426 if (myImmediateUpdate || theToUpdate)
1432 //=============================================================================
1433 //function : DepthFitAll
1435 //=============================================================================
1436 void V3d_View::DepthFitAll(const Standard_Real Aspect,
1437 const Standard_Real Margin)
1439 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1440 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1441 Standard_Real Dx,Dy,Dz,Size;
1443 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1445 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1450 Bnd_Box aBox = myView->MinMaxValues();
1456 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1457 Project (Xmin,Ymin,Zmin,U,V,W) ;
1458 Project (Xmax,Ymax,Zmax,U1,V1,W1) ;
1459 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1460 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1461 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1462 Project (Xmin,Ymin,Zmax,U,V,W) ;
1463 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1464 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1465 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1466 Project (Xmax,Ymin,Zmax,U,V,W) ;
1467 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1468 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1469 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1470 Project (Xmax,Ymin,Zmin,U,V,W) ;
1471 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1472 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1473 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1474 Project (Xmax,Ymax,Zmin,U,V,W) ;
1475 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1476 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1477 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1478 Project (Xmin,Ymax,Zmax,U,V,W) ;
1479 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1480 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1481 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1482 Project (Xmin,Ymax,Zmin,U,V,W) ;
1483 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1484 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1485 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1488 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1489 Dz = 2.*Wmax + Margin * Wmax;
1491 // Compute depth value
1492 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1493 Dx += Margin * Dx; Dy += Margin * Dy;
1494 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1497 SetDepth( Aspect * Size / 2.);
1503 //=============================================================================
1504 //function : WindowFitAll
1506 //=============================================================================
1507 void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1508 const Standard_Integer Ymin,
1509 const Standard_Integer Xmax,
1510 const Standard_Integer Ymax)
1512 WindowFit(Xmin,Ymin,Xmax,Ymax);
1515 //=======================================================================
1516 //function : WindowFit
1518 //=======================================================================
1519 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1520 const Standard_Integer theMinYp,
1521 const Standard_Integer theMaxXp,
1522 const Standard_Integer theMaxYp)
1524 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1526 Handle(Graphic3d_Camera) aCamera = Camera();
1528 if (!aCamera->IsOrthographic())
1530 // normalize view coordinates
1531 Standard_Integer aWinWidth, aWinHeight;
1532 MyWindow->Size (aWinWidth, aWinHeight);
1534 // z coordinate of camera center
1535 Standard_Real aDepth = aCamera->Project (aCamera->Center()).Z();
1537 // camera projection coordinate are in NDC which are normalized [-1, 1]
1538 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1539 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1540 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1541 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1543 // compute camera panning
1544 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1545 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1546 gp_Pnt aPanTo = aCamera->ConvertProj2View (aFitCenter);
1547 gp_Pnt aPanFrom = aCamera->ConvertProj2View (aScreenCenter);
1548 gp_Vec aPanVec (aPanFrom, aPanTo);
1550 // compute section size
1551 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1552 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1553 gp_Pnt aViewBotLeft = aCamera->ConvertProj2View (aFitBotLeft);
1554 gp_Pnt aViewTopRight = aCamera->ConvertProj2View (aFitTopRight);
1556 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1557 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1559 Translate (aCamera, aPanVec.X(), -aPanVec.Y());
1560 Scale (aCamera, aUSize, aVSize);
1565 Standard_Real aX1, aY1, aX2, aY2;
1566 Convert (theMinXp, theMinYp, aX1, aY1);
1567 Convert (theMaxXp, theMaxYp, aX2, aY2);
1568 FitAll (aX1, aY1, aX2, aY2);
1571 SetImmediateUpdate (wasUpdateEnabled);
1576 //=======================================================================
1577 //function : ConvertToGrid
1579 //=======================================================================
1580 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1581 const Standard_Integer Yp,
1584 Standard_Real& Zg) const
1586 Graphic3d_Vertex aVrp;
1587 Standard_Real anX, anY, aZ;
1588 Convert (Xp, Yp, anX, anY, aZ);
1589 aVrp.SetCoord (anX, anY, aZ);
1591 if( MyViewer->Grid()->IsActive() ) {
1592 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1593 aNewVrp.Coord (Xg,Yg,Zg) ;
1595 aVrp.Coord (Xg,Yg,Zg) ;
1598 //=======================================================================
1599 //function : ConvertToGrid
1601 //=======================================================================
1602 void V3d_View::ConvertToGrid(const Standard_Real X,
1603 const Standard_Real Y,
1604 const Standard_Real Z,
1607 Standard_Real& Zg) const
1609 if( MyViewer->Grid()->IsActive() ) {
1610 Graphic3d_Vertex aVrp (X,Y,Z) ;
1611 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1612 aNewVrp.Coord(Xg,Yg,Zg) ;
1614 Xg = X; Yg = Y; Zg = Z;
1618 //=======================================================================
1619 //function : Convert
1621 //=======================================================================
1622 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1624 Standard_Integer aDxw, aDyw ;
1626 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1628 MyWindow->Size (aDxw, aDyw);
1629 Standard_Real aValue;
1631 gp_Pnt aViewDims = Camera()->ViewDimensions();
1632 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1637 //=======================================================================
1638 //function : Convert
1640 //=======================================================================
1641 void V3d_View::Convert(const Standard_Integer Xp,
1642 const Standard_Integer Yp,
1644 Standard_Real& Yv) const
1646 Standard_Integer aDxw, aDyw;
1648 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1650 MyWindow->Size (aDxw, aDyw);
1652 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1653 aPoint = Camera()->ConvertProj2View (aPoint);
1659 //=======================================================================
1660 //function : Convert
1662 //=======================================================================
1663 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1665 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1667 Standard_Integer aDxw, aDyw;
1668 MyWindow->Size (aDxw, aDyw);
1670 gp_Pnt aViewDims = Camera()->ViewDimensions();
1671 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1676 //=======================================================================
1677 //function : Convert
1679 //=======================================================================
1680 void V3d_View::Convert(const Standard_Real Xv,
1681 const Standard_Real Yv,
1682 Standard_Integer& Xp,
1683 Standard_Integer& Yp) const
1685 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1687 Standard_Integer aDxw, aDyw;
1688 MyWindow->Size (aDxw, aDyw);
1690 gp_Pnt aPoint (Xv, Yv, 0.0);
1691 aPoint = Camera()->ConvertView2Proj (aPoint);
1692 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1694 Xp = RealToInt (aPoint.X());
1695 Yp = RealToInt (aPoint.Y());
1698 //=======================================================================
1699 //function : Convert
1701 //=======================================================================
1702 void V3d_View::Convert(const Standard_Integer Xp,
1703 const Standard_Integer Yp,
1706 Standard_Real& Z) const
1708 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1709 Standard_Integer aHeight, aWidth;
1710 MyWindow->Size (aWidth, aHeight);
1712 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1713 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1714 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1716 gp_Pnt aResult = Camera()->UnProject (gp_Pnt (anX, anY, aZ));
1723 //=======================================================================
1724 //function : ConvertWithProj
1726 //=======================================================================
1727 void V3d_View::ConvertWithProj(const Standard_Integer theXp,
1728 const Standard_Integer theYp,
1729 Standard_Real& theX,
1730 Standard_Real& theY,
1731 Standard_Real& theZ,
1732 Standard_Real& theDx,
1733 Standard_Real& theDy,
1734 Standard_Real& theDz) const
1736 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1737 Standard_Integer aHeight = 0, aWidth = 0;
1738 MyWindow->Size (aWidth, aHeight);
1740 const Standard_Real anX = 2.0 * theXp / aWidth - 1.0;
1741 const Standard_Real anY = 2.0 * (aHeight - 1 - theYp) / aHeight - 1.0;
1742 const Standard_Real aZ = 2.0 * 0.0 - 1.0;
1744 const Handle(Graphic3d_Camera)& aCamera = Camera();
1745 const gp_Pnt aResult1 = aCamera->UnProject (gp_Pnt (anX, anY, aZ));
1746 const gp_Pnt aResult2 = aCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1748 theX = aResult1.X();
1749 theY = aResult1.Y();
1750 theZ = aResult1.Z();
1751 Graphic3d_Vec3d aNormDir (theX - aResult2.X(),
1752 theY - aResult2.Y(),
1753 theZ - aResult2.Z());
1754 aNormDir.Normalize();
1756 theDx = aNormDir.x();
1757 theDy = aNormDir.y();
1758 theDz = aNormDir.z();
1761 //=======================================================================
1762 //function : Convert
1764 //=======================================================================
1765 void V3d_View::Convert(const Standard_Real X,
1766 const Standard_Real Y,
1767 const Standard_Real Z,
1768 Standard_Integer& Xp,
1769 Standard_Integer& Yp) const
1771 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1772 Standard_Integer aHeight, aWidth;
1773 MyWindow->Size (aWidth, aHeight);
1775 gp_Pnt aPoint = Camera()->Project (gp_Pnt (X, Y, Z));
1777 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1778 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1781 //=======================================================================
1782 //function : Project
1784 //=======================================================================
1785 void V3d_View::Project (const Standard_Real theX,
1786 const Standard_Real theY,
1787 const Standard_Real theZ,
1788 Standard_Real& theXp,
1789 Standard_Real& theYp) const
1792 Project (theX, theY, theZ, theXp, theYp, aZp);
1795 //=======================================================================
1796 //function : Project
1798 //=======================================================================
1799 void V3d_View::Project (const Standard_Real theX,
1800 const Standard_Real theY,
1801 const Standard_Real theZ,
1802 Standard_Real& theXp,
1803 Standard_Real& theYp,
1804 Standard_Real& theZp) const
1806 Handle(Graphic3d_Camera) aCamera = Camera();
1808 gp_XYZ aViewSpaceDimensions = aCamera->ViewDimensions();
1809 Standard_Real aXSize = aViewSpaceDimensions.X();
1810 Standard_Real aYSize = aViewSpaceDimensions.Y();
1811 Standard_Real aZSize = aViewSpaceDimensions.Z();
1813 gp_Pnt aPoint = aCamera->Project (gp_Pnt (theX, theY, theZ));
1815 // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
1816 theXp = aPoint.X() * aXSize * 0.5;
1817 theYp = aPoint.Y() * aYSize * 0.5;
1818 theZp = aPoint.Z() * aZSize * 0.5;
1821 //=======================================================================
1822 //function : BackgroundColor
1824 //=======================================================================
1825 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1828 Standard_Real& V3) const
1830 Quantity_Color C = BackgroundColor() ;
1831 C.Values(V1,V2,V3,Type) ;
1834 //=======================================================================
1835 //function : BackgroundColor
1837 //=======================================================================
1838 Quantity_Color V3d_View::BackgroundColor() const
1840 return myView->Background().Color() ;
1843 //=======================================================================
1844 //function : GradientBackgroundColors
1846 //=======================================================================
1847 void V3d_View::GradientBackgroundColors (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1849 myView->GradientBackground().Colors (theColor1, theColor2);
1852 //=======================================================================
1853 //function : GradientBackground
1855 //=======================================================================
1856 Aspect_GradientBackground V3d_View::GradientBackground() const
1858 return myView->GradientBackground();
1861 //=======================================================================
1864 //=======================================================================
1865 Standard_Real V3d_View::Scale() const
1867 return myDefaultCamera->Scale() / Camera()->Scale();
1870 //=======================================================================
1871 //function : AxialScale
1873 //=======================================================================
1874 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1876 gp_Pnt anAxialScale = Camera()->AxialScale();
1877 Sx = anAxialScale.X();
1878 Sy = anAxialScale.Y();
1879 Sz = anAxialScale.Z();
1882 //=======================================================================
1885 //=======================================================================
1886 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1888 gp_Pnt aViewDims = Camera()->ViewDimensions();
1890 Width = aViewDims.X();
1891 Height = aViewDims.Y();
1894 //=======================================================================
1897 //=======================================================================
1898 Standard_Real V3d_View::ZSize() const
1900 gp_Pnt aViewDims = Camera()->ViewDimensions();
1902 return aViewDims.Z();
1905 //=======================================================================
1908 //=======================================================================
1909 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
1910 Standard_Real& Vmin,
1911 Standard_Real& Umax,
1912 Standard_Real& Vmax) const
1914 Standard_Real Wmin,Wmax,U,V,W ;
1915 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
1917 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1920 Bnd_Box aBox = myView->MinMaxValues();
1921 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1922 Project (Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
1923 Project (Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
1924 Project (Xmin,Ymin,Zmax,U,V,W) ;
1925 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1926 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1927 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1928 Project (Xmax,Ymin,Zmax,U,V,W) ;
1929 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1930 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1931 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1932 Project (Xmax,Ymin,Zmin,U,V,W) ;
1933 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1934 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1935 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1936 Project (Xmax,Ymax,Zmin,U,V,W) ;
1937 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1938 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1939 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1940 Project (Xmin,Ymax,Zmax,U,V,W) ;
1941 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1942 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1943 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1944 Project (Xmin,Ymax,Zmin,U,V,W) ;
1945 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1946 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1947 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1952 //=======================================================================
1955 //=======================================================================
1956 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
1957 Standard_Real& Ymin,
1958 Standard_Real& Zmin,
1959 Standard_Real& Xmax,
1960 Standard_Real& Ymax,
1961 Standard_Real& Zmax) const
1964 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
1965 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1968 Bnd_Box aBox = myView->MinMaxValues();
1969 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1974 //=======================================================================
1975 //function : Gravity
1977 //=======================================================================
1978 void V3d_View::Gravity (Standard_Real& theX,
1979 Standard_Real& theY,
1980 Standard_Real& theZ) const
1982 Graphic3d_MapOfStructure aSetOfStructures;
1983 myView->DisplayedStructures (aSetOfStructures);
1985 Standard_Boolean hasSelection = Standard_False;
1986 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
1987 aStructIter.More(); aStructIter.Next())
1989 if (aStructIter.Key()->IsHighlighted()
1990 && aStructIter.Key()->IsVisible())
1992 hasSelection = Standard_True;
1997 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
1998 Standard_Integer aNbPoints = 0;
1999 gp_XYZ aResult (0.0, 0.0, 0.0);
2000 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2001 aStructIter.More(); aStructIter.Next())
2003 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2004 if (!aStruct->IsVisible()
2005 || aStruct->IsInfinite()
2006 || (hasSelection && !aStruct->IsHighlighted()))
2011 const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox();
2012 if (!aBox.IsValid())
2017 // skip transformation-persistent objects
2018 if (!aStruct->TransformPersistence().IsNull())
2023 // use camera projection to find gravity point
2024 Xmin = aBox.CornerMin().x();
2025 Ymin = aBox.CornerMin().y();
2026 Zmin = aBox.CornerMin().z();
2027 Xmax = aBox.CornerMax().x();
2028 Ymax = aBox.CornerMax().y();
2029 Zmax = aBox.CornerMax().z();
2030 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2032 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2033 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2034 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2035 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2038 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2040 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2041 const gp_Pnt aProjected = Camera()->Project (aBndPnt);
2042 if (Abs (aProjected.X()) <= 1.0
2043 && Abs (aProjected.Y()) <= 1.0)
2045 aResult += aBndPnt.XYZ();
2053 // fallback - just use bounding box of entire scene
2054 Bnd_Box aBox = myView->MinMaxValues();
2057 aBox.Get (Xmin, Ymin, Zmin,
2059 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2061 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2062 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2063 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2064 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2067 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2069 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2070 aResult += aBndPnt.XYZ();
2078 aResult /= aNbPoints;
2085 //=======================================================================
2088 //=======================================================================
2089 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2091 gp_Pnt aCameraEye = Camera()->Eye();
2097 //=============================================================================
2098 //function : FocalReferencePoint
2100 //=============================================================================
2101 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2106 //=============================================================================
2107 //function : ProjReferenceAxe
2109 //=============================================================================
2110 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2111 const Standard_Integer Ypix,
2117 Standard_Real& VZ) const
2119 Standard_Real Xo,Yo,Zo;
2121 Convert (Xpix, Ypix, XP, YP, ZP);
2122 if ( Type() == V3d_PERSPECTIVE )
2124 FocalReferencePoint (Xo,Yo,Zo);
2135 //=============================================================================
2138 //=============================================================================
2139 Standard_Real V3d_View::Depth() const
2141 return Camera()->Distance();
2144 //=============================================================================
2147 //=============================================================================
2148 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2150 gp_Dir aCameraDir = Camera()->Direction().Reversed();
2151 Dx = aCameraDir.X();
2152 Dy = aCameraDir.Y();
2153 Dz = aCameraDir.Z();
2156 //=============================================================================
2159 //=============================================================================
2160 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2162 gp_Pnt aCameraCenter = Camera()->Center();
2163 X = aCameraCenter.X();
2164 Y = aCameraCenter.Y();
2165 Z = aCameraCenter.Z();
2168 //=============================================================================
2171 //=============================================================================
2172 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2174 gp_Dir aCameraUp = Camera()->Up();
2180 //=============================================================================
2183 //=============================================================================
2184 Standard_Real V3d_View::Twist() const
2186 gp_Vec Xaxis, Yaxis, Zaxis;
2187 const gp_Dir aReferencePlane (Camera()->Direction().Reversed());
2188 if (!screenAxis (aReferencePlane, gp::DZ(), Xaxis, Yaxis, Zaxis)
2189 && !screenAxis (aReferencePlane, gp::DY(), Xaxis, Yaxis, Zaxis)
2190 && !screenAxis (aReferencePlane, gp::DX(), Xaxis, Yaxis, Zaxis))
2195 // Compute Cross Vector From Up & Origin
2196 const gp_Dir aCameraUp = Camera()->Up();
2197 const gp_XYZ aP = Yaxis.XYZ().Crossed (aCameraUp.XYZ());
2200 Standard_Real anAngle = ASin (Max (Min (aP.Modulus(), 1.0), -1.0));
2201 if (Yaxis.Dot (aCameraUp.XYZ()) < 0.0)
2203 anAngle = M_PI - anAngle;
2208 const gp_Dir aProjDir = Camera()->Direction().Reversed();
2209 if (aP.Dot (aProjDir.XYZ()) < 0.0)
2211 anAngle = DEUXPI - anAngle;
2217 //=============================================================================
2218 //function : ShadingModel
2220 //=============================================================================
2221 Graphic3d_TypeOfShadingModel V3d_View::ShadingModel() const
2223 return myView->ShadingModel();
2226 //=============================================================================
2227 //function : TextureEnv
2229 //=============================================================================
2230 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2232 return myView->TextureEnv();
2235 //=============================================================================
2236 //function : Visualization
2238 //=============================================================================
2239 V3d_TypeOfVisualization V3d_View::Visualization() const
2241 return static_cast<V3d_TypeOfVisualization> (myView->VisualizationType());
2244 //=============================================================================
2247 //=============================================================================
2248 Handle(V3d_Viewer) V3d_View::Viewer() const
2253 //=============================================================================
2254 //function : IfWindow
2256 //=============================================================================
2257 Standard_Boolean V3d_View::IfWindow() const
2259 return myView->IsDefined();
2262 //=============================================================================
2265 //=============================================================================
2266 Handle(Aspect_Window) V3d_View::Window() const
2271 //=============================================================================
2274 //=============================================================================
2275 V3d_TypeOfView V3d_View::Type() const
2277 return Camera()->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2280 //=============================================================================
2281 //function : SetFocale
2283 //=============================================================================
2284 void V3d_View::SetFocale( const Standard_Real focale )
2286 Handle(Graphic3d_Camera) aCamera = Camera();
2288 if (aCamera->IsOrthographic())
2293 Standard_Real aFOVyRad = ATan (focale / (aCamera->Distance() * 2.0));
2295 aCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2300 //=============================================================================
2303 //=============================================================================
2304 Standard_Real V3d_View::Focale() const
2306 Handle(Graphic3d_Camera) aCamera = Camera();
2308 if (aCamera->IsOrthographic())
2313 return aCamera->Distance() * 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
2316 //=============================================================================
2319 //=============================================================================
2320 Handle(Graphic3d_CView) V3d_View::View() const
2325 //=============================================================================
2326 //function : screenAxis
2328 //=============================================================================
2329 Standard_Boolean V3d_View::screenAxis (const gp_Dir& theVpn, const gp_Dir& theVup,
2330 gp_Vec& theXaxe, gp_Vec& theYaxe, gp_Vec& theZaxe)
2332 theXaxe = theVup.XYZ().Crossed (theVpn.XYZ());
2333 if (theXaxe.Magnitude() <= gp::Resolution())
2335 return Standard_False;
2337 theXaxe.Normalize();
2339 theYaxe = theVpn.XYZ().Crossed (theXaxe.XYZ());
2340 if (theYaxe.Magnitude() <= gp::Resolution())
2342 return Standard_False;
2344 theYaxe.Normalize();
2346 theZaxe = theVpn.XYZ();
2347 theZaxe.Normalize();
2348 return Standard_True;
2351 //=============================================================================
2352 //function : TrsPoint
2354 //=============================================================================
2355 gp_XYZ V3d_View::TrsPoint (const Graphic3d_Vertex& thePnt, const TColStd_Array2OfReal& theMat)
2358 const Standard_Integer lr = theMat.LowerRow();
2359 const Standard_Integer ur = theMat.UpperRow();
2360 const Standard_Integer lc = theMat.LowerCol();
2361 const Standard_Integer uc = theMat.UpperCol();
2362 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4))
2364 return gp_XYZ (thePnt.X(), thePnt.Y(), thePnt.Z());
2367 Standard_Real X, Y, Z;
2368 thePnt.Coord (X,Y,Z);
2369 const Standard_Real XX = (theMat(lr,lc+3) + X*theMat(lr,lc) + Y*theMat(lr,lc+1) + Z*theMat(lr,lc+2)) / theMat(lr+3,lc+3);
2370 const Standard_Real YY = (theMat(lr+1,lc+3) + X*theMat(lr+1,lc) + Y*theMat(lr+1,lc+1) + Z*theMat(lr+1,lc+2))/theMat(lr+3,lc+3);
2371 const Standard_Real ZZ = (theMat(lr+2,lc+3) + X*theMat(lr+2,lc) + Y*theMat(lr+2,lc+1) + Z*theMat(lr+2,lc+2))/theMat(lr+3,lc+3);
2372 return gp_XYZ (XX, YY, ZZ);
2375 //=======================================================================
2378 //=======================================================================
2379 void V3d_View::Pan (const Standard_Integer theDXp,
2380 const Standard_Integer theDYp,
2381 const Standard_Real theZoomFactor,
2382 const Standard_Boolean theToStart)
2384 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2387 //=======================================================================
2388 //function : Panning
2390 //=======================================================================
2391 void V3d_View::Panning (const Standard_Real theDXv,
2392 const Standard_Real theDYv,
2393 const Standard_Real theZoomFactor,
2394 const Standard_Boolean theToStart)
2396 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2398 Handle(Graphic3d_Camera) aCamera = Camera();
2402 myCamStartOpEye = aCamera->Eye();
2403 myCamStartOpCenter = aCamera->Center();
2406 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2408 gp_Pnt aViewDims = aCamera->ViewDimensions();
2410 aCamera->SetEye (myCamStartOpEye);
2411 aCamera->SetCenter (myCamStartOpCenter);
2412 Translate (aCamera, -theDXv, -theDYv);
2413 Scale (aCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2415 SetImmediateUpdate (wasUpdateEnabled);
2420 //=======================================================================
2423 //=======================================================================
2424 void V3d_View::Zoom (const Standard_Integer theXp1,
2425 const Standard_Integer theYp1,
2426 const Standard_Integer theXp2,
2427 const Standard_Integer theYp2)
2429 Standard_Integer aDx = theXp2 - theXp1;
2430 Standard_Integer aDy = theYp2 - theYp1;
2431 if (aDx != 0 || aDy != 0)
2433 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2434 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2435 SetZoom (aCoeff, Standard_True);
2439 //=======================================================================
2440 //function : StartZoomAtPoint
2442 //=======================================================================
2443 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2444 const Standard_Integer theYp)
2446 MyZoomAtPointX = theXp;
2447 MyZoomAtPointY = theYp;
2450 //=======================================================================
2451 //function : ZoomAtPoint
2453 //=======================================================================
2454 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2455 const Standard_Integer theMouseStartY,
2456 const Standard_Integer theMouseEndX,
2457 const Standard_Integer theMouseEndY)
2459 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2462 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2463 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2464 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2466 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2468 Handle(Graphic3d_Camera) aCamera = Camera();
2470 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
2471 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
2473 // ensure that zoom will not be too small or too big.
2474 Standard_Real aCoef = aDZoom;
2475 if (aViewWidth < aCoef * Precision::Confusion())
2477 aCoef = aViewWidth / Precision::Confusion();
2479 else if (aViewWidth > aCoef * 1e12)
2481 aCoef = aViewWidth / 1e12;
2483 if (aViewHeight < aCoef * Precision::Confusion())
2485 aCoef = aViewHeight / Precision::Confusion();
2487 else if (aViewHeight > aCoef * 1e12)
2489 aCoef = aViewHeight / 1e12;
2492 Standard_Real aZoomAtPointXv = 0.0;
2493 Standard_Real aZoomAtPointYv = 0.0;
2494 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2496 Standard_Real aDxv = aZoomAtPointXv / aCoef;
2497 Standard_Real aDyv = aZoomAtPointYv / aCoef;
2499 aCamera->SetScale (aCamera->Scale() / aCoef);
2500 Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2504 SetImmediateUpdate (wasUpdateEnabled);
2509 //=============================================================================
2510 //function : AxialScale
2512 //=============================================================================
2513 void V3d_View::AxialScale (const Standard_Integer Dx,
2514 const Standard_Integer Dy,
2515 const V3d_TypeOfAxe Axis)
2517 if( Dx != 0. || Dy != 0. ) {
2518 Standard_Real Sx, Sy, Sz;
2519 AxialScale( Sx, Sy, Sz );
2520 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2521 dscale = (Dx > 0) ? dscale : 1./dscale;
2522 if( Axis == V3d_X ) Sx = dscale;
2523 if( Axis == V3d_Y ) Sy = dscale;
2524 if( Axis == V3d_Z ) Sz = dscale;
2525 SetAxialScale( Sx, Sy, Sz );
2529 //=============================================================================
2532 //=============================================================================
2533 void V3d_View::FitAll(const Standard_Real theXmin,
2534 const Standard_Real theYmin,
2535 const Standard_Real theXmax,
2536 const Standard_Real theYmax)
2538 Handle(Graphic3d_Camera) aCamera = Camera();
2539 Standard_Real anAspect = aCamera->Aspect();
2541 Standard_Real aFitSizeU = Abs (theXmax - theXmin);
2542 Standard_Real aFitSizeV = Abs (theYmax - theYmin);
2543 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2544 if (aFitAspect >= anAspect)
2546 aFitSizeV = aFitSizeU / anAspect;
2550 aFitSizeU = aFitSizeV * anAspect;
2553 Translate (aCamera, (theXmin + theXmax) * 0.5, (theYmin + theYmax) * 0.5);
2554 Scale (aCamera, aFitSizeU, aFitSizeV);
2561 //=============================================================================
2562 //function : StartRotation
2564 //=============================================================================
2565 void V3d_View::StartRotation(const Standard_Integer X,
2566 const Standard_Integer Y,
2567 const Standard_Real zRotationThreshold)
2572 rx = Standard_Real(Convert(x));
2573 ry = Standard_Real(Convert(y));
2575 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2576 myZRotation = Standard_False;
2577 if( zRotationThreshold > 0. ) {
2578 Standard_Real dx = Abs(sx - rx/2.);
2579 Standard_Real dy = Abs(sy - ry/2.);
2580 // if( dx > rx/3. || dy > ry/3. ) myZRotation = Standard_True;
2581 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2582 if( dx > dd || dy > dd ) myZRotation = Standard_True;
2587 //=============================================================================
2588 //function : Rotation
2590 //=============================================================================
2591 void V3d_View::Rotation(const Standard_Integer X,
2592 const Standard_Integer Y)
2594 if( rx == 0. || ry == 0. ) {
2598 Standard_Real dx=0.,dy=0.,dz=0.;
2600 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2601 atan2(sx-rx/2.,ry/2.-sy);
2603 dx = (Standard_Real(X) - sx) * M_PI / rx;
2604 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2607 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2610 //=============================================================================
2611 //function : SetComputedMode
2613 //=============================================================================
2614 void V3d_View::SetComputedMode (const Standard_Boolean theMode)
2620 myView->SetComputedMode (Standard_True);
2625 myView->SetComputedMode (Standard_False);
2629 //=============================================================================
2630 //function : ComputedMode
2632 //=============================================================================
2633 Standard_Boolean V3d_View::ComputedMode() const
2635 return myView->ComputedMode();
2638 //=============================================================================
2639 //function : SetBackFacingModel
2641 //=============================================================================
2642 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel theModel)
2644 myView->SetBackfacingModel (static_cast<Graphic3d_TypeOfBackfacingModel> (theModel));
2648 //=============================================================================
2649 //function : BackFacingModel
2651 //=============================================================================
2652 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2654 return static_cast<V3d_TypeOfBackfacingModel> (myView->BackfacingModel());
2657 //=============================================================================
2660 //=============================================================================
2661 void V3d_View::Init()
2663 myComputedMode = MyViewer->ComputedMode();
2664 if (!myComputedMode || !MyViewer->DefaultComputedMode())
2666 SetComputedMode (Standard_False);
2670 //=============================================================================
2673 //=============================================================================
2674 Standard_Boolean V3d_View::Export (const Standard_CString theFileName,
2675 const Graphic3d_ExportFormat theFormat,
2676 const Graphic3d_SortType theSortType)
2678 return myView->Export (theFileName, theFormat, theSortType);
2681 //=============================================================================
2684 //=============================================================================
2685 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2686 const Graphic3d_BufferType& theBufferType)
2688 Standard_Integer aWinWidth, aWinHeight;
2689 MyWindow->Size (aWinWidth, aWinHeight);
2690 Image_AlienPixMap anImage;
2692 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2695 //=============================================================================
2696 //function : ToPixMap
2698 //=============================================================================
2699 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
2700 const V3d_ImageDumpOptions& theParams)
2702 Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
2703 if (aTargetSize.x() != 0
2704 && aTargetSize.y() != 0)
2706 // allocate image buffer for dumping
2707 if (theImage.IsEmpty()
2708 || theImage.SizeX() != Standard_Size(aTargetSize.x())
2709 || theImage.SizeY() != Standard_Size(aTargetSize.y()))
2711 Image_Format aFormat = Image_Format_UNKNOWN;
2712 switch (theParams.BufferType)
2714 case Graphic3d_BT_RGB: aFormat = Image_Format_RGB; break;
2715 case Graphic3d_BT_RGBA: aFormat = Image_Format_RGBA; break;
2716 case Graphic3d_BT_Depth: aFormat = Image_Format_GrayF; break;
2717 case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF; break;
2720 if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
2722 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y()
2723 + " for view dump", Message_Fail);
2724 return Standard_False;
2728 if (theImage.IsEmpty())
2730 Message::DefaultMessenger()->Send (TCollection_AsciiString ("V3d_View::ToPixMap() has been called without image dimensions"), Message_Fail);
2731 return Standard_False;
2733 aTargetSize.x() = (Standard_Integer )theImage.SizeX();
2734 aTargetSize.y() = (Standard_Integer )theImage.SizeY();
2736 Handle(Standard_Transient) aFBOPtr;
2737 Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
2738 Graphic3d_Vec2i aFBOVPSize = aTargetSize;
2740 bool isTiling = false;
2741 if (theParams.TileSize > 0)
2743 if (aFBOVPSize.x() > theParams.TileSize
2744 || aFBOVPSize.y() > theParams.TileSize)
2746 aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
2747 aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
2752 Graphic3d_Vec2i aPrevFBOVPSize;
2753 if (!aPrevFBOPtr.IsNull())
2755 Graphic3d_Vec2i aPrevFBOSizeMax;
2756 myView->FBOGetDimensions (aPrevFBOPtr,
2757 aPrevFBOVPSize.x(), aPrevFBOVPSize.y(),
2758 aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
2759 if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
2760 && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
2762 aFBOPtr = aPrevFBOPtr;
2766 if (aFBOPtr.IsNull())
2768 Standard_Integer aMaxTexSize = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxTextureSize);
2769 if (theParams.TileSize > aMaxTexSize)
2771 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
2772 + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSize + ")", Message_Fail);
2773 return Standard_False;
2776 if (aFBOVPSize.x() > aMaxTexSize
2777 || aFBOVPSize.y() > aMaxTexSize)
2779 aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSize);
2780 aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSize);
2784 // Try to create hardware accelerated buffer
2785 aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
2787 myView->SetFBO (aFBOPtr);
2789 if (aFBOPtr.IsNull())
2791 // try to use on-screen buffer
2792 Graphic3d_Vec2i aWinSize;
2793 MyWindow->Size (aWinSize.x(), aWinSize.y());
2794 if (aFBOVPSize.x() != aWinSize.x()
2795 || aFBOVPSize.y() != aWinSize.y())
2799 aFBOVPSize = aWinSize;
2801 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning, on screen buffer is used for image dump - content might be invalid"), Message_Warning);
2804 // backup camera parameters
2805 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2806 Handle(Graphic3d_Camera) aCamera = Camera();
2807 aStoreMapping->Copy (aCamera);
2808 if (aCamera->IsStereo())
2810 switch (theParams.StereoOptions)
2814 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2817 case V3d_SDO_LEFT_EYE:
2819 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2822 case V3d_SDO_RIGHT_EYE:
2824 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2827 case V3d_SDO_BLENDED:
2829 break; // dump as is
2833 if (theParams.ToAdjustAspect)
2835 aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
2839 // render immediate structures into back buffer rather than front
2840 const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
2842 Standard_Boolean isSuccess = Standard_True;
2845 if (!aFBOPtr.IsNull())
2847 myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
2850 isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
2854 Image_PixMap aTilePixMap;
2855 aTilePixMap.SetTopDown (theImage.IsTopDown());
2857 Graphic3d_Vec2i anOffset (0, 0);
2858 for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
2861 for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
2863 Graphic3d_CameraTile aTileUncropped;
2864 aTileUncropped.Offset = anOffset;
2865 aTileUncropped.TotalSize = aTargetSize;
2866 aTileUncropped.TileSize = aFBOVPSize;
2867 const Graphic3d_CameraTile aTile = aTileUncropped.Cropped();
2868 if (aTile.TileSize.x() < 1
2869 || aTile.TileSize.y() < 1)
2874 const Standard_Integer aLeft = aTile.Offset.x();
2875 Standard_Integer aBottom = aTile.Offset.y();
2876 if (theImage.IsTopDown())
2878 const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
2879 aBottom = aTargetSize.y() - aTop;
2881 aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
2882 + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
2883 aTile.TileSize.x(), aTile.TileSize.y(),
2884 theImage.SizeRowBytes());
2886 if (!aFBOPtr.IsNull())
2888 aCamera->SetTile (aTile);
2889 myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
2893 // no API to resize viewport of on-screen buffer - render uncropped
2894 aCamera->SetTile (aTileUncropped);
2897 isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
2911 myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
2912 aCamera->Copy (aStoreMapping);
2913 if (aFBOPtr != aPrevFBOPtr)
2915 myView->FBORelease (aFBOPtr);
2917 else if (!aPrevFBOPtr.IsNull())
2919 myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
2921 myView->SetFBO (aPrevFBOPtr);
2925 //=============================================================================
2926 //function : ImmediateUpdate
2928 //=============================================================================
2929 void V3d_View::ImmediateUpdate() const
2931 if (myImmediateUpdate)
2937 //=============================================================================
2938 //function : SetImmediateUpdate
2940 //=============================================================================
2941 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2943 Standard_Boolean aPreviousMode = myImmediateUpdate;
2944 myImmediateUpdate = theImmediateUpdate;
2945 return aPreviousMode;
2948 // =======================================================================
2949 // function : SetCamera
2951 // =======================================================================
2952 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2954 myView->SetCamera (theCamera);
2959 // =======================================================================
2960 // function : GetCamera
2962 // =======================================================================
2963 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
2965 return myView->Camera();
2968 // =======================================================================
2969 // function : FitMinMax
2970 // purpose : Internal
2971 // =======================================================================
2972 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
2973 const Bnd_Box& theBox,
2974 const Standard_Real theMargin,
2975 const Standard_Real theResolution,
2976 const Standard_Boolean theToEnlargeIfLine) const
2978 // Check bounding box for validness
2979 if (theBox.IsVoid())
2981 return Standard_False; // bounding box is out of bounds...
2984 // Apply "axial scaling" to the bounding points.
2985 // It is not the best approach to make this scaling as a part of fit all operation,
2986 // but the axial scale is integrated into camera orientation matrix and the other
2987 // option is to perform frustum plane adjustment algorithm in view camera space,
2988 // which will lead to a number of additional world-view space conversions and
2989 // loosing precision as well.
2990 gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (theCamera->AxialScale());
2991 gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (theCamera->AxialScale());
2993 if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
2995 return Standard_False; // nothing to fit all
2998 // Prepare camera frustum planes.
2999 NCollection_Array1<gp_Pln> aFrustumPlane (1, 6);
3000 theCamera->Frustum (aFrustumPlane.ChangeValue (1),
3001 aFrustumPlane.ChangeValue (2),
3002 aFrustumPlane.ChangeValue (3),
3003 aFrustumPlane.ChangeValue (4),
3004 aFrustumPlane.ChangeValue (5),
3005 aFrustumPlane.ChangeValue (6));
3007 // Prepare camera up, side, direction vectors.
3008 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3009 gp_Dir aCamDir = theCamera->Direction();
3010 gp_Dir aCamSide = aCamDir ^ aCamUp;
3012 // Prepare scene bounding box parameters.
3013 gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
3015 NCollection_Array1<gp_Pnt> aBndCorner (1, 8);
3016 aBndCorner.ChangeValue (1) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
3017 aBndCorner.ChangeValue (2) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
3018 aBndCorner.ChangeValue (3) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
3019 aBndCorner.ChangeValue (4) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
3020 aBndCorner.ChangeValue (5) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
3021 aBndCorner.ChangeValue (6) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
3022 aBndCorner.ChangeValue (7) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
3023 aBndCorner.ChangeValue (8) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
3025 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3026 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3027 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3028 // set up perspective-correct camera projection matching the bounding box.
3029 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3030 // The zooming can be done by calculating view plane size matching the bounding box at center of
3031 // the bounding box. The only limitation here is that the scale of camera should define size of
3032 // its view plane passing through the camera center, and the center of camera should be on the
3033 // same line with the center of bounding box.
3035 // The following method is applied:
3036 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3037 // 2) Determine new location of frustum planes, "matching" the bounding box.
3038 // 3) Determine new camera projection vector using the normalized asymmetry.
3039 // 4) Determine new zooming in view space.
3041 // 1. Determine normalized projection asymmetry (if any).
3042 Standard_Real anAssymX = Tan (( aCamSide).Angle (aFrustumPlane (1).Axis().Direction()))
3043 - Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction()));
3044 Standard_Real anAssymY = Tan (( aCamUp) .Angle (aFrustumPlane (3).Axis().Direction()))
3045 - Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction()));
3047 // 2. Determine how far should be the frustum planes placed from center
3048 // of bounding box, in order to match the bounding box closely.
3049 NCollection_Array1<Standard_Real> aFitDistance (1, 6);
3050 aFitDistance.ChangeValue (1) = 0.0;
3051 aFitDistance.ChangeValue (2) = 0.0;
3052 aFitDistance.ChangeValue (3) = 0.0;
3053 aFitDistance.ChangeValue (4) = 0.0;
3054 aFitDistance.ChangeValue (5) = 0.0;
3055 aFitDistance.ChangeValue (6) = 0.0;
3057 for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
3059 // Measure distances from center of bounding box to its corners towards the frustum plane.
3060 const gp_Dir& aPlaneN = aFrustumPlane.ChangeValue (anI).Axis().Direction();
3062 Standard_Real& aFitDist = aFitDistance.ChangeValue (anI);
3064 for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
3066 aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner (aJ)).Dot (aPlaneN));
3069 // The center of camera is placed on the same line with center of bounding box.
3070 // The view plane section crosses the bounding box at its center.
3071 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3072 // into view section size between the point and the frustum plane.
3074 // /|\ right half of frame //
3076 // point o<-- distance * coeff -->//---- (view plane section)
3085 aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan ( aCamSide .Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
3086 aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
3087 aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan ( aCamUp .Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
3088 aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
3089 aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan ( aCamDir .Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
3090 aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan ((-aCamDir) .Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
3092 Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
3093 Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
3094 Standard_Real aViewSizeZv = aFitDistance (5) + aFitDistance (6);
3096 // 3. Place center of camera on the same line with center of bounding
3097 // box applying corresponding projection asymmetry (if any).
3098 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3099 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3100 Standard_Real anOffsetXv = (aFitDistance (2) - aFitDistance (1)) * 0.5 + anAssymXv;
3101 Standard_Real anOffsetYv = (aFitDistance (4) - aFitDistance (3)) * 0.5 + anAssymYv;
3102 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3103 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3104 gp_Pnt aCamNewCenter = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3106 gp_Trsf aCenterTrsf;
3107 aCenterTrsf.SetTranslation (theCamera->Center(), aCamNewCenter);
3108 theCamera->Transform (aCenterTrsf);
3109 theCamera->SetDistance (aFitDistance (6) + aFitDistance (5));
3111 // Bounding box collapses to a point or thin line going in depth of the screen
3112 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3114 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3116 return Standard_True; // This is just one point or line and zooming has no effect.
3119 // Looking along line and "theToEnlargeIfLine" is requested.
3120 // Fit view to see whole scene on rotation.
3121 aViewSizeXv = aViewSizeZv;
3122 aViewSizeYv = aViewSizeZv;
3125 Scale (theCamera, aViewSizeXv, aViewSizeYv);
3127 const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
3129 Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
3131 return Standard_True;
3134 // =======================================================================
3136 // purpose : Internal
3137 // =======================================================================
3138 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3139 const Standard_Real theSizeXv,
3140 const Standard_Real theSizeYv) const
3142 Standard_Real anAspect = theCamera->Aspect();
3145 theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
3149 theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
3153 // =======================================================================
3154 // function : Translate
3155 // purpose : Internal
3156 // =======================================================================
3157 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3158 const Standard_Real theDXv,
3159 const Standard_Real theDYv) const
3161 const gp_Pnt& aCenter = theCamera->Center();
3162 const gp_Dir& aDir = theCamera->Direction();
3163 const gp_Dir& anUp = theCamera->Up();
3164 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3166 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3167 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3168 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3170 aPanTrsf.SetTranslation (aCameraPan);
3172 theCamera->Transform (aPanTrsf);
3175 // =======================================================================
3176 // function : IsCullingEnabled
3178 // =======================================================================
3179 Standard_Boolean V3d_View::IsCullingEnabled() const
3181 return myView->IsCullingEnabled();
3184 // =======================================================================
3185 // function : SetFrustumCulling
3187 // =======================================================================
3188 void V3d_View::SetFrustumCulling (const Standard_Boolean theToClip)
3190 myView->SetCullingEnabled (theToClip);
3193 // =======================================================================
3194 // function : DiagnosticInformation
3196 // =======================================================================
3197 void V3d_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
3198 Graphic3d_DiagnosticInfo theFlags) const
3200 myView->DiagnosticInformation (theDict, theFlags);
3203 //=============================================================================
3204 //function : RenderingParams
3206 //=============================================================================
3207 const Graphic3d_RenderingParams& V3d_View::RenderingParams() const
3209 return myView->RenderingParams();
3212 //=============================================================================
3213 //function : ChangeRenderingParams
3215 //=============================================================================
3216 Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams()
3218 return myView->ChangeRenderingParams();