1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <V3d_View.hxx>
16 #include <Aspect_GradientBackground.hxx>
17 #include <Aspect_Grid.hxx>
18 #include <Aspect_Window.hxx>
19 #include <Bnd_Box.hxx>
23 #include <Graphic3d_AspectMarker3d.hxx>
24 #include <Graphic3d_GraphicDriver.hxx>
25 #include <Graphic3d_Group.hxx>
26 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
27 #include <Graphic3d_MapOfStructure.hxx>
28 #include <Graphic3d_Structure.hxx>
29 #include <Graphic3d_TextureEnv.hxx>
30 #include <Graphic3d_Vector.hxx>
31 #include <Image_AlienPixMap.hxx>
32 #include <Message.hxx>
33 #include <Message_Messenger.hxx>
34 #include <NCollection_Array1.hxx>
35 #include <Precision.hxx>
36 #include <Quantity_Color.hxx>
37 #include <Standard_Assert.hxx>
38 #include <Standard_DivideByZero.hxx>
39 #include <Standard_ErrorHandler.hxx>
40 #include <Standard_MultiplyDefined.hxx>
41 #include <Standard_ShortReal.hxx>
42 #include <Standard_Type.hxx>
43 #include <Standard_TypeMismatch.hxx>
44 #include <TColgp_Array1OfPnt.hxx>
45 #include <TColStd_Array2OfReal.hxx>
46 #include <TColStd_HSequenceOfInteger.hxx>
48 #include <V3d_BadValue.hxx>
49 #include <V3d_Light.hxx>
50 #include <V3d_StereoDumpOptions.hxx>
51 #include <V3d_UnMapped.hxx>
52 #include <V3d_Viewer.hxx>
54 IMPLEMENT_STANDARD_RTTIEXT(V3d_View,MMgt_TShared)
56 #define DEUXPI (2. * M_PI)
60 static const Standard_Integer THE_NB_BOUND_POINTS = 8;
63 //=============================================================================
64 //function : Constructor
66 //=============================================================================
67 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType)
68 : MyViewer (theViewer.operator->()),
70 myActiveLightsIterator(),
71 SwitchSetFront (Standard_False),
72 myZRotation (Standard_False),
75 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
77 myView->SetBackground (theViewer->GetBackgroundColor());
78 myView->SetGradientBackground (theViewer->GetGradientBackground());
80 ChangeRenderingParams() = theViewer->DefaultRenderingParams();
83 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
84 aCamera->SetFOVy (45.0);
85 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
86 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
87 aCamera->SetProjectionType ((theType == V3d_ORTHOGRAPHIC)
88 ? Graphic3d_Camera::Projection_Orthographic
89 : Graphic3d_Camera::Projection_Perspective);
91 myDefaultCamera = new Graphic3d_Camera();
93 myImmediateUpdate = Standard_False;
94 SetAutoZFitMode (Standard_True, 1.0);
95 SetBackFacingModel (V3d_TOBM_AUTOMATIC);
97 SetAxis (0.,0.,0.,1.,1.,1.);
98 SetVisualization (theViewer->DefaultVisualization());
99 SetShadingModel (theViewer->DefaultShadingModel());
102 SetProj (theViewer->DefaultViewProj());
103 SetSize (theViewer->DefaultViewSize());
104 Standard_Real zsize = theViewer->DefaultViewSize();
106 SetDepth (theViewer->DefaultViewSize() / 2.0);
107 SetViewMappingDefault();
108 SetViewOrientationDefault();
109 theViewer->AddView (this);
111 myImmediateUpdate = Standard_True;
114 //=============================================================================
115 //function : Constructor
117 //=============================================================================
118 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
119 : MyViewer (theViewer.operator->()),
121 myActiveLightsIterator(),
122 SwitchSetFront(Standard_False),
123 myZRotation (Standard_False),
126 myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
128 myView->CopySettings (theView->View());
130 myDefaultCamera = new Graphic3d_Camera();
132 myImmediateUpdate = Standard_False;
133 SetAutoZFitMode (theView->AutoZFitMode(), theView->AutoZFitScaleFactor());
134 SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
135 SetViewMappingDefault();
136 SetViewOrientationDefault();
137 theViewer->AddView (this);
139 myImmediateUpdate = Standard_True;
142 //=============================================================================
143 //function : Destructor
145 //=============================================================================
146 V3d_View::~V3d_View()
148 if (!myView->IsRemoved())
154 //=============================================================================
155 //function : SetMagnify
157 //=============================================================================
158 void V3d_View::SetMagnify (const Handle(Aspect_Window)& theWindow,
159 const Handle(V3d_View)& thePreviousView,
160 const Standard_Integer theX1,
161 const Standard_Integer theY1,
162 const Standard_Integer theX2,
163 const Standard_Integer theY2)
165 if (!myView->IsRemoved() && !myView->IsDefined())
167 Standard_Real aU1, aV1, aU2, aV2;
168 thePreviousView->Convert (theX1, theY1, aU1, aV1);
169 thePreviousView->Convert (theX2, theY2, aU2, aV2);
170 myView->SetWindow (theWindow);
171 FitAll (theWindow, aU1, aV1, aU2, aV2);
172 MyViewer->SetViewOn (this);
173 MyWindow = theWindow;
176 SetViewMappingDefault();
180 //=============================================================================
181 //function : SetWindow
183 //=============================================================================
184 void V3d_View::SetWindow (const Handle(Aspect_Window)& theWindow,
185 const Aspect_RenderingContext theContext)
187 if (myView->IsRemoved())
192 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
193 MyWindow = theWindow;
194 myView->SetWindow (theWindow, theContext);
195 MyViewer->SetViewOn (this);
200 //=============================================================================
203 //=============================================================================
204 void V3d_View::Remove() const
206 MyViewer->DelView (this);
208 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
212 //=============================================================================
215 //=============================================================================
216 void V3d_View::Update() const
218 if (!myView->IsDefined()
219 || !myView->IsActive())
224 myView->Update (Aspect_TOU_ASAP);
227 //=============================================================================
230 //=============================================================================
231 void V3d_View::Redraw() const
233 if (!myView->IsDefined()
234 || !myView->IsActive())
239 Handle(Graphic3d_GraphicDriver) aGraphicDriver = MyViewer->Driver();
240 Handle(Graphic3d_StructureManager) aStructureMgr = MyViewer->StructureManager();
241 for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
243 if (aGraphicDriver->IsDeviceLost())
245 aStructureMgr->RecomputeStructures();
246 aGraphicDriver->ResetDeviceLostFlag();
253 if (!aGraphicDriver->IsDeviceLost())
260 //=============================================================================
261 //function : RedrawImmediate
263 //=============================================================================
264 void V3d_View::RedrawImmediate() const
266 if (!myView->IsDefined()
267 || !myView->IsActive())
272 myView->RedrawImmediate();
275 //=============================================================================
276 //function : Invalidate
278 //=============================================================================
279 void V3d_View::Invalidate() const
281 if (!myView->IsDefined())
286 myView->Invalidate();
289 //=============================================================================
290 //function : IsInvalidated
292 //=============================================================================
293 Standard_Boolean V3d_View::IsInvalidated() const
295 return !myView->IsDefined()
296 || myView->IsInvalidated();
299 // ========================================================================
300 // function : SetAutoZFitMode
302 // ========================================================================
303 void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn,
304 const Standard_Real theScaleFactor)
306 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
307 myAutoZFitScaleFactor = theScaleFactor;
308 myAutoZFitIsOn = theIsOn;
311 // ========================================================================
312 // function : AutoZFitMode
314 // ========================================================================
315 Standard_Boolean V3d_View::AutoZFitMode() const
317 return myAutoZFitIsOn;
320 // ========================================================================
321 // function : AutoZFitScaleFactor
323 // ========================================================================
324 Standard_Real V3d_View::AutoZFitScaleFactor() const
326 return myAutoZFitScaleFactor;
329 //=============================================================================
330 //function : AutoZFit
332 //=============================================================================
333 void V3d_View::AutoZFit() const
340 ZFitAll (myAutoZFitScaleFactor);
343 //=============================================================================
346 //=============================================================================
347 void V3d_View::ZFitAll (const Standard_Real theScaleFactor) const
349 Bnd_Box aMinMaxBox = myView->MinMaxValues (Standard_False); // applicative min max boundaries
350 Bnd_Box aGraphicBox = myView->MinMaxValues (Standard_True); // real graphical boundaries (not accounting infinite flag).
352 myView->Camera()->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
355 //=============================================================================
358 //=============================================================================
359 Standard_Boolean V3d_View::IsEmpty() const
361 Standard_Boolean TheStatus = Standard_True ;
362 if( myView->IsDefined() ) {
363 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
364 if( Nstruct > 0 ) TheStatus = Standard_False ;
369 //=============================================================================
370 //function : UpdateLights
372 //=============================================================================
373 void V3d_View::UpdateLights() const
375 Graphic3d_ListOfCLight aLights;
377 for (TColStd_ListIteratorOfListOfTransient anIt (MyActiveLights); anIt.More(); anIt.Next())
379 aLights.Append (Handle(V3d_Light)::DownCast (anIt.Value())->Light());
382 myView->SetLights (aLights);
387 //=============================================================================
388 //function : DoMapping
390 //=============================================================================
391 void V3d_View::DoMapping()
393 if (!myView->IsDefined())
398 myView->Window()->DoMapping();
401 //=============================================================================
402 //function : MustBeResized
404 //=============================================================================
405 void V3d_View::MustBeResized()
407 if (!myView->IsDefined())
419 //=============================================================================
420 //function : SetBackgroundColor
422 //=============================================================================
423 void V3d_View::SetBackgroundColor (const Quantity_TypeOfColor theType,
424 const Standard_Real theV1,
425 const Standard_Real theV2,
426 const Standard_Real theV3)
428 Standard_Real aV1 = Max (Min (theV1, 1.0), 0.0);
429 Standard_Real aV2 = Max (Min (theV2, 1.0), 0.0);
430 Standard_Real aV3 = Max (Min (theV3, 1.0), 0.0);
432 SetBackgroundColor (Quantity_Color (aV1, aV2, aV3, theType));
435 //=============================================================================
436 //function : SetBackgroundColor
438 //=============================================================================
439 void V3d_View::SetBackgroundColor (const Quantity_Color& theColor)
441 myView->SetBackground (Aspect_Background (theColor));
443 if (myImmediateUpdate)
449 //=============================================================================
450 //function : SetBackgroundColor
452 //=============================================================================
453 void V3d_View::SetBackgroundColor (const Quantity_NameOfColor theName)
455 SetBackgroundColor (Quantity_Color (theName));
458 //=============================================================================
459 //function : SetBgGradientColors
461 //=============================================================================
462 void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
463 const Quantity_Color& theColor2,
464 const Aspect_GradientFillMethod theFillStyle,
465 const Standard_Boolean theToUpdate)
467 Aspect_GradientBackground aGradientBg (theColor1, theColor2, theFillStyle);
469 myView->SetGradientBackground (aGradientBg);
471 if (myImmediateUpdate || theToUpdate)
477 //=============================================================================
478 //function : SetBgGradientColors
480 //=============================================================================
481 void V3d_View::SetBgGradientColors (const Quantity_NameOfColor theColor1,
482 const Quantity_NameOfColor theColor2,
483 const Aspect_GradientFillMethod theFillStyle,
484 const Standard_Boolean theToUpdate)
486 Quantity_Color aColor1 (theColor1);
487 Quantity_Color aColor2 (theColor2);
489 SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
492 //=============================================================================
493 //function : SetBgGradientStyle
495 //=============================================================================
496 void V3d_View::SetBgGradientStyle (const Aspect_GradientFillMethod theFillStyle, const Standard_Boolean theToUpdate)
498 Quantity_Color aColor1;
499 Quantity_Color aColor2;
500 GradientBackground().Colors (aColor1, aColor2);
502 SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
505 //=============================================================================
506 //function : SetBackgroundImage
508 //=============================================================================
509 void V3d_View::SetBackgroundImage (const Standard_CString theFileName,
510 const Aspect_FillMethod theFillStyle,
511 const Standard_Boolean theToUpdate)
513 myView->SetBackgroundImage (theFileName);
514 myView->SetBackgroundImageStyle (theFillStyle);
516 if (myImmediateUpdate || theToUpdate)
522 //=============================================================================
523 //function : SetBgImageStyle
525 //=============================================================================
526 void V3d_View::SetBgImageStyle (const Aspect_FillMethod theFillStyle, const Standard_Boolean theToUpdate)
528 myView->SetBackgroundImageStyle (theFillStyle);
530 if (myImmediateUpdate || theToUpdate)
536 //=============================================================================
539 //=============================================================================
540 void V3d_View::SetAxis(const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Real Vx, const Standard_Real Vy, const Standard_Real Vz)
542 Standard_Real D,Nx = Vx,Ny = Vy,Nz = Vz ;
544 D = Sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) ;
545 V3d_BadValue_Raise_if ( D <= 0. , "V3d_View::SetAxis, bad axis");
546 Nx /= D ; Ny /= D ; Nz /= D ;
547 MyDefaultViewPoint.SetCoord(X,Y,Z) ;
548 MyDefaultViewAxis.SetCoord(Nx,Ny,Nz) ;
551 //=============================================================================
552 //function : SetShadingModel
554 //=============================================================================
555 void V3d_View::SetShadingModel (const V3d_TypeOfShadingModel theShadingModel)
557 myView->SetShadingModel (static_cast<Graphic3d_TypeOfShadingModel> (theShadingModel));
560 //=============================================================================
561 //function : SetTextureEnv
563 //=============================================================================
564 void V3d_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTexture)
566 myView->SetTextureEnv (theTexture);
568 if (myImmediateUpdate)
574 //=============================================================================
575 //function : SetVisualization
577 //=============================================================================
578 void V3d_View::SetVisualization (const V3d_TypeOfVisualization theType)
580 myView->SetVisualizationType (static_cast <Graphic3d_TypeOfVisualization> (theType));
582 if (myImmediateUpdate)
588 //=============================================================================
589 //function : SetFront
591 //=============================================================================
592 void V3d_View::SetFront()
594 gp_Ax3 a = MyViewer->PrivilegedPlane();
595 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
597 a.Direction().Coord(vx,vy,vz);
598 a.YDirection().Coord(xu,yu,zu);
599 a.Location().Coord(xo,yo,zo);
601 Handle(Graphic3d_Camera) aCamera = Camera();
603 aCamera->SetCenter (gp_Pnt (xo, yo, zo));
607 aCamera->SetDirection (gp_Dir (vx, vy, vz));
611 aCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
614 aCamera->SetUp (gp_Dir (xu, yu, zu));
618 SwitchSetFront = !SwitchSetFront;
623 //=============================================================================
626 //=============================================================================
627 void V3d_View::Rotate (const Standard_Real ax,
628 const Standard_Real ay,
629 const Standard_Real az,
630 const Standard_Boolean Start)
632 Standard_Real Ax = ax;
633 Standard_Real Ay = ay;
634 Standard_Real Az = az;
636 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
637 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
638 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
639 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
640 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
641 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
643 Handle(Graphic3d_Camera) aCamera = Camera();
647 myCamStartOpUp = aCamera->Up();
648 myCamStartOpEye = aCamera->Eye();
649 myCamStartOpCenter = aCamera->Center();
652 aCamera->SetUp (myCamStartOpUp);
653 aCamera->SetEye (myCamStartOpEye);
654 aCamera->SetCenter (myCamStartOpCenter);
656 // rotate camera around 3 initial axes
657 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
658 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
659 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
660 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
662 gp_Trsf aRot[3], aTrsf;
663 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
664 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
665 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
666 aTrsf.Multiply (aRot[0]);
667 aTrsf.Multiply (aRot[1]);
668 aTrsf.Multiply (aRot[2]);
670 aCamera->Transform (aTrsf);
677 //=============================================================================
680 //=============================================================================
681 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
682 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
685 Standard_Real Ax = ax ;
686 Standard_Real Ay = ay ;
687 Standard_Real Az = az ;
689 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
690 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
691 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
692 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
693 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
694 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
696 Handle(Graphic3d_Camera) aCamera = Camera();
700 myGravityReferencePoint.SetCoord (X, Y, Z);
701 myCamStartOpUp = aCamera->Up();
702 myCamStartOpEye = aCamera->Eye();
703 myCamStartOpCenter = aCamera->Center();
706 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
708 aCamera->SetUp (myCamStartOpUp);
709 aCamera->SetEye (myCamStartOpEye);
710 aCamera->SetCenter (myCamStartOpCenter);
712 // rotate camera around 3 initial axes
713 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
715 gp_Dir aZAxis (aCamera->Direction().Reversed());
716 gp_Dir aYAxis (aCamera->Up());
717 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
719 gp_Trsf aRot[3], aTrsf;
720 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
721 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
722 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
723 aTrsf.Multiply (aRot[0]);
724 aTrsf.Multiply (aRot[1]);
725 aTrsf.Multiply (aRot[2]);
727 aCamera->Transform (aTrsf);
734 //=============================================================================
737 //=============================================================================
738 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
742 Rotate(angle,0.,0.,Start);
745 Rotate(0.,angle,0.,Start);
748 Rotate(0.,0.,angle,Start);
753 //=============================================================================
756 //=============================================================================
757 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
758 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
760 Standard_Real Angle = angle ;
762 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
763 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
765 Handle(Graphic3d_Camera) aCamera = Camera();
769 myGravityReferencePoint.SetCoord (X, Y, Z);
770 myCamStartOpUp = aCamera->Up();
771 myCamStartOpEye = aCamera->Eye();
772 myCamStartOpCenter = aCamera->Center();
776 myViewAxis.SetCoord(1.,0.,0.) ;
779 myViewAxis.SetCoord(0.,1.,0.) ;
782 myViewAxis.SetCoord(0.,0.,1.) ;
786 myCamStartOpUp = aCamera->Up();
787 myCamStartOpEye = aCamera->Eye();
788 myCamStartOpCenter = aCamera->Center();
791 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
793 aCamera->SetUp (myCamStartOpUp);
794 aCamera->SetEye (myCamStartOpEye);
795 aCamera->SetCenter (myCamStartOpCenter);
797 // rotate camera around passed axis
799 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
800 gp_Dir aRAxis ((Axe == V3d_X) ? 1.0 : 0.0,
801 (Axe == V3d_Y) ? 1.0 : 0.0,
802 (Axe == V3d_Z) ? 1.0 : 0.0);
804 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
806 aCamera->Transform (aRotation);
813 //=============================================================================
816 //=============================================================================
817 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
819 Standard_Real Angle = angle;
821 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
822 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
824 Handle(Graphic3d_Camera) aCamera = Camera();
827 myCamStartOpUp = aCamera->Up();
828 myCamStartOpEye = aCamera->Eye();
829 myCamStartOpCenter = aCamera->Center();
832 const Graphic3d_Vertex& aPnt = MyDefaultViewPoint;
833 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
835 aCamera->SetUp (myCamStartOpUp);
836 aCamera->SetEye (myCamStartOpEye);
837 aCamera->SetCenter (myCamStartOpCenter);
840 gp_Pnt aRCenter (aPnt.X(), aPnt.Y(), aPnt.Z());
841 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
842 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
844 aCamera->Transform (aRotation);
851 //=============================================================================
854 //=============================================================================
855 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
857 Standard_Real Ax = ax;
858 Standard_Real Ay = ay;
859 Standard_Real Az = az;
861 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
862 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
863 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
864 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
865 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
866 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
868 Handle(Graphic3d_Camera) aCamera = Camera();
871 myCamStartOpUp = aCamera->Up();
872 myCamStartOpEye = aCamera->Eye();
873 myCamStartOpCenter = aCamera->Center();
876 aCamera->SetUp (myCamStartOpUp);
877 aCamera->SetEye (myCamStartOpEye);
878 aCamera->SetCenter (myCamStartOpCenter);
880 // rotate camera around 3 initial axes
881 gp_Pnt aRCenter = aCamera->Eye();
882 gp_Dir aZAxis (aCamera->Direction().Reversed());
883 gp_Dir aYAxis (aCamera->Up());
884 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
886 gp_Trsf aRot[3], aTrsf;
887 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
888 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
889 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
890 aTrsf.Multiply (aRot[0]);
891 aTrsf.Multiply (aRot[1]);
892 aTrsf.Multiply (aRot[2]);
894 aCamera->Transform (aTrsf);
901 //=============================================================================
904 //=============================================================================
905 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
909 Turn(angle,0.,0.,Start);
912 Turn(0.,angle,0.,Start);
915 Turn(0.,0.,angle,Start);
920 //=============================================================================
923 //=============================================================================
924 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
926 Standard_Real Angle = angle ;
928 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
929 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
931 Handle(Graphic3d_Camera) aCamera = Camera();
934 myCamStartOpUp = aCamera->Up();
935 myCamStartOpEye = aCamera->Eye();
936 myCamStartOpCenter = aCamera->Center();
939 aCamera->SetUp (myCamStartOpUp);
940 aCamera->SetEye (myCamStartOpEye);
941 aCamera->SetCenter (myCamStartOpCenter);
943 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
946 gp_Pnt aRCenter = aCamera->Eye();
947 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
948 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
950 aCamera->Transform (aRotation);
957 //=============================================================================
958 //function : SetTwist
960 //=============================================================================
961 void V3d_View::SetTwist(const Standard_Real angle)
963 Standard_Real Angle = angle ;
964 Standard_Boolean TheStatus;
966 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
967 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
969 Handle(Graphic3d_Camera) aCamera = Camera();
971 gp_Dir aReferencePlane (aCamera->Direction().Reversed());
974 anUp = gp_Dir (0.0, 0.0, 1.0);
976 TheStatus = ScreenAxis(aReferencePlane, anUp,
977 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
979 anUp = gp_Dir (0.0, 1.0, 0.0);
980 TheStatus = ScreenAxis(aReferencePlane, anUp,
981 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
984 anUp = gp_Dir (1.0, 0.0, 0.0);
985 TheStatus = ScreenAxis(aReferencePlane, anUp,
986 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
989 V3d_BadValue_Raise_if( !TheStatus,"V3d_ViewSetTwist, alignment of Eye,At,Up,");
991 gp_Pnt aRCenter = aCamera->Center();
992 gp_Dir aZAxis (aCamera->Direction().Reversed());
995 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
997 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
998 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1000 aCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1001 aCamera->Transform (aTrsf);
1008 //=============================================================================
1011 //=============================================================================
1012 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1014 Standard_Real aTwistBefore = Twist();
1016 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1018 Handle(Graphic3d_Camera) aCamera = Camera();
1020 aCamera->SetEye (gp_Pnt (X, Y, Z));
1022 SetTwist (aTwistBefore);
1026 SetImmediateUpdate (wasUpdateEnabled);
1031 //=============================================================================
1032 //function : SetDepth
1034 //=============================================================================
1035 void V3d_View::SetDepth(const Standard_Real Depth)
1037 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1039 Handle(Graphic3d_Camera) aCamera = Camera();
1043 // Move eye using center (target) as anchor.
1044 aCamera->SetDistance (Depth);
1048 // Move the view ref point instead of the eye.
1049 gp_Vec aDir (aCamera->Direction());
1050 gp_Pnt aCameraEye = aCamera->Eye();
1051 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1053 aCamera->SetCenter (aCameraCenter);
1061 //=============================================================================
1062 //function : SetProj
1064 //=============================================================================
1065 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1067 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1068 "V3d_View::SetProj, null projection vector");
1070 Standard_Real aTwistBefore = Twist();
1072 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1074 Camera()->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1076 SetTwist(aTwistBefore);
1080 SetImmediateUpdate (wasUpdateEnabled);
1085 //=============================================================================
1086 //function : SetProj
1088 //=============================================================================
1089 void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1091 Standard_Real Xpn=0;
1092 Standard_Real Ypn=0;
1093 Standard_Real Zpn=0;
1095 switch (Orientation) {
1106 const Graphic3d_Vector& aBck = V3d::GetProjAxis (Orientation);
1108 // retain camera panning from origin when switching projection
1109 Handle(Graphic3d_Camera) aCamera = Camera();
1111 gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
1112 Standard_Real aPanX = anOriginVCS.X();
1113 Standard_Real aPanY = anOriginVCS.Y();
1115 aCamera->SetCenter (gp_Pnt (0, 0, 0));
1116 aCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1117 aCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
1118 aCamera->OrthogonalizeUp();
1120 Panning (aPanX, aPanY);
1127 //=============================================================================
1130 //=============================================================================
1131 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1133 Standard_Real aTwistBefore = Twist();
1135 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1137 Camera()->SetCenter (gp_Pnt (X, Y, Z));
1139 SetTwist (aTwistBefore);
1143 SetImmediateUpdate (wasUpdateEnabled);
1148 //=============================================================================
1151 //=============================================================================
1152 void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standard_Real Vz)
1154 Standard_Boolean TheStatus ;
1155 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0. ,
1156 "V3d_View::SetUp, nullUp vector");
1158 Handle(Graphic3d_Camera) aCamera = Camera();
1160 gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1161 gp_Dir anUp (Vx, Vy, Vz);
1163 TheStatus = ScreenAxis(aReferencePlane,anUp,
1164 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1166 anUp = gp_Dir (0.0, 0.0, 1.0);
1167 TheStatus = ScreenAxis(aReferencePlane,anUp,
1168 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1171 anUp = gp_Dir (0.0, 1.0, 0.0);
1172 TheStatus = ScreenAxis(aReferencePlane,anUp,
1173 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1176 anUp = gp_Dir (1.0, 0.0, 0.0);
1177 TheStatus = ScreenAxis(aReferencePlane,anUp,
1178 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1180 V3d_BadValue_Raise_if( !TheStatus,"V3d_View::Setup, alignment of Eye,At,Up");
1182 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1183 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1185 aCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1192 //=============================================================================
1195 //=============================================================================
1196 void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
1198 Standard_Boolean TheStatus ;
1200 Handle(Graphic3d_Camera) aCamera = Camera();
1202 gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1205 const Graphic3d_Vector& aViewReferenceUp = V3d::GetProjAxis(Orientation) ;
1206 anUp = gp_Dir (aViewReferenceUp.X(), aViewReferenceUp.Y(), aViewReferenceUp.Z());
1208 TheStatus = ScreenAxis(aReferencePlane,anUp,
1209 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1211 anUp = gp_Dir (0.,0.,1.);
1212 TheStatus = ScreenAxis(aReferencePlane,anUp,
1213 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1216 anUp = gp_Dir (0.,1.,0.);
1217 TheStatus = ScreenAxis(aReferencePlane,anUp,
1218 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1221 anUp = gp_Dir (1.,0.,0.);
1222 TheStatus = ScreenAxis(aReferencePlane,anUp,
1223 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1225 V3d_BadValue_Raise_if( !TheStatus, "V3d_View::SetUp, alignment of Eye,At,Up");
1227 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1228 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1230 aCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1237 //=============================================================================
1238 //function : SetViewOrientationDefault
1240 //=============================================================================
1241 void V3d_View::SetViewOrientationDefault()
1243 myDefaultCamera->CopyOrientationData (Camera());
1246 //=======================================================================
1247 //function : SetViewMappingDefault
1249 //=======================================================================
1250 void V3d_View::SetViewMappingDefault()
1252 myDefaultCamera->CopyMappingData (Camera());
1255 //=============================================================================
1256 //function : ResetViewOrientation
1258 //=============================================================================
1259 void V3d_View::ResetViewOrientation()
1261 Camera()->CopyOrientationData (myDefaultCamera);
1268 //=======================================================================
1269 //function : ResetViewMapping
1271 //=======================================================================
1272 void V3d_View::ResetViewMapping()
1274 Camera()->CopyMappingData (myDefaultCamera);
1281 //=============================================================================
1284 //=============================================================================
1285 void V3d_View::Reset (const Standard_Boolean theToUpdate)
1287 Camera()->Copy (myDefaultCamera);
1291 SwitchSetFront = Standard_False;
1293 if (myImmediateUpdate || theToUpdate)
1299 //=======================================================================
1300 //function : SetCenter
1302 //=======================================================================
1303 void V3d_View::SetCenter (const Standard_Integer theXp,
1304 const Standard_Integer theYp)
1306 Standard_Real aXv, aYv;
1307 Convert (theXp, theYp, aXv, aYv);
1308 Translate (Camera(), aXv, aYv);
1313 //=============================================================================
1314 //function : SetSize
1316 //=============================================================================
1317 void V3d_View::SetSize (const Standard_Real theSize)
1319 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1321 Handle(Graphic3d_Camera) aCamera = Camera();
1323 aCamera->SetScale (aCamera->Aspect() >= 1.0 ? theSize / aCamera->Aspect() : theSize);
1330 //=============================================================================
1331 //function : SetZSize
1333 //=============================================================================
1334 void V3d_View::SetZSize (const Standard_Real theSize)
1336 Handle(Graphic3d_Camera) aCamera = Camera();
1338 Standard_Real Zmax = theSize / 2.;
1340 Standard_Real aDistance = aCamera->Distance();
1347 // ShortReal precision factor used to add meaningful tolerance to
1348 // ZNear, ZFar values in order to avoid equality after type conversion
1349 // to ShortReal matrices type.
1350 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1352 Standard_Real aZFar = Zmax + aDistance * 2.0;
1353 Standard_Real aZNear = -Zmax + aDistance;
1354 aZNear -= Abs (aZNear) * aPrecision;
1355 aZFar += Abs (aZFar) * aPrecision;
1357 if (!aCamera->IsOrthographic())
1359 if (aZFar < aPrecision)
1361 // Invalid case when both values are negative
1362 aZNear = aPrecision;
1363 aZFar = aPrecision * 2.0;
1365 else if (aZNear < Abs (aZFar) * aPrecision)
1367 // Z is less than 0.0, try to fix it using any appropriate z-scale
1368 aZNear = Abs (aZFar) * aPrecision;
1372 // If range is too small
1373 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1375 aZFar = aZNear + Abs (aZFar) * aPrecision;
1378 aCamera->SetZRange (aZNear, aZFar);
1380 if (myImmediateUpdate)
1386 //=============================================================================
1387 //function : SetZoom
1389 //=============================================================================
1390 void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1392 V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
1394 Handle(Graphic3d_Camera) aCamera = Camera();
1398 myCamStartOpEye = aCamera->Eye();
1399 myCamStartOpCenter = aCamera->Center();
1402 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
1403 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
1405 // ensure that zoom will not be too small or too big
1406 Standard_Real coef = Coef;
1407 if (aViewWidth < coef * Precision::Confusion())
1409 coef = aViewWidth / Precision::Confusion();
1411 else if (aViewWidth > coef * 1e12)
1413 coef = aViewWidth / 1e12;
1415 if (aViewHeight < coef * Precision::Confusion())
1417 coef = aViewHeight / Precision::Confusion();
1419 else if (aViewHeight > coef * 1e12)
1421 coef = aViewHeight / 1e12;
1424 aCamera->SetEye (myCamStartOpEye);
1425 aCamera->SetCenter (myCamStartOpCenter);
1426 aCamera->SetScale (aCamera->Scale() / Coef);
1433 //=============================================================================
1434 //function : SetScale
1436 //=============================================================================
1437 void V3d_View::SetScale( const Standard_Real Coef )
1439 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1441 Handle(Graphic3d_Camera) aCamera = Camera();
1443 Standard_Real aDefaultScale = myDefaultCamera->Scale();
1444 aCamera->SetAspect (myDefaultCamera->Aspect());
1445 aCamera->SetScale (aDefaultScale / Coef);
1452 //=============================================================================
1453 //function : SetAxialScale
1455 //=============================================================================
1456 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1458 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1460 Camera()->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1465 //=============================================================================
1466 //function : SetRatio
1468 //=============================================================================
1469 void V3d_View::SetRatio()
1471 if (MyWindow.IsNull())
1476 Standard_Integer aWidth = 0;
1477 Standard_Integer aHeight = 0;
1478 MyWindow->Size (aWidth, aHeight);
1479 if (aWidth > 0 && aHeight > 0)
1481 Standard_Real aRatio = static_cast<Standard_Real> (aWidth) /
1482 static_cast<Standard_Real> (aHeight);
1484 Camera() ->SetAspect (aRatio);
1485 myDefaultCamera->SetAspect (aRatio);
1489 //=============================================================================
1492 //=============================================================================
1493 void V3d_View::FitAll (const Quantity_Coefficient theMargin, const Standard_Boolean theToUpdate)
1495 FitAll (myView->MinMaxValues(), theMargin, theToUpdate);
1498 //=============================================================================
1501 //=============================================================================
1502 void V3d_View::FitAll (const Bnd_Box& theBox, const Quantity_Coefficient theMargin, const Standard_Boolean theToUpdate)
1504 Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1506 if (myView->NumberOfDisplayedStructures() == 0)
1511 if (!FitMinMax (Camera(), theBox, theMargin, 10.0 * Precision::Confusion()))
1518 if (myImmediateUpdate || theToUpdate)
1524 //=============================================================================
1525 //function : DepthFitAll
1527 //=============================================================================
1528 void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1529 const Quantity_Coefficient Margin)
1531 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1532 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1533 Standard_Real Dx,Dy,Dz,Size;
1535 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1537 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1542 Bnd_Box aBox = myView->MinMaxValues();
1548 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1549 Project (Xmin,Ymin,Zmin,U,V,W) ;
1550 Project (Xmax,Ymax,Zmax,U1,V1,W1) ;
1551 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1552 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1553 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1554 Project (Xmin,Ymin,Zmax,U,V,W) ;
1555 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1556 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1557 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1558 Project (Xmax,Ymin,Zmax,U,V,W) ;
1559 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1560 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1561 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1562 Project (Xmax,Ymin,Zmin,U,V,W) ;
1563 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1564 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1565 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1566 Project (Xmax,Ymax,Zmin,U,V,W) ;
1567 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1568 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1569 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1570 Project (Xmin,Ymax,Zmax,U,V,W) ;
1571 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1572 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1573 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1574 Project (Xmin,Ymax,Zmin,U,V,W) ;
1575 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1576 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1577 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1580 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1581 Dz = 2.*Wmax + Margin * Wmax;
1583 // Compute depth value
1584 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1585 Dx += Margin * Dx; Dy += Margin * Dy;
1586 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1589 SetDepth( Aspect * Size / 2.);
1595 //=============================================================================
1598 //=============================================================================
1599 void V3d_View::FitAll(const Standard_Real theMinXv,
1600 const Standard_Real theMinYv,
1601 const Standard_Real theMaxXv,
1602 const Standard_Real theMaxYv)
1604 FitAll (MyWindow, theMinXv, theMinYv, theMaxXv, theMaxYv);
1607 //=============================================================================
1608 //function : WindowFitAll
1610 //=============================================================================
1611 void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1612 const Standard_Integer Ymin,
1613 const Standard_Integer Xmax,
1614 const Standard_Integer Ymax)
1616 WindowFit(Xmin,Ymin,Xmax,Ymax);
1619 //=======================================================================
1620 //function : WindowFit
1622 //=======================================================================
1623 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1624 const Standard_Integer theMinYp,
1625 const Standard_Integer theMaxXp,
1626 const Standard_Integer theMaxYp)
1628 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1630 Handle(Graphic3d_Camera) aCamera = Camera();
1632 if (!aCamera->IsOrthographic())
1634 // normalize view coordinates
1635 Standard_Integer aWinWidth, aWinHeight;
1636 MyWindow->Size (aWinWidth, aWinHeight);
1638 // z coordinate of camera center
1639 Standard_Real aDepth = aCamera->Project (aCamera->Center()).Z();
1641 // camera projection coordinate are in NDC which are normalized [-1, 1]
1642 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1643 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1644 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1645 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1647 // compute camera panning
1648 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1649 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1650 gp_Pnt aPanTo = aCamera->ConvertProj2View (aFitCenter);
1651 gp_Pnt aPanFrom = aCamera->ConvertProj2View (aScreenCenter);
1652 gp_Vec aPanVec (aPanFrom, aPanTo);
1654 // compute section size
1655 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1656 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1657 gp_Pnt aViewBotLeft = aCamera->ConvertProj2View (aFitBotLeft);
1658 gp_Pnt aViewTopRight = aCamera->ConvertProj2View (aFitTopRight);
1660 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1661 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1663 Translate (aCamera, aPanVec.X(), -aPanVec.Y());
1664 Scale (aCamera, aUSize, aVSize);
1669 Standard_Real aX1, aY1, aX2, aY2;
1670 Convert (theMinXp, theMinYp, aX1, aY1);
1671 Convert (theMaxXp, theMaxYp, aX2, aY2);
1672 FitAll (aX1, aY1, aX2, aY2);
1675 SetImmediateUpdate (wasUpdateEnabled);
1680 //=======================================================================
1681 //function : ConvertToGrid
1683 //=======================================================================
1684 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1685 const Standard_Integer Yp,
1688 Standard_Real& Zg) const
1690 Graphic3d_Vertex aVrp;
1691 Standard_Real anX, anY, aZ;
1692 Convert (Xp, Yp, anX, anY, aZ);
1693 aVrp.SetCoord (anX, anY, aZ);
1695 if( MyViewer->Grid()->IsActive() ) {
1696 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1697 aNewVrp.Coord (Xg,Yg,Zg) ;
1699 aVrp.Coord (Xg,Yg,Zg) ;
1702 //=======================================================================
1703 //function : ConvertToGrid
1705 //=======================================================================
1706 void V3d_View::ConvertToGrid(const Standard_Real X,
1707 const Standard_Real Y,
1708 const Standard_Real Z,
1711 Standard_Real& Zg) const
1713 if( MyViewer->Grid()->IsActive() ) {
1714 Graphic3d_Vertex aVrp (X,Y,Z) ;
1715 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1716 aNewVrp.Coord(Xg,Yg,Zg) ;
1718 Xg = X; Yg = Y; Zg = Z;
1722 //=======================================================================
1723 //function : Convert
1725 //=======================================================================
1726 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1728 Standard_Integer aDxw, aDyw ;
1730 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1732 MyWindow->Size (aDxw, aDyw);
1733 Standard_Real aValue;
1735 gp_Pnt aViewDims = Camera()->ViewDimensions();
1736 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1741 //=======================================================================
1742 //function : Convert
1744 //=======================================================================
1745 void V3d_View::Convert(const Standard_Integer Xp,
1746 const Standard_Integer Yp,
1748 Standard_Real& Yv) const
1750 Standard_Integer aDxw, aDyw;
1752 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1754 MyWindow->Size (aDxw, aDyw);
1756 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1757 aPoint = Camera()->ConvertProj2View (aPoint);
1763 //=======================================================================
1764 //function : Convert
1766 //=======================================================================
1767 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1769 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1771 Standard_Integer aDxw, aDyw;
1772 MyWindow->Size (aDxw, aDyw);
1774 gp_Pnt aViewDims = Camera()->ViewDimensions();
1775 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1780 //=======================================================================
1781 //function : Convert
1783 //=======================================================================
1784 void V3d_View::Convert(const Standard_Real Xv,
1785 const Standard_Real Yv,
1786 Standard_Integer& Xp,
1787 Standard_Integer& Yp) const
1789 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1791 Standard_Integer aDxw, aDyw;
1792 MyWindow->Size (aDxw, aDyw);
1794 gp_Pnt aPoint (Xv, Yv, 0.0);
1795 aPoint = Camera()->ConvertView2Proj (aPoint);
1796 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1798 Xp = RealToInt (aPoint.X());
1799 Yp = RealToInt (aPoint.Y());
1802 //=======================================================================
1803 //function : Convert
1805 //=======================================================================
1806 void V3d_View::Convert(const Standard_Integer Xp,
1807 const Standard_Integer Yp,
1810 Standard_Real& Z) const
1812 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1813 Standard_Integer aHeight, aWidth;
1814 MyWindow->Size (aWidth, aHeight);
1816 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1817 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1818 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1820 gp_Pnt aResult = Camera()->UnProject (gp_Pnt (anX, anY, aZ));
1827 //=======================================================================
1828 //function : ConvertWithProj
1830 //=======================================================================
1831 void V3d_View::ConvertWithProj(const Standard_Integer Xp,
1832 const Standard_Integer Yp,
1838 Standard_Real& Dz) const
1840 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1841 Standard_Integer aHeight, aWidth;
1842 MyWindow->Size (aWidth, aHeight);
1844 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1845 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1846 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1848 Handle(Graphic3d_Camera) aCamera = Camera();
1850 gp_Pnt aResult = aCamera->UnProject (gp_Pnt (anX, anY, aZ));
1856 Graphic3d_Vertex aVrp;
1857 aVrp.SetCoord (X, Y, Z);
1859 aResult = aCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1861 Graphic3d_Vec3d aNormDir;
1862 aNormDir.x() = X - aResult.X();
1863 aNormDir.y() = Y - aResult.Y();
1864 aNormDir.z() = Z - aResult.Z();
1865 aNormDir.Normalize();
1872 //=======================================================================
1873 //function : Convert
1875 //=======================================================================
1876 void V3d_View::Convert(const Standard_Real X,
1877 const Standard_Real Y,
1878 const Standard_Real Z,
1879 Standard_Integer& Xp,
1880 Standard_Integer& Yp) const
1882 V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1883 Standard_Integer aHeight, aWidth;
1884 MyWindow->Size (aWidth, aHeight);
1886 gp_Pnt aPoint = Camera()->Project (gp_Pnt (X, Y, Z));
1888 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1889 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1892 //=======================================================================
1893 //function : Project
1895 //=======================================================================
1896 void V3d_View::Project (const Standard_Real theX,
1897 const Standard_Real theY,
1898 const Standard_Real theZ,
1899 Standard_Real& theXp,
1900 Standard_Real& theYp) const
1903 Project (theX, theY, theZ, theXp, theYp, aZp);
1906 //=======================================================================
1907 //function : Project
1909 //=======================================================================
1910 void V3d_View::Project (const Standard_Real theX,
1911 const Standard_Real theY,
1912 const Standard_Real theZ,
1913 Standard_Real& theXp,
1914 Standard_Real& theYp,
1915 Standard_Real& theZp) const
1917 Handle(Graphic3d_Camera) aCamera = Camera();
1919 gp_XYZ aViewSpaceDimensions = aCamera->ViewDimensions();
1920 Standard_Real aXSize = aViewSpaceDimensions.X();
1921 Standard_Real aYSize = aViewSpaceDimensions.Y();
1922 Standard_Real aZSize = aViewSpaceDimensions.Z();
1924 gp_Pnt aPoint = aCamera->Project (gp_Pnt (theX, theY, theZ));
1926 // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
1927 theXp = aPoint.X() * aXSize * 0.5;
1928 theYp = aPoint.Y() * aYSize * 0.5;
1929 theZp = aPoint.Z() * aZSize * 0.5;
1932 //=======================================================================
1933 //function : BackgroundColor
1935 //=======================================================================
1936 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1939 Standard_Real& V3) const
1941 Quantity_Color C = BackgroundColor() ;
1942 C.Values(V1,V2,V3,Type) ;
1945 //=======================================================================
1946 //function : BackgroundColor
1948 //=======================================================================
1949 Quantity_Color V3d_View::BackgroundColor() const
1951 return myView->Background().Color() ;
1954 //=======================================================================
1955 //function : GradientBackgroundColors
1957 //=======================================================================
1958 void V3d_View::GradientBackgroundColors (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1960 myView->GradientBackground().Colors (theColor1, theColor2);
1963 //=======================================================================
1964 //function : GradientBackground
1966 //=======================================================================
1967 Aspect_GradientBackground V3d_View::GradientBackground() const
1969 return myView->GradientBackground();
1972 //=======================================================================
1975 //=======================================================================
1976 Standard_Real V3d_View::Scale() const
1978 return myDefaultCamera->Scale() / Camera()->Scale();
1981 //=======================================================================
1982 //function : AxialScale
1984 //=======================================================================
1985 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1987 gp_Pnt anAxialScale = Camera()->AxialScale();
1988 Sx = anAxialScale.X();
1989 Sy = anAxialScale.Y();
1990 Sz = anAxialScale.Z();
1993 //=======================================================================
1996 //=======================================================================
1997 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1999 gp_Pnt aViewDims = Camera()->ViewDimensions();
2001 Width = aViewDims.X();
2002 Height = aViewDims.Y();
2005 //=======================================================================
2008 //=======================================================================
2009 Standard_Real V3d_View::ZSize() const
2011 gp_Pnt aViewDims = Camera()->ViewDimensions();
2013 return aViewDims.Z();
2016 //=======================================================================
2019 //=======================================================================
2020 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
2021 Standard_Real& Vmin,
2022 Standard_Real& Umax,
2023 Standard_Real& Vmax) const
2025 Standard_Real Wmin,Wmax,U,V,W ;
2026 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
2028 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
2031 Bnd_Box aBox = myView->MinMaxValues();
2032 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2033 Project (Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
2034 Project (Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
2035 Project (Xmin,Ymin,Zmax,U,V,W) ;
2036 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2037 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2038 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2039 Project (Xmax,Ymin,Zmax,U,V,W) ;
2040 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2041 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2042 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2043 Project (Xmax,Ymin,Zmin,U,V,W) ;
2044 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2045 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2046 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2047 Project (Xmax,Ymax,Zmin,U,V,W) ;
2048 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2049 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2050 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2051 Project (Xmin,Ymax,Zmax,U,V,W) ;
2052 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2053 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2054 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2055 Project (Xmin,Ymax,Zmin,U,V,W) ;
2056 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2057 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2058 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2063 //=======================================================================
2066 //=======================================================================
2067 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
2068 Standard_Real& Ymin,
2069 Standard_Real& Zmin,
2070 Standard_Real& Xmax,
2071 Standard_Real& Ymax,
2072 Standard_Real& Zmax) const
2075 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
2076 Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
2079 Bnd_Box aBox = myView->MinMaxValues();
2080 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2085 //=======================================================================
2086 //function : Gravity
2088 //=======================================================================
2089 void V3d_View::Gravity (Standard_Real& theX,
2090 Standard_Real& theY,
2091 Standard_Real& theZ) const
2093 Graphic3d_MapOfStructure aSetOfStructures;
2094 myView->DisplayedStructures (aSetOfStructures);
2096 Standard_Boolean hasSelection = Standard_False;
2097 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2098 aStructIter.More(); aStructIter.Next())
2100 if (aStructIter.Key()->IsHighlighted()
2101 && aStructIter.Key()->IsVisible())
2103 hasSelection = Standard_True;
2108 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
2109 Standard_Integer aNbPoints = 0;
2110 gp_XYZ aResult (0.0, 0.0, 0.0);
2111 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2112 aStructIter.More(); aStructIter.Next())
2114 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2115 if (!aStruct->IsVisible()
2116 || aStruct->IsInfinite()
2117 || (hasSelection && !aStruct->IsHighlighted()))
2122 const Graphic3d_BndBox4f& aBox = aStruct->CStructure()->BoundingBox();
2123 if (!aBox.IsValid())
2128 // skip transformation-persistent objects
2129 if (aStruct->TransformPersistence().Flags != Graphic3d_TMF_None)
2134 // use camera projection to find gravity point
2135 Xmin = (Standard_Real )aBox.CornerMin().x();
2136 Ymin = (Standard_Real )aBox.CornerMin().y();
2137 Zmin = (Standard_Real )aBox.CornerMin().z();
2138 Xmax = (Standard_Real )aBox.CornerMax().x();
2139 Ymax = (Standard_Real )aBox.CornerMax().y();
2140 Zmax = (Standard_Real )aBox.CornerMax().z();
2141 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2143 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2144 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2145 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2146 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2149 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2151 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2152 const gp_Pnt aProjected = Camera()->Project (aBndPnt);
2153 if (Abs (aProjected.X()) <= 1.0
2154 && Abs (aProjected.Y()) <= 1.0)
2156 aResult += aBndPnt.XYZ();
2164 // fallback - just use bounding box of entire scene
2165 Bnd_Box aBox = myView->MinMaxValues();
2168 aBox.Get (Xmin, Ymin, Zmin,
2170 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2172 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2173 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2174 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2175 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2178 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2180 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2181 aResult += aBndPnt.XYZ();
2189 aResult /= aNbPoints;
2196 //=======================================================================
2199 //=======================================================================
2200 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2202 gp_Pnt aCameraEye = Camera()->Eye();
2208 //=============================================================================
2209 //function : FocalReferencePoint
2211 //=============================================================================
2212 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2217 //=============================================================================
2218 //function : ProjReferenceAxe
2220 //=============================================================================
2221 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2222 const Standard_Integer Ypix,
2228 Standard_Real& VZ) const
2230 Standard_Real Xo,Yo,Zo;
2232 Convert (Xpix, Ypix, XP, YP, ZP);
2233 if ( Type() == V3d_PERSPECTIVE )
2235 FocalReferencePoint (Xo,Yo,Zo);
2246 //=============================================================================
2249 //=============================================================================
2250 Standard_Real V3d_View::Depth() const
2252 return Camera()->Distance();
2255 //=============================================================================
2258 //=============================================================================
2259 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2261 gp_Dir aCameraDir = Camera()->Direction().Reversed();
2262 Dx = aCameraDir.X();
2263 Dy = aCameraDir.Y();
2264 Dz = aCameraDir.Z();
2267 //=============================================================================
2270 //=============================================================================
2271 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2273 gp_Pnt aCameraCenter = Camera()->Center();
2274 X = aCameraCenter.X();
2275 Y = aCameraCenter.Y();
2276 Z = aCameraCenter.Z();
2279 //=============================================================================
2282 //=============================================================================
2283 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2285 gp_Dir aCameraUp = Camera()->Up();
2291 //=============================================================================
2294 //=============================================================================
2295 Standard_Real V3d_View::Twist() const
2297 Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2298 Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
2299 Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
2300 Standard_Boolean TheStatus ;
2302 gp_Dir aReferencePlane (Camera()->Direction().Reversed());
2306 anUp = gp_Dir (0.,0.,1.) ;
2307 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2309 anUp = gp_Dir (0.,1.,0.) ;
2310 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2313 anUp = gp_Dir (1.,0.,0.) ;
2314 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2316 Yaxis.Coord(X0,Y0,Z0) ;
2319 /* Compute Cross Vector From Up & Origin */
2320 pvx = Y0*Zup - Z0*Yup ;
2321 pvy = Z0*Xup - X0*Zup ;
2322 pvz = X0*Yup - Y0*Xup ;
2323 pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2324 sca = X0*Xup + Y0*Yup + Z0*Zup ;
2327 if( angle > 1. ) angle = 1. ;
2328 else if( angle < -1. ) angle = -1. ;
2329 angle = asin(angle) ;
2330 if( sca < 0. ) angle = M_PI - angle ;
2331 if( angle > 0. && angle < M_PI ) {
2332 sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2333 if( sca < 0. ) angle = DEUXPI - angle ;
2338 //=============================================================================
2339 //function : ShadingModel
2341 //=============================================================================
2342 V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2344 return static_cast<V3d_TypeOfShadingModel> (myView->ShadingModel());
2347 //=============================================================================
2348 //function : TextureEnv
2350 //=============================================================================
2351 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2353 return myView->TextureEnv();
2356 //=============================================================================
2357 //function : Visualization
2359 //=============================================================================
2360 V3d_TypeOfVisualization V3d_View::Visualization() const
2362 return static_cast<V3d_TypeOfVisualization> (myView->VisualizationType());
2365 //=============================================================================
2368 //=============================================================================
2369 Handle(V3d_Viewer) V3d_View::Viewer() const
2374 //=============================================================================
2375 //function : IfWindow
2377 //=============================================================================
2378 Standard_Boolean V3d_View::IfWindow() const
2380 return myView->IsDefined();
2383 //=============================================================================
2386 //=============================================================================
2387 Handle(Aspect_Window) V3d_View::Window() const
2392 //=============================================================================
2395 //=============================================================================
2396 V3d_TypeOfView V3d_View::Type() const
2398 return Camera()->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2401 //=============================================================================
2402 //function : SetFocale
2404 //=============================================================================
2405 void V3d_View::SetFocale( const Standard_Real focale )
2407 Handle(Graphic3d_Camera) aCamera = Camera();
2409 if (aCamera->IsOrthographic())
2414 Standard_Real aFOVyRad = ATan (focale / (aCamera->Distance() * 2.0));
2416 aCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2421 //=============================================================================
2424 //=============================================================================
2425 Standard_Real V3d_View::Focale() const
2427 Handle(Graphic3d_Camera) aCamera = Camera();
2429 if (aCamera->IsOrthographic())
2434 return aCamera->Distance() * 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
2437 //=============================================================================
2440 //=============================================================================
2441 Handle(Graphic3d_CView) V3d_View::View() const
2446 //=============================================================================
2447 //function : ScreenAxis
2449 //=============================================================================
2450 Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2452 Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2453 Standard_Real dx1, dy1, dz1, xx, yy, zz;
2455 Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2456 Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2457 xx = Yup*Zpn - Zup*Ypn;
2458 yy = Zup*Xpn - Xup*Zpn;
2459 zz = Xup*Ypn - Yup*Xpn;
2460 Xaxe.SetCoord (xx, yy, zz);
2461 if (Xaxe.LengthZero()) return Standard_False;
2463 Xaxe.Coord(dx1, dy1, dz1);
2464 xx = Ypn*dz1 - Zpn*dy1;
2465 yy = Zpn*dx1 - Xpn*dz1;
2466 zz = Xpn*dy1 - Ypn*dx1;
2467 Yaxe.SetCoord (xx, yy, zz) ;
2468 if (Yaxe.LengthZero()) return Standard_False;
2471 Zaxe.SetCoord (Xpn, Ypn, Zpn);
2473 return Standard_True;
2476 //=============================================================================
2477 //function : TrsPoint
2479 //=============================================================================
2480 Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2482 Graphic3d_Vertex PP ;
2483 Standard_Real X,Y,Z,XX,YY,ZZ ;
2486 Standard_Integer lr, ur, lc, uc;
2487 lr = Matrix.LowerRow ();
2488 ur = Matrix.UpperRow ();
2489 lc = Matrix.LowerCol ();
2490 uc = Matrix.UpperCol ();
2491 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
2493 PP.SetCoord(X,Y,Z) ;
2497 XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2498 Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2500 YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2501 Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2503 ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2504 Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2505 PP.SetCoord(XX,YY,ZZ) ;
2509 //=======================================================================
2512 //=======================================================================
2513 void V3d_View::Pan (const Standard_Integer theDXp,
2514 const Standard_Integer theDYp,
2515 const Quantity_Factor theZoomFactor,
2516 const Standard_Boolean theToStart)
2518 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2521 //=======================================================================
2522 //function : Panning
2524 //=======================================================================
2525 void V3d_View::Panning (const Standard_Real theDXv,
2526 const Standard_Real theDYv,
2527 const Quantity_Factor theZoomFactor,
2528 const Standard_Boolean theToStart)
2530 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2532 Handle(Graphic3d_Camera) aCamera = Camera();
2536 myCamStartOpEye = aCamera->Eye();
2537 myCamStartOpCenter = aCamera->Center();
2540 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2542 gp_Pnt aViewDims = aCamera->ViewDimensions();
2544 aCamera->SetEye (myCamStartOpEye);
2545 aCamera->SetCenter (myCamStartOpCenter);
2546 Translate (aCamera, -theDXv, -theDYv);
2547 Scale (aCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2549 SetImmediateUpdate (wasUpdateEnabled);
2554 //=======================================================================
2557 //=======================================================================
2558 void V3d_View::Zoom (const Standard_Integer theXp1,
2559 const Standard_Integer theYp1,
2560 const Standard_Integer theXp2,
2561 const Standard_Integer theYp2)
2563 Standard_Integer aDx = theXp2 - theXp1;
2564 Standard_Integer aDy = theYp2 - theYp1;
2565 if (aDx != 0 || aDy != 0)
2567 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2568 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2569 SetZoom (aCoeff, Standard_True);
2573 //=======================================================================
2574 //function : StartZoomAtPoint
2576 //=======================================================================
2577 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2578 const Standard_Integer theYp)
2580 MyZoomAtPointX = theXp;
2581 MyZoomAtPointY = theYp;
2584 //=======================================================================
2585 //function : ZoomAtPoint
2587 //=======================================================================
2588 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2589 const Standard_Integer theMouseStartY,
2590 const Standard_Integer theMouseEndX,
2591 const Standard_Integer theMouseEndY)
2593 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2596 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2597 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2598 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2600 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2602 Handle(Graphic3d_Camera) aCamera = Camera();
2604 Standard_Real aViewWidth = aCamera->ViewDimensions().X();
2605 Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
2607 // ensure that zoom will not be too small or too big.
2608 Standard_Real aCoef = aDZoom;
2609 if (aViewWidth < aCoef * Precision::Confusion())
2611 aCoef = aViewWidth / Precision::Confusion();
2613 else if (aViewWidth > aCoef * 1e12)
2615 aCoef = aViewWidth / 1e12;
2617 if (aViewHeight < aCoef * Precision::Confusion())
2619 aCoef = aViewHeight / Precision::Confusion();
2621 else if (aViewHeight > aCoef * 1e12)
2623 aCoef = aViewHeight / 1e12;
2626 Standard_Real aZoomAtPointXv = 0.0;
2627 Standard_Real aZoomAtPointYv = 0.0;
2628 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2630 V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
2631 V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
2633 aCamera->SetScale (aCamera->Scale() / aCoef);
2634 Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2638 SetImmediateUpdate (wasUpdateEnabled);
2643 //=============================================================================
2644 //function : AxialScale
2646 //=============================================================================
2647 void V3d_View::AxialScale (const Standard_Integer Dx,
2648 const Standard_Integer Dy,
2649 const V3d_TypeOfAxe Axis)
2651 if( Dx != 0. || Dy != 0. ) {
2652 Standard_Real Sx, Sy, Sz;
2653 AxialScale( Sx, Sy, Sz );
2654 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2655 dscale = (Dx > 0) ? dscale : 1./dscale;
2656 if( Axis == V3d_X ) Sx = dscale;
2657 if( Axis == V3d_Y ) Sy = dscale;
2658 if( Axis == V3d_Z ) Sz = dscale;
2659 SetAxialScale( Sx, Sy, Sz );
2663 //=============================================================================
2666 //=============================================================================
2667 void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
2668 const Standard_Real Xmin,
2669 const Standard_Real Ymin,
2670 const Standard_Real Xmax,
2671 const Standard_Real Ymax)
2673 Standard_Integer aWinWidth, aWinHeight;
2674 aWindow->Size (aWinWidth, aWinHeight);
2676 Standard_Real aWinAspect = (Standard_Real)aWinWidth / aWinHeight;
2677 Standard_Real aFitSizeU = Abs (Xmax - Xmin);
2678 Standard_Real aFitSizeV = Abs (Ymax - Ymin);
2679 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2680 if (aFitAspect >= aWinAspect)
2682 aFitSizeV = aFitSizeU / aWinAspect;
2686 aFitSizeU = aFitSizeV * aWinAspect;
2689 Handle(Graphic3d_Camera) aCamera = Camera();
2691 aCamera->SetAspect (aWinAspect);
2692 Translate (aCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
2693 Scale (aCamera, aFitSizeU, aFitSizeV);
2700 //=============================================================================
2701 //function : StartRotation
2703 //=============================================================================
2704 void V3d_View::StartRotation(const Standard_Integer X,
2705 const Standard_Integer Y,
2706 const Quantity_Ratio zRotationThreshold)
2711 rx = Standard_Real(Convert(x));
2712 ry = Standard_Real(Convert(y));
2714 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2715 myZRotation = Standard_False;
2716 if( zRotationThreshold > 0. ) {
2717 Standard_Real dx = Abs(sx - rx/2.);
2718 Standard_Real dy = Abs(sy - ry/2.);
2719 // if( dx > rx/3. || dy > ry/3. ) myZRotation = Standard_True;
2720 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2721 if( dx > dd || dy > dd ) myZRotation = Standard_True;
2726 //=============================================================================
2727 //function : Rotation
2729 //=============================================================================
2730 void V3d_View::Rotation(const Standard_Integer X,
2731 const Standard_Integer Y)
2733 if( rx == 0. || ry == 0. ) {
2737 Standard_Real dx=0.,dy=0.,dz=0.;
2739 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2740 atan2(sx-rx/2.,ry/2.-sy);
2742 dx = (Standard_Real(X) - sx) * M_PI / rx;
2743 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2746 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2749 //=============================================================================
2750 //function : SetComputedMode
2752 //=============================================================================
2753 void V3d_View::SetComputedMode (const Standard_Boolean theMode)
2759 myView->SetComputedMode (Standard_True);
2765 myView->SetComputedMode (Standard_False);
2770 //=============================================================================
2771 //function : ComputedMode
2773 //=============================================================================
2774 Standard_Boolean V3d_View::ComputedMode() const
2776 return myView->ComputedMode();
2779 //=============================================================================
2780 //function : SetBackFacingModel
2782 //=============================================================================
2783 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel theModel)
2785 myView->SetBackfacingModel (static_cast<Graphic3d_TypeOfBackfacingModel> (theModel));
2789 //=============================================================================
2790 //function : BackFacingModel
2792 //=============================================================================
2793 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2795 return static_cast<V3d_TypeOfBackfacingModel> (myView->BackfacingModel());
2798 //=============================================================================
2801 //=============================================================================
2802 void V3d_View::Init()
2804 myComputedMode = MyViewer->ComputedMode();
2805 if (!myComputedMode || !MyViewer->DefaultComputedMode())
2807 SetComputedMode (Standard_False);
2811 //=============================================================================
2814 //=============================================================================
2815 Standard_Boolean V3d_View::Export (const Standard_CString theFileName,
2816 const Graphic3d_ExportFormat theFormat,
2817 const Graphic3d_SortType theSortType)
2819 return myView->Export (theFileName, theFormat, theSortType);
2822 //=============================================================================
2825 //=============================================================================
2826 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2827 const Graphic3d_BufferType& theBufferType)
2829 Standard_Integer aWinWidth, aWinHeight;
2830 MyWindow->Size (aWinWidth, aWinHeight);
2831 Image_AlienPixMap anImage;
2833 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2836 //=============================================================================
2837 //function : ToPixMap
2839 //=============================================================================
2840 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
2841 const V3d_ImageDumpOptions& theParams)
2843 Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
2844 if (aTargetSize.x() != 0
2845 && aTargetSize.y() != 0)
2847 // allocate image buffer for dumping
2848 if (theImage.IsEmpty()
2849 || theImage.SizeX() != Standard_Size(aTargetSize.x())
2850 || theImage.SizeY() != Standard_Size(aTargetSize.y()))
2852 const bool isBigEndian = Image_PixMap::IsBigEndianHost();
2853 Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
2854 switch (theParams.BufferType)
2856 case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
2857 case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
2858 case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
2861 if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
2863 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y()
2864 + " for view dump", Message_Fail);
2865 return Standard_False;
2869 if (theImage.IsEmpty())
2871 Message::DefaultMessenger()->Send (TCollection_AsciiString ("V3d_View::ToPixMap() has been called without image dimensions"), Message_Fail);
2872 return Standard_False;
2874 aTargetSize.x() = (Standard_Integer )theImage.SizeX();
2875 aTargetSize.y() = (Standard_Integer )theImage.SizeY();
2877 Handle(Standard_Transient) aFBOPtr;
2878 Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
2879 Graphic3d_Vec2i aFBOVPSize = aTargetSize;
2881 bool isTiling = false;
2882 if (theParams.TileSize > 0)
2884 if (aFBOVPSize.x() > theParams.TileSize
2885 || aFBOVPSize.y() > theParams.TileSize)
2887 aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
2888 aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
2893 Graphic3d_Vec2i aPrevFBOVPSize;
2894 if (!aPrevFBOPtr.IsNull())
2896 Graphic3d_Vec2i aPrevFBOSizeMax;
2897 myView->FBOGetDimensions (aPrevFBOPtr,
2898 aPrevFBOVPSize.x(), aPrevFBOVPSize.y(),
2899 aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
2900 if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
2901 && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
2903 aFBOPtr = aPrevFBOPtr;
2907 if (aFBOPtr.IsNull())
2909 Standard_Integer aMaxTexSize = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxTextureSize);
2910 if (theParams.TileSize > aMaxTexSize)
2912 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
2913 + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSize + ")", Message_Fail);
2914 return Standard_False;
2917 if (aFBOVPSize.x() > aMaxTexSize
2918 || aFBOVPSize.y() > aMaxTexSize)
2920 aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSize);
2921 aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSize);
2925 // Try to create hardware accelerated buffer
2926 aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
2928 myView->SetFBO (aFBOPtr);
2930 if (aFBOPtr.IsNull())
2932 // try to use on-screen buffer
2933 Graphic3d_Vec2i aWinSize;
2934 MyWindow->Size (aWinSize.x(), aWinSize.y());
2935 if (aFBOVPSize.x() != aWinSize.x()
2936 || aFBOVPSize.y() != aWinSize.y())
2940 aFBOVPSize = aWinSize;
2942 Message::DefaultMessenger()->Send (TCollection_AsciiString ("Warning, on screen buffer is used for image dump - content might be invalid"), Message_Warning);
2945 // backup camera parameters
2946 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2947 Handle(Graphic3d_Camera) aCamera = Camera();
2948 aStoreMapping->Copy (aCamera);
2949 if (aCamera->IsStereo())
2951 switch (theParams.StereoOptions)
2955 aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2958 case V3d_SDO_LEFT_EYE:
2960 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2963 case V3d_SDO_RIGHT_EYE:
2965 aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2968 case V3d_SDO_BLENDED:
2970 break; // dump as is
2974 if (theParams.ToAdjustAspect)
2976 aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
2980 // render immediate structures into back buffer rather than front
2981 const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
2983 Standard_Boolean isSuccess = Standard_True;
2986 if (!aFBOPtr.IsNull())
2988 myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
2991 isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
2995 Image_PixMap aTilePixMap;
2996 aTilePixMap.SetTopDown (theImage.IsTopDown());
2998 Graphic3d_Vec2i anOffset (0, 0);
2999 for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
3002 for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
3004 Graphic3d_CameraTile aTile;
3005 aTile.Offset = anOffset;
3006 aTile.TotalSize = aTargetSize;
3007 aTile.TileSize = aFBOVPSize;
3008 if (!aFBOPtr.IsNull())
3010 // crop corners in case of FBO
3011 // (no API to resize viewport of on-screen buffer - keep uncropped in this case)
3012 aTile = aTile.Cropped();
3014 if (aTile.TileSize.x() < 1
3015 || aTile.TileSize.y() < 1)
3020 const Standard_Integer aLeft = aTile.Offset.x();
3021 Standard_Integer aBottom = aTile.Offset.y();
3022 if (theImage.IsTopDown())
3024 const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
3025 aBottom = aTargetSize.y() - aTop;
3027 aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
3028 + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
3029 aTile.TileSize.x(), aTile.TileSize.y(),
3030 theImage.SizeRowBytes());
3032 aCamera->SetTile (aTile);
3033 if (!aFBOPtr.IsNull())
3035 myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
3038 isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
3052 myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
3053 aCamera->Copy (aStoreMapping);
3054 if (aFBOPtr != aPrevFBOPtr)
3056 myView->FBORelease (aFBOPtr);
3058 else if (!aPrevFBOPtr.IsNull())
3060 myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
3062 myView->SetFBO (aPrevFBOPtr);
3066 //=============================================================================
3067 //function : ImmediateUpdate
3069 //=============================================================================
3070 void V3d_View::ImmediateUpdate() const
3072 if (myImmediateUpdate)
3078 //=============================================================================
3079 //function : SetImmediateUpdate
3081 //=============================================================================
3082 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
3084 Standard_Boolean aPreviousMode = myImmediateUpdate;
3085 myImmediateUpdate = theImmediateUpdate;
3086 return aPreviousMode;
3089 // =======================================================================
3090 // function : SetCamera
3092 // =======================================================================
3093 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
3095 myView->SetCamera (theCamera);
3100 // =======================================================================
3101 // function : GetCamera
3103 // =======================================================================
3104 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
3106 return myView->Camera();
3109 // =======================================================================
3110 // function : FitMinMax
3111 // purpose : Internal
3112 // =======================================================================
3113 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
3114 const Bnd_Box& theBox,
3115 const Standard_Real theMargin,
3116 const Standard_Real theResolution,
3117 const Standard_Boolean theToEnlargeIfLine) const
3119 // Check bounding box for validness
3120 if (theBox.IsVoid())
3122 return Standard_False; // bounding box is out of bounds...
3125 // Apply "axial scaling" to the bounding points.
3126 // It is not the best approach to make this scaling as a part of fit all operation,
3127 // but the axial scale is integrated into camera orientation matrix and the other
3128 // option is to perform frustum plane adjustment algorithm in view camera space,
3129 // which will lead to a number of additional world-view space conversions and
3130 // loosing precision as well.
3131 gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (theCamera->AxialScale());
3132 gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (theCamera->AxialScale());
3134 if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
3136 return Standard_False; // nothing to fit all
3139 // Prepare camera frustum planes.
3140 NCollection_Array1<gp_Pln> aFrustumPlane (1, 6);
3141 theCamera->Frustum (aFrustumPlane.ChangeValue (1),
3142 aFrustumPlane.ChangeValue (2),
3143 aFrustumPlane.ChangeValue (3),
3144 aFrustumPlane.ChangeValue (4),
3145 aFrustumPlane.ChangeValue (5),
3146 aFrustumPlane.ChangeValue (6));
3148 // Prepare camera up, side, direction vectors.
3149 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3150 gp_Dir aCamDir = theCamera->Direction();
3151 gp_Dir aCamSide = aCamDir ^ aCamUp;
3153 // Prepare scene bounding box parameters.
3154 gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
3156 NCollection_Array1<gp_Pnt> aBndCorner (1, 8);
3157 aBndCorner.ChangeValue (1) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
3158 aBndCorner.ChangeValue (2) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
3159 aBndCorner.ChangeValue (3) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
3160 aBndCorner.ChangeValue (4) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
3161 aBndCorner.ChangeValue (5) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
3162 aBndCorner.ChangeValue (6) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
3163 aBndCorner.ChangeValue (7) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
3164 aBndCorner.ChangeValue (8) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
3166 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3167 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3168 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3169 // set up perspective-correct camera projection matching the bounding box.
3170 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3171 // The zooming can be done by calculating view plane size matching the bounding box at center of
3172 // the bounding box. The only limitation here is that the scale of camera should define size of
3173 // its view plane passing through the camera center, and the center of camera should be on the
3174 // same line with the center of bounding box.
3176 // The following method is applied:
3177 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3178 // 2) Determine new location of frustum planes, "matching" the bounding box.
3179 // 3) Determine new camera projection vector using the normalized asymmetry.
3180 // 4) Determine new zooming in view space.
3182 // 1. Determine normalized projection asymmetry (if any).
3183 Standard_Real anAssymX = Tan (( aCamSide).Angle (aFrustumPlane (1).Axis().Direction()))
3184 - Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction()));
3185 Standard_Real anAssymY = Tan (( aCamUp) .Angle (aFrustumPlane (3).Axis().Direction()))
3186 - Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction()));
3188 // 2. Determine how far should be the frustum planes placed from center
3189 // of bounding box, in order to match the bounding box closely.
3190 NCollection_Array1<Standard_Real> aFitDistance (1, 6);
3191 aFitDistance.ChangeValue (1) = 0.0;
3192 aFitDistance.ChangeValue (2) = 0.0;
3193 aFitDistance.ChangeValue (3) = 0.0;
3194 aFitDistance.ChangeValue (4) = 0.0;
3195 aFitDistance.ChangeValue (5) = 0.0;
3196 aFitDistance.ChangeValue (6) = 0.0;
3198 for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
3200 // Measure distances from center of bounding box to its corners towards the frustum plane.
3201 const gp_Dir& aPlaneN = aFrustumPlane.ChangeValue (anI).Axis().Direction();
3203 Standard_Real& aFitDist = aFitDistance.ChangeValue (anI);
3205 for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
3207 aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner (aJ)).Dot (aPlaneN));
3210 // The center of camera is placed on the same line with center of bounding box.
3211 // The view plane section crosses the bounding box at its center.
3212 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3213 // into view section size between the point and the frustum plane.
3215 // /|\ right half of frame //
3217 // point o<-- distance * coeff -->//---- (view plane section)
3226 aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan ( aCamSide .Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
3227 aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan ((-aCamSide).Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
3228 aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan ( aCamUp .Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
3229 aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan ((-aCamUp) .Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
3230 aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan ( aCamDir .Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
3231 aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan ((-aCamDir) .Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
3233 Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
3234 Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
3235 Standard_Real aViewSizeZv = aFitDistance (5) + aFitDistance (6);
3237 // 3. Place center of camera on the same line with center of bounding
3238 // box applying corresponding projection asymmetry (if any).
3239 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3240 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3241 Standard_Real anOffsetXv = (aFitDistance (2) - aFitDistance (1)) * 0.5 + anAssymXv;
3242 Standard_Real anOffsetYv = (aFitDistance (4) - aFitDistance (3)) * 0.5 + anAssymYv;
3243 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3244 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3245 gp_Pnt aCamNewCenter = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3247 gp_Trsf aCenterTrsf;
3248 aCenterTrsf.SetTranslation (theCamera->Center(), aCamNewCenter);
3249 theCamera->Transform (aCenterTrsf);
3250 theCamera->SetDistance (aFitDistance (6) + aFitDistance (5));
3252 // Bounding box collapses to a point or thin line going in depth of the screen
3253 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3255 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3257 return Standard_True; // This is just one point or line and zooming has no effect.
3260 // Looking along line and "theToEnlargeIfLine" is requested.
3261 // Fit view to see whole scene on rotation.
3262 aViewSizeXv = aViewSizeZv;
3263 aViewSizeYv = aViewSizeZv;
3266 Scale (theCamera, aViewSizeXv, aViewSizeYv);
3268 const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
3270 Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
3272 return Standard_True;
3275 // =======================================================================
3277 // purpose : Internal
3278 // =======================================================================
3279 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3280 const Standard_Real theSizeXv,
3281 const Standard_Real theSizeYv) const
3283 Standard_Real anAspect = theCamera->Aspect();
3286 theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
3290 theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
3294 // =======================================================================
3295 // function : Translate
3296 // purpose : Internal
3297 // =======================================================================
3298 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3299 const Standard_Real theDXv,
3300 const Standard_Real theDYv) const
3302 const gp_Pnt& aCenter = theCamera->Center();
3303 const gp_Dir& aDir = theCamera->Direction();
3304 const gp_Dir& anUp = theCamera->Up();
3305 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3307 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3308 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3309 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3311 aPanTrsf.SetTranslation (aCameraPan);
3313 theCamera->Transform (aPanTrsf);
3316 // =======================================================================
3317 // function : IsCullingEnabled
3319 // =======================================================================
3320 Standard_Boolean V3d_View::IsCullingEnabled() const
3322 return myView->IsCullingEnabled();
3325 // =======================================================================
3326 // function : SetFrustumCulling
3328 // =======================================================================
3329 void V3d_View::SetFrustumCulling (const Standard_Boolean theToClip)
3331 myView->SetCullingEnabled (theToClip);