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 /***********************************************************************
20 HISTORIQUE DES MODIFICATIONS :
21 --------------------------------
22 00-09-92 : GG ; Creation.
23 02-10-96 : FMN ; Suppression appel Redraw sans MustBeResized()
24 05-06-97 : FMN ; Correction FitAll()
25 30-06-97 : GG ; Correction + Optimisation de Panning(...)
26 On fait la translation + le zoom en une seule
27 operation au lieu de 2 precedemment qui etait buggee.
28 09-07-97 : FMN ; Correction FitAll() sur le Ratio
29 16-07-97 : FMN ; Correction FitAll() sur le calcul de la Box
30 22-07-97 : FMN ; Ajout mode RetainMode pour le Transient
31 15-12-97 : FMN ; Ajout texture mapping
32 17-12-97 : FMN ; CTS19129 Correction FitAll() multiple
33 18-12-97 : FMN ; Ajout mode Ajout
34 24-12-97 : FMN ; Remplacement de math par MathGra
35 24-12-97 : CQO ; BUC50037 Xw_Window -> Aspect_Window
36 31-12-97 : CAL ; Remplacement de MathGra par Array2OfReal
37 07-01-98 : CAL ; Ajout de la methode DoMapping.
38 07-01-98 : CAL ; Retrait de tous les "this->" inutiles
39 21-01-98 : CAL ; Remplacement des Window->Position () par Window->Size ()
40 27-01-98 : FMN ; PERF: OPTIMISATION LOADER (LOPTIM)
41 12-02-98 : GG ; Reactivation du Redraw dans MustBeResized()
42 23-02-98 : FMN ; Remplacement PI par Standard_PI
43 25-02-98 : FMN ; PERF.27: Optimisation of view creation from existing view
44 11-03-98 : STT ; S3558
45 19-03-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
47 08-04-98 : STT ; suppr. S3558
48 10-04-98 : CAL ; Ajout des methodes RefToPix et PixToRef
49 13-06-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
50 ne marche pas. Contournement en appelant WNT_Window::Size(Int,Int).
51 16-08-98 : CAL ; S3892. Ajout grilles 3d.
52 09-09-98 : CAL ; S3892. Generalisation de TrsPoint.
53 06-10-98 : CAL ; Ajout d'un TIMER si CSF_GraphicTimer est definie.
54 16-10-98 : CAL ; Retrait d'un TIMER si CSF_GraphicTimer est definie.
55 06-11-98 : CAL ; PRO ?????. Probleme dans ZFitAll si un point dans la vue.
56 13-06-98 : FMN ; PRO14896: Correction sur la gestion de la perspective (cf Programming Guinde)
57 29-OCT-98 : DCB : Adding ScreenCopy () method.
58 10-11-99 : GG ; PRO19603 Add Redraw( area ) method
60 -> Don't increase too much the ZSize.
61 -> Initialize correctly the Z clipping and D cueing
63 IMP100701 : SZV ; Add ToPixMap() method
67 About FitAll() multiple. This probleme is caused by missing
68 precision of transformation matrices. If it is supposed that
69 projection is made in the plane (U,V), there is a difference
70 after several Zoom - compared to the exact value (cf ZoomX).
71 Don't forget that the matrices work in float and not in double.
72 To solve the problem (for lack of a better solution) I make 2 passes.
74 ************************************************************************/
76 //GER61351 //GG_15/12/99 Add SetBackgroundColor() and BackgroundColor() methods
79 #define IMP020300 //GG Don't use ZFitAll in during Rotation
80 // for perf improvment
82 #define IMP210600 //GG Avoid to have infinite loop when call Rotation() method
83 // without call before StartRotation().
84 // This problem occurs when CTRL MB3 is maintain press betwwen 2 views.
86 #define IMP250900 //GG Enable rotation around screen Z axis when
87 // rotation begin far the center of the screen.
88 // Thanks to Patrick REGINSTER (SAMTECH)
89 // GG 21/12/00 Due to a regression on the previous specifications
90 // this new functionnality is right now deactivated
91 // by default (see StartRotation(...,zRotationThreshold)
94 #define BUC60952 //GG Enable to rotate around the view axis
95 // and the required view point
97 #define IMP260302 //GG To avoid conflicting in Window destructor
98 // nullify this handle in Remove method
100 #define OCC280 //SAV fix for FitAll problem in the perspective view.
102 #define OCC1188 //SAV Added methods to set background image
104 /*----------------------------------------------------------------------*/
109 #include <Standard_TypeMismatch.hxx>
110 #include <Standard_ShortReal.hxx>
111 #include <Standard_Assert.hxx>
112 #include <Standard_ErrorHandler.hxx>
113 #include <Standard_DivideByZero.hxx>
115 #include <Visual3d_ViewManager.hxx>
116 #include <Visual3d_Light.hxx>
117 #include <Visual3d_Layer.hxx>
120 #include <V3d_View.ixx>
121 #include <V3d_BadValue.hxx>
122 #include <V3d_StereoDumpOptions.hxx>
124 #include <Image_AlienPixMap.hxx>
126 #include <gp_Dir.hxx>
127 #include <gp_Pln.hxx>
128 #include <TColStd_Array2OfReal.hxx>
129 #include <TColStd_HSequenceOfInteger.hxx>
131 #include <Bnd_Box.hxx>
133 #include <Precision.hxx>
135 #include <Graphic3d_Structure.hxx>
136 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
137 #include <Graphic3d_MapOfStructure.hxx>
138 #include <Graphic3d_TextureEnv.hxx>
139 #include <Graphic3d_AspectMarker3d.hxx>
140 #include <Graphic3d_GraphicDriver.hxx>
142 #define V3d_FLAG_COMPUTATION 0x00000004
145 #include <OSD_Environment.hxx>
147 /*----------------------------------------------------------------------*/
152 #define DEUXPI (2. * M_PI)
154 //=============================================================================
155 //function : Constructor
157 //=============================================================================
158 V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) :
159 MyViewer(VM.operator->()),
162 myActiveLightsIterator(),
163 SwitchSetFront(Standard_False),
166 myImmediateUpdate = Standard_False;
167 MyView = new Visual3d_View(MyViewer->Viewer());
169 // { Begin to retrieve the definition from ViewContext.
170 // Step MyViewContext = MyView->Context() ;
171 // to permit MyView->SetContext to compare
172 // the old and the new context.
173 // No problem for MyViewMapping, MyViewOrientation
174 // as MyView->SetViewMapping and MyView->SetViewOrientation
175 // don't try to optimize the modifications introduced to
176 // viewmapping and vieworientation.
179 if ((MyView->Context ()).AliasingIsOn ())
180 MyViewContext.SetAliasingOn ();
182 MyViewContext.SetAliasingOff ();
185 MyViewContext.SetDepthCueingBackPlane
186 ((MyView->Context ()).DepthCueingBackPlane ());
187 MyViewContext.SetDepthCueingFrontPlane
188 ((MyView->Context ()).DepthCueingFrontPlane ());
190 if ((MyView->Context ()).DepthCueingIsOn ())
191 MyViewContext.SetDepthCueingOn ();
193 MyViewContext.SetDepthCueingOff ();
196 MyViewContext.SetZClippingBackPlane
197 ((MyView->Context ()).ZClippingBackPlane ());
198 MyViewContext.SetZClippingFrontPlane
199 ((MyView->Context ()).ZClippingFrontPlane ());
201 if ((MyView->Context ()).FrontZClippingIsOn ())
202 MyViewContext.SetFrontZClippingOn ();
204 MyViewContext.SetFrontZClippingOff ();
206 if ((MyView->Context ()).BackZClippingIsOn ())
207 MyViewContext.SetBackZClippingOn ();
209 MyViewContext.SetBackZClippingOff ();
211 // Visualization and Shading Model
212 MyViewContext.SetModel ((MyView->Context ()).Model ());
213 MyViewContext.SetVisualization ((MyView->Context ()).Visualization ());
216 MyViewContext.SetSurfaceDetail (MyView->Context ().SurfaceDetail ());
217 MyViewContext.SetTextureEnv (MyView->Context ().TextureEnv ());
218 // } End of retrieval of the definition of ViewContext.
220 MyBackground = VM->GetBackgroundColor() ;
221 MyGradientBackground = VM->GetGradientBackground() ;
224 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
225 aCamera->SetFOVy (45.0);
226 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
227 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
230 SetAxis (0.,0.,0.,1.,1.,1.);
231 SetVisualization (VM->DefaultVisualization());
232 SetShadingModel (VM->DefaultShadingModel());
233 SetSurfaceDetail (VM->DefaultSurfaceDetail());
236 SetProj (VM->DefaultViewProj());
237 SetSize (VM->DefaultViewSize());
238 Standard_Real zsize = VM->DefaultViewSize();
240 SetZClippingDepth (0.);
241 SetZClippingWidth (zsize);
242 SetZCueingDepth (0.);
243 SetZCueingWidth (zsize);
244 SetDepth (VM->DefaultViewSize()/2.0);
245 SetViewMappingDefault();
246 SetViewOrientationDefault();
249 myImmediateUpdate = Standard_True;
251 aCamera->SetProjectionType ((Type == V3d_ORTHOGRAPHIC)
252 ? Graphic3d_Camera::Projection_Orthographic
253 : Graphic3d_Camera::Projection_Perspective);
255 MyTransparencyFlag = Standard_False;
258 //=============================================================================
259 //function : Constructor
261 //=============================================================================
262 V3d_View::V3d_View(const Handle(V3d_Viewer)& theVM,const Handle(V3d_View)& theView) :
263 MyViewer(theVM.operator->()),
266 myActiveLightsIterator(),
267 SwitchSetFront(Standard_False),
270 Handle(Visual3d_View) aFromView = theView->View();
272 myImmediateUpdate = Standard_False;
273 MyView = new Visual3d_View (MyViewer->Viewer());
275 for (theView->InitActiveLights(); theView->MoreActiveLights(); theView->NextActiveLights())
277 MyActiveLights.Append (theView->ActiveLight());
280 MyViewContext = aFromView->Context() ;
282 SetCamera (new Graphic3d_Camera (theView->Camera()));
283 View()->SetAutoZFitMode (theView->View()->AutoZFitMode(), theView->View()->AutoZFitScaleFactor());
285 MyBackground = aFromView->Background() ;
286 MyGradientBackground = aFromView->GradientBackground();
288 MyView->SetContext (MyViewContext) ;
290 SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
292 SetViewMappingDefault();
293 SetViewOrientationDefault();
294 theVM->AddView (this);
298 myImmediateUpdate = Standard_True;
301 //=============================================================================
302 //function : SetMagnify
304 //=============================================================================
305 void V3d_View::SetMagnify(const Handle(Aspect_Window)& TheWindow,
306 const Handle(V3d_View)& aPreviousView,
307 const Standard_Integer x1,
308 const Standard_Integer y1,
309 const Standard_Integer x2,
310 const Standard_Integer y2)
312 if( !MyView->IsDefined() ) {
313 Standard_Real a,b,c,d;
314 aPreviousView->Convert(x1,y1,a,b);
315 aPreviousView->Convert(x2,y2,c,d);
316 MyView->SetWindow(TheWindow) ;
317 FitAll(TheWindow,a,b,c,d);
318 MyView->SetContext(MyViewContext) ;
319 MyView->SetBackground(MyBackground) ;
320 MyViewer->SetViewOn(this) ;
321 MyWindow = TheWindow;
323 SetViewMappingDefault();
327 //=============================================================================
328 //function : SetWindow
330 //=============================================================================
331 void V3d_View::SetWindow(const Handle(Aspect_Window)& TheWindow)
333 MyView->SetWindow(TheWindow) ;
334 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
335 MyWindow = TheWindow;
336 // SetWindow carries out SetRatio and modifies
337 MyView->SetContext(MyViewContext) ;
338 MyView->SetBackground(MyBackground) ;
339 MyViewer->SetViewOn(this) ;
343 //=============================================================================
344 //function : SetWindow
346 //=============================================================================
347 void V3d_View::SetWindow(const Handle(Aspect_Window)& aWindow,
348 const Aspect_RenderingContext aContext,
349 const Aspect_GraphicCallbackProc& aDisplayCB,
350 const Standard_Address aClientData)
352 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
354 MyView->SetWindow(aWindow, aContext, aDisplayCB, aClientData) ;
355 MyView->SetContext(MyViewContext) ;
356 MyView->SetBackground(MyBackground) ;
357 MyViewer->SetViewOn(this) ;
361 //=============================================================================
364 //=============================================================================
365 void V3d_View::Remove() const
367 MyViewer->DelView (this);
369 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
373 //=============================================================================
376 //=============================================================================
377 void V3d_View::Update() const
379 if( MyView->IsDefined() ) MyView->Update (Aspect_TOU_ASAP) ;
382 //=============================================================================
385 //=============================================================================
386 void V3d_View::Redraw() const
388 if( MyView->IsDefined() ) MyView->Redraw() ;
391 //=============================================================================
392 //function : RedrawImmediate
394 //=============================================================================
395 void V3d_View::RedrawImmediate() const
397 if (MyView->IsDefined())
399 MyView->RedrawImmediate();
403 //=============================================================================
404 //function : Invalidate
406 //=============================================================================
407 void V3d_View::Invalidate() const
409 if (MyView->IsDefined())
411 MyView->Invalidate();
415 //=============================================================================
416 //function : AutoZFit
418 //=============================================================================
419 void V3d_View::AutoZFit()
424 //=============================================================================
427 //=============================================================================
428 void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
430 View()->ZFitAll (theScaleFactor);
433 //=============================================================================
436 //=============================================================================
437 void V3d_View::Redraw(const Standard_Integer xc,const Standard_Integer yc,
438 const Standard_Integer width,const Standard_Integer height) const
440 if( MyView->IsDefined() ) MyView->Redraw(xc,yc,width,height) ;
443 //=============================================================================
446 //=============================================================================
447 Standard_Boolean V3d_View::IsEmpty() const
449 Standard_Boolean TheStatus = Standard_True ;
450 if( MyView->IsDefined() ) {
451 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
452 if( Nstruct > 0 ) TheStatus = Standard_False ;
457 //=============================================================================
458 //function : UpdateLights
460 //=============================================================================
461 void V3d_View::UpdateLights() const
463 MyView->SetContext(MyViewContext);
467 //=============================================================================
468 //function : DoMapping
470 //=============================================================================
471 void V3d_View::DoMapping()
473 if( MyView->IsDefined() ) {
474 (MyView->Window())->DoMapping() ;
478 //=============================================================================
479 //function : MustBeResized
481 //=============================================================================
482 void V3d_View::MustBeResized()
484 if ( !MyLayerMgr.IsNull() )
485 MyLayerMgr->Resized();
487 if( MyView->IsDefined() ) {
493 //=============================================================================
494 //function : SetBackgroundColor
496 //=============================================================================
497 void V3d_View::SetBackgroundColor(const Quantity_TypeOfColor Type, const Standard_Real v1, const Standard_Real v2, const Standard_Real v3)
499 Standard_Real V1 = Max( Min( v1, 1.0 ), 0.0 );
500 Standard_Real V2 = Max( Min( v2, 1.0 ), 0.0 );
501 Standard_Real V3 = Max( Min( v3, 1.0 ), 0.0 );
503 Quantity_Color C( V1, V2, V3, Type );
504 SetBackgroundColor( C );
507 //=============================================================================
508 //function : SetBackgroundColor
510 //=============================================================================
511 void V3d_View::SetBackgroundColor(const Quantity_Color &Color)
513 MyBackground.SetColor( Color );
514 if ( MyView->IsDefined() )
515 MyView->SetBackground( MyBackground );
517 if ( !MyLayerMgr.IsNull() )
518 MyLayerMgr->Resized();
521 //=============================================================================
522 //function : SetBackgroundColor
524 //=============================================================================
525 void V3d_View::SetBackgroundColor(const Quantity_NameOfColor Name)
527 Quantity_Color C( Name );
528 SetBackgroundColor( C );
531 //=============================================================================
532 //function : SetBgGradientColors
534 //=============================================================================
535 void V3d_View::SetBgGradientColors( const Quantity_Color& Color1,
536 const Quantity_Color& Color2,
537 const Aspect_GradientFillMethod FillStyle,
538 const Standard_Boolean status)
540 MyGradientBackground.SetColors(Color1, Color2, FillStyle);
541 if ( MyView->IsDefined() )
542 MyView->SetGradientBackground( MyGradientBackground, status );
545 //=============================================================================
546 //function : SetBgGradientColors
548 //=============================================================================
549 void V3d_View::SetBgGradientColors( const Quantity_NameOfColor Color1,
550 const Quantity_NameOfColor Color2,
551 const Aspect_GradientFillMethod FillStyle,
552 const Standard_Boolean status )
554 Quantity_Color C1( Color1 );
555 Quantity_Color C2( Color2 );
556 MyGradientBackground.SetColors( C1, C2, FillStyle );
557 if ( MyView->IsDefined() )
558 MyView->SetGradientBackground( MyGradientBackground, status );
561 //=============================================================================
562 //function : SetBgGradientStyle
564 //=============================================================================
565 void V3d_View::SetBgGradientStyle( const Aspect_GradientFillMethod FillStyle,
566 const Standard_Boolean update)
568 Quantity_Color Color1, Color2;
569 MyGradientBackground.Colors( Color1, Color2 );
570 MyGradientBackground.SetColors( Color1, Color2, FillStyle );
571 if( MyView->IsDefined() )
572 MyView->SetBgGradientStyle( FillStyle, update ) ;
575 //=============================================================================
576 //function : SetBackgroundImage
578 //=============================================================================
579 void V3d_View::SetBackgroundImage( const Standard_CString FileName,
580 const Aspect_FillMethod FillStyle,
581 const Standard_Boolean update )
584 if( MyView->IsDefined() )
585 MyView->SetBackgroundImage( FileName, FillStyle, update ) ;
589 //=============================================================================
590 //function : SetBgImageStyle
592 //=============================================================================
593 void V3d_View::SetBgImageStyle( const Aspect_FillMethod FillStyle,
594 const Standard_Boolean update )
597 if( MyView->IsDefined() )
598 MyView->SetBgImageStyle( FillStyle, update ) ;
602 //=============================================================================
605 //=============================================================================
606 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)
608 Standard_Real D,Nx = Vx,Ny = Vy,Nz = Vz ;
610 D = Sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) ;
611 V3d_BadValue_Raise_if ( D <= 0. , "V3d_View::SetAxis, bad axis");
612 Nx /= D ; Ny /= D ; Nz /= D ;
613 MyDefaultViewPoint.SetCoord(X,Y,Z) ;
614 MyDefaultViewAxis.SetCoord(Nx,Ny,Nz) ;
617 //=============================================================================
618 //function : SetShadingModel
620 //=============================================================================
621 void V3d_View::SetShadingModel(const V3d_TypeOfShadingModel Model)
623 MyViewContext.SetModel((Visual3d_TypeOfModel) Model) ;
624 MyView->SetContext(MyViewContext) ;
627 //=============================================================================
628 //function : SetSurfaceDetail
630 //=============================================================================
631 void V3d_View::SetSurfaceDetail(const V3d_TypeOfSurfaceDetail Model)
633 MyViewContext.SetSurfaceDetail((Visual3d_TypeOfSurfaceDetail) Model) ;
634 MyView->SetContext(MyViewContext) ;
637 //=============================================================================
638 //function : SetTextureEnv
640 //=============================================================================
641 void V3d_View::SetTextureEnv(const Handle(Graphic3d_TextureEnv)& ATexture)
643 MyViewContext.SetTextureEnv(ATexture) ;
644 MyView->SetContext(MyViewContext) ;
647 //=============================================================================
648 //function : SetVisualization
650 //=============================================================================
651 void V3d_View::SetVisualization(const V3d_TypeOfVisualization Mode)
653 MyViewContext.SetVisualization((Visual3d_TypeOfVisualization) Mode);
654 MyView->SetContext(MyViewContext) ;
657 //=============================================================================
658 //function : SetFront
660 //=============================================================================
661 void V3d_View::SetFront()
663 gp_Ax3 a = MyViewer->PrivilegedPlane();
664 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
666 a.Direction().Coord(vx,vy,vz);
667 a.YDirection().Coord(xu,yu,zu);
668 a.Location().Coord(xo,yo,zo);
670 myCamera->SetCenter (gp_Pnt (xo, yo, zo));
672 myCamera->SetDirection (gp_Dir (vx, vy, vz));
674 myCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
675 myCamera->SetUp (gp_Dir (xu, yu, zu));
679 SwitchSetFront = !SwitchSetFront;
684 //=============================================================================
687 //=============================================================================
688 void V3d_View::Rotate (const Standard_Real ax,
689 const Standard_Real ay,
690 const Standard_Real az,
691 const Standard_Boolean Start)
693 Standard_Real Ax = ax;
694 Standard_Real Ay = ay;
695 Standard_Real Az = az;
697 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
698 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
699 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
700 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
701 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
702 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
706 myCamStartOpUp = myCamera->Up();
707 myCamStartOpEye = myCamera->Eye();
708 myCamStartOpCenter = myCamera->Center();
711 myCamera->SetUp (myCamStartOpUp);
712 myCamera->SetEye (myCamStartOpEye);
713 myCamera->SetCenter (myCamStartOpCenter);
715 // rotate camera around 3 initial axes
716 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
717 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
718 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
719 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
721 gp_Trsf aRot[3], aTrsf;
722 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
723 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
724 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
725 aTrsf.Multiply (aRot[0]);
726 aTrsf.Multiply (aRot[1]);
727 aTrsf.Multiply (aRot[2]);
729 myCamera->Transform (aTrsf);
736 //=============================================================================
739 //=============================================================================
740 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
741 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
744 Standard_Real Ax = ax ;
745 Standard_Real Ay = ay ;
746 Standard_Real Az = az ;
748 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
749 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
750 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
751 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
752 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
753 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
757 myGravityReferencePoint.SetCoord (X, Y, Z);
758 myCamStartOpUp = myCamera->Up();
759 myCamStartOpEye = myCamera->Eye();
760 myCamStartOpCenter = myCamera->Center();
763 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
765 myCamera->SetUp (myCamStartOpUp);
766 myCamera->SetEye (myCamStartOpEye);
767 myCamera->SetCenter (myCamStartOpCenter);
769 // rotate camera around 3 initial axes
770 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
772 gp_Dir aZAxis (myCamera->Direction().Reversed());
773 gp_Dir aYAxis (myCamera->Up());
774 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
776 gp_Trsf aRot[3], aTrsf;
777 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
778 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
779 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
780 aTrsf.Multiply (aRot[0]);
781 aTrsf.Multiply (aRot[1]);
782 aTrsf.Multiply (aRot[2]);
784 myCamera->Transform (aTrsf);
791 //=============================================================================
794 //=============================================================================
795 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
799 Rotate(angle,0.,0.,Start);
802 Rotate(0.,angle,0.,Start);
805 Rotate(0.,0.,angle,Start);
810 //=============================================================================
813 //=============================================================================
814 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
815 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
817 Standard_Real Angle = angle ;
819 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
820 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
824 myGravityReferencePoint.SetCoord (X, Y, Z);
825 myCamStartOpUp = myCamera->Up();
826 myCamStartOpEye = myCamera->Eye();
827 myCamStartOpCenter = myCamera->Center();
831 myViewAxis.SetCoord(1.,0.,0.) ;
834 myViewAxis.SetCoord(0.,1.,0.) ;
837 myViewAxis.SetCoord(0.,0.,1.) ;
841 myCamStartOpUp = myCamera->Up();
842 myCamStartOpEye = myCamera->Eye();
843 myCamStartOpCenter = myCamera->Center();
846 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
848 myCamera->SetUp (myCamStartOpUp);
849 myCamera->SetEye (myCamStartOpEye);
850 myCamera->SetCenter (myCamStartOpCenter);
852 // rotate camera around passed axis
854 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
855 gp_Dir aRAxis ((Axe == V3d_X) ? 1.0 : 0.0,
856 (Axe == V3d_Y) ? 1.0 : 0.0,
857 (Axe == V3d_Z) ? 1.0 : 0.0);
859 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
860 myCamera->Transform (aRotation);
867 //=============================================================================
870 //=============================================================================
871 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
873 Standard_Real Angle = angle;
875 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
876 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
879 myCamStartOpUp = myCamera->Up();
880 myCamStartOpEye = myCamera->Eye();
881 myCamStartOpCenter = myCamera->Center();
884 const Graphic3d_Vertex& aPnt = MyDefaultViewPoint;
885 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
887 myCamera->SetUp (myCamStartOpUp);
888 myCamera->SetEye (myCamStartOpEye);
889 myCamera->SetCenter (myCamStartOpCenter);
892 gp_Pnt aRCenter (aPnt.X(), aPnt.Y(), aPnt.Z());
893 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
894 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
895 myCamera->Transform (aRotation);
902 //=============================================================================
905 //=============================================================================
906 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
908 Standard_Real Ax = ax;
909 Standard_Real Ay = ay;
910 Standard_Real Az = az;
912 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
913 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
914 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
915 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
916 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
917 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
920 myCamStartOpUp = myCamera->Up();
921 myCamStartOpEye = myCamera->Eye();
922 myCamStartOpCenter = myCamera->Center();
925 myCamera->SetUp (myCamStartOpUp);
926 myCamera->SetEye (myCamStartOpEye);
927 myCamera->SetCenter (myCamStartOpCenter);
929 // rotate camera around 3 initial axes
930 gp_Pnt aRCenter = myCamera->Eye();
931 gp_Dir aZAxis (myCamera->Direction().Reversed());
932 gp_Dir aYAxis (myCamera->Up());
933 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
935 gp_Trsf aRot[3], aTrsf;
936 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
937 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
938 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
939 aTrsf.Multiply (aRot[0]);
940 aTrsf.Multiply (aRot[1]);
941 aTrsf.Multiply (aRot[2]);
943 myCamera->Transform (aTrsf);
950 //=============================================================================
953 //=============================================================================
954 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
958 Turn(angle,0.,0.,Start);
961 Turn(0.,angle,0.,Start);
964 Turn(0.,0.,angle,Start);
969 //=============================================================================
972 //=============================================================================
973 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
975 Standard_Real Angle = angle ;
977 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
978 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
981 myCamStartOpUp = myCamera->Up();
982 myCamStartOpEye = myCamera->Eye();
983 myCamStartOpCenter = myCamera->Center();
986 myCamera->SetUp (myCamStartOpUp);
987 myCamera->SetEye (myCamStartOpEye);
988 myCamera->SetCenter (myCamStartOpCenter);
990 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
993 gp_Pnt aRCenter = myCamera->Eye();
994 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
995 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
996 myCamera->Transform (aRotation);
1003 //=============================================================================
1004 //function : SetTwist
1006 //=============================================================================
1007 void V3d_View::SetTwist(const Standard_Real angle)
1009 Standard_Real Angle = angle ;
1010 Standard_Boolean TheStatus;
1012 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
1013 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
1015 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1018 anUp = gp_Dir (0.0, 0.0, 1.0);
1020 TheStatus = ScreenAxis(aReferencePlane, anUp,
1021 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1023 anUp = gp_Dir (0.0, 1.0, 0.0);
1024 TheStatus = ScreenAxis(aReferencePlane, anUp,
1025 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1028 anUp = gp_Dir (1.0, 0.0, 0.0);
1029 TheStatus = ScreenAxis(aReferencePlane, anUp,
1030 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1033 V3d_BadValue_Raise_if( !TheStatus,"V3d_ViewSetTwist, alignment of Eye,At,Up,");
1035 gp_Pnt aRCenter = myCamera->Center();
1036 gp_Dir aZAxis (myCamera->Direction().Reversed());
1039 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
1041 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1042 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1044 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1045 myCamera->Transform (aTrsf);
1052 //=============================================================================
1055 //=============================================================================
1056 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1058 Standard_Real aTwistBefore = Twist();
1060 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1062 myCamera->SetEye (gp_Pnt (X, Y, Z));
1063 SetTwist (aTwistBefore);
1067 SetImmediateUpdate (wasUpdateEnabled);
1072 //=============================================================================
1073 //function : SetDepth
1075 //=============================================================================
1076 void V3d_View::SetDepth(const Standard_Real Depth)
1078 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1082 // Move eye using center (target) as anchor.
1083 myCamera->SetDistance (Depth);
1087 // Move the view ref point instead of the eye.
1088 gp_Vec aDir (myCamera->Direction());
1089 gp_Pnt aCameraEye = myCamera->Eye();
1090 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1092 myCamera->SetCenter (aCameraCenter);
1100 //=============================================================================
1101 //function : SetProj
1103 //=============================================================================
1104 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1106 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1107 "V3d_View::SetProj, null projection vector");
1109 Standard_Real aTwistBefore = Twist();
1111 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1113 myCamera->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1115 SetTwist(aTwistBefore);
1119 SetImmediateUpdate (wasUpdateEnabled);
1124 //=============================================================================
1125 //function : SetProj
1127 //=============================================================================
1128 void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1130 Standard_Real Xpn=0;
1131 Standard_Real Ypn=0;
1132 Standard_Real Zpn=0;
1134 switch (Orientation) {
1145 const Graphic3d_Vector& aBck = V3d::GetProjAxis (Orientation);
1147 // retain camera panning from origin when switching projection
1148 gp_Pnt anOriginVCS = myCamera->ConvertWorld2View (gp::Origin());
1149 Standard_Real aPanX = anOriginVCS.X();
1150 Standard_Real aPanY = anOriginVCS.Y();
1152 myCamera->SetCenter (gp_Pnt (0, 0, 0));
1153 myCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1154 myCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
1155 myCamera->OrthogonalizeUp();
1157 Panning (aPanX, aPanY);
1164 //=============================================================================
1167 //=============================================================================
1168 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1170 Standard_Real aTwistBefore = Twist();
1172 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1174 myCamera->SetCenter (gp_Pnt (X, Y, Z));
1176 SetTwist (aTwistBefore);
1180 SetImmediateUpdate (wasUpdateEnabled);
1185 //=============================================================================
1188 //=============================================================================
1189 void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standard_Real Vz)
1191 Standard_Boolean TheStatus ;
1192 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0. ,
1193 "V3d_View::SetUp, nullUp vector");
1195 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1196 gp_Dir anUp (Vx, Vy, Vz);
1198 TheStatus = ScreenAxis(aReferencePlane,anUp,
1199 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1201 anUp = gp_Dir (0.0, 0.0, 1.0);
1202 TheStatus = ScreenAxis(aReferencePlane,anUp,
1203 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1206 anUp = gp_Dir (0.0, 1.0, 0.0);
1207 TheStatus = ScreenAxis(aReferencePlane,anUp,
1208 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1211 anUp = gp_Dir (1.0, 0.0, 0.0);
1212 TheStatus = ScreenAxis(aReferencePlane,anUp,
1213 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1215 V3d_BadValue_Raise_if( !TheStatus,"V3d_View::Setup, alignment of Eye,At,Up");
1217 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1218 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1220 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1227 //=============================================================================
1230 //=============================================================================
1231 void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
1233 Standard_Boolean TheStatus ;
1235 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1238 const Graphic3d_Vector& aViewReferenceUp = V3d::GetProjAxis(Orientation) ;
1239 anUp = gp_Dir (aViewReferenceUp.X(), aViewReferenceUp.Y(), aViewReferenceUp.Z());
1241 TheStatus = ScreenAxis(aReferencePlane,anUp,
1242 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1244 anUp = gp_Dir (0.,0.,1.);
1245 TheStatus = ScreenAxis(aReferencePlane,anUp,
1246 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1249 anUp = gp_Dir (0.,1.,0.);
1250 TheStatus = ScreenAxis(aReferencePlane,anUp,
1251 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1254 anUp = gp_Dir (1.,0.,0.);
1255 TheStatus = ScreenAxis(aReferencePlane,anUp,
1256 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1258 V3d_BadValue_Raise_if( !TheStatus, "V3d_View::SetUp, alignment of Eye,At,Up");
1260 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1261 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1263 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1270 //=============================================================================
1271 //function : SetViewOrientationDefault
1273 //=============================================================================
1274 void V3d_View::SetViewOrientationDefault()
1276 MyView->SetViewOrientationDefault() ;
1281 //=============================================================================
1282 //function : ResetViewOrientation
1284 //=============================================================================
1285 void V3d_View::ResetViewOrientation()
1287 MyView->ViewOrientationReset() ;
1292 //=============================================================================
1295 //=============================================================================
1296 void V3d_View::Reset( const Standard_Boolean update )
1298 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1300 if (!aDefaultCamera.IsNull())
1302 myCamera->CopyMappingData (aDefaultCamera);
1303 myCamera->CopyOrientationData (aDefaultCamera);
1308 SwitchSetFront = Standard_False;
1310 if( myImmediateUpdate || update ) Update();
1313 //=======================================================================
1314 //function : SetCenter
1316 //=======================================================================
1317 void V3d_View::SetCenter (const Standard_Integer theXp,
1318 const Standard_Integer theYp)
1320 Standard_Real aXv, aYv;
1321 Convert (theXp, theYp, aXv, aYv);
1322 Translate (myCamera, aXv, aYv);
1327 //=============================================================================
1328 //function : SetSize
1330 //=============================================================================
1331 void V3d_View::SetSize (const Standard_Real theSize)
1333 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1335 myCamera->SetScale (myCamera->Aspect() >= 1.0 ? theSize / myCamera->Aspect() : theSize);
1342 //=============================================================================
1343 //function : SetZSize
1345 //=============================================================================
1346 void V3d_View::SetZSize(const Standard_Real Size)
1348 Standard_Real Zmax = Size/2.;
1350 Standard_Real aDistance = myCamera->Distance();
1356 Standard_Real Front = MyViewContext.ZClippingFrontPlane();
1357 Standard_Real Back = MyViewContext.ZClippingBackPlane();
1359 // ShortReal precision factor used to add meaningful tolerance to
1360 // ZNear, ZFar values in order to avoid equality after type conversion
1361 // to ShortReal matrices type.
1362 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1364 Standard_Real aZFar = Zmax + aDistance * 2.0;
1365 Standard_Real aZNear = -Zmax + aDistance;
1366 aZNear -= Abs (aZNear) * aPrecision;
1367 aZFar += Abs (aZFar) * aPrecision;
1369 if (!myCamera->IsOrthographic())
1371 if (aZFar < aPrecision)
1373 // Invalid case when both values are negative
1374 aZNear = aPrecision;
1375 aZFar = aPrecision * 2.0;
1377 else if (aZNear < Abs (aZFar) * aPrecision)
1379 // Z is less than 0.0, try to fix it using any appropriate z-scale
1380 aZNear = Abs (aZFar) * aPrecision;
1384 // If range is too small
1385 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1387 aZFar = aZNear + Abs (aZFar) * aPrecision;
1390 myCamera->SetZRange (aZNear, aZFar);
1392 if (MyViewContext.FrontZClippingIsOn() ||
1393 MyViewContext.BackZClippingIsOn())
1395 MyViewContext.SetZClippingFrontPlane (Front);
1396 MyViewContext.SetZClippingBackPlane (Back);
1397 MyView->SetContext (MyViewContext);
1401 //=============================================================================
1402 //function : SetZoom
1404 //=============================================================================
1405 void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1407 V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
1411 myCamStartOpEye = myCamera->Eye();
1412 myCamStartOpCenter = myCamera->Center();
1415 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
1416 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
1418 // ensure that zoom will not be too small or too big
1419 Standard_Real coef = Coef;
1420 if (aViewWidth < coef * Precision::Confusion())
1422 coef = aViewWidth / Precision::Confusion();
1424 else if (aViewWidth > coef * 1e12)
1426 coef = aViewWidth / 1e12;
1428 if (aViewHeight < coef * Precision::Confusion())
1430 coef = aViewHeight / Precision::Confusion();
1432 else if (aViewHeight > coef * 1e12)
1434 coef = aViewHeight / 1e12;
1437 myCamera->SetEye (myCamStartOpEye);
1438 myCamera->SetCenter (myCamStartOpCenter);
1439 myCamera->SetScale (myCamera->Scale() / Coef);
1445 //=============================================================================
1446 //function : SetScale
1448 //=============================================================================
1449 void V3d_View::SetScale( const Standard_Real Coef )
1451 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1453 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1455 // Strange behavior for the sake of compatibility.
1456 if (!aDefaultCamera.IsNull())
1458 myCamera->SetAspect (aDefaultCamera->Aspect());
1459 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1460 myCamera->SetScale (aDefaultScale / Coef);
1464 myCamera->SetScale (myCamera->Scale() / Coef);
1472 //=============================================================================
1473 //function : SetAxialScale
1475 //=============================================================================
1476 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1478 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1480 myCamera->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1484 //=============================================================================
1487 //=============================================================================
1488 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1490 Standard_ASSERT_RAISE (theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1492 if (MyView->NumberOfDisplayedStructures() == 0)
1497 if (!FitMinMax (myCamera, MyView->MinMaxValues(), theMargin, 10.0 * Precision::Confusion()))
1504 if (myImmediateUpdate || theToUpdate)
1510 //=============================================================================
1511 //function : DepthFitAll
1513 //=============================================================================
1514 void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1515 const Quantity_Coefficient Margin)
1517 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1518 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1519 Standard_Real Dx,Dy,Dz,Size;
1521 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1523 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1528 Bnd_Box aBox = MyView->MinMaxValues();
1534 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1535 MyView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
1536 MyView->Projects(Xmax,Ymax,Zmax,U1,V1,W1) ;
1537 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1538 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1539 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1540 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
1541 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1542 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1543 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1544 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
1545 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1546 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1547 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1548 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
1549 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1550 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1551 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1552 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
1553 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1554 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1555 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1556 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
1557 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1558 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1559 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1560 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
1561 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1562 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1563 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1566 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1567 Dz = 2.*Wmax + Margin * Wmax;
1569 // Compute depth value
1570 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1571 Dx += Margin * Dx; Dy += Margin * Dy;
1572 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1575 SetDepth( Aspect * Size / 2.);
1581 //=============================================================================
1584 //=============================================================================
1585 void V3d_View::FitAll(const Standard_Real theMinXv,
1586 const Standard_Real theMinYv,
1587 const Standard_Real theMaxXv,
1588 const Standard_Real theMaxYv)
1590 FitAll (MyWindow, theMinXv, theMinYv, theMaxXv, theMaxYv);
1593 //=============================================================================
1594 //function : WindowFitAll
1596 //=============================================================================
1597 void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1598 const Standard_Integer Ymin,
1599 const Standard_Integer Xmax,
1600 const Standard_Integer Ymax)
1602 WindowFit(Xmin,Ymin,Xmax,Ymax);
1605 //=======================================================================
1606 //function : WindowFit
1608 //=======================================================================
1609 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1610 const Standard_Integer theMinYp,
1611 const Standard_Integer theMaxXp,
1612 const Standard_Integer theMaxYp)
1614 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1616 if (!myCamera->IsOrthographic())
1618 // normalize view coordiantes
1619 Standard_Integer aWinWidth, aWinHeight;
1620 MyWindow->Size (aWinWidth, aWinHeight);
1622 // z coordinate of camera center
1623 Standard_Real aDepth = myCamera->Project (myCamera->Center()).Z();
1625 // camera projection coordinate are in NDC which are normalized [-1, 1]
1626 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1627 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1628 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1629 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1631 // compute camera panning
1632 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1633 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1634 gp_Pnt aPanTo = myCamera->ConvertProj2View (aFitCenter);
1635 gp_Pnt aPanFrom = myCamera->ConvertProj2View (aScreenCenter);
1636 gp_Vec aPanVec (aPanFrom, aPanTo);
1638 // compute section size
1639 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1640 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1641 gp_Pnt aViewBotLeft = myCamera->ConvertProj2View (aFitBotLeft);
1642 gp_Pnt aViewTopRight = myCamera->ConvertProj2View (aFitTopRight);
1644 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1645 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1647 Translate (myCamera, aPanVec.X(), -aPanVec.Y());
1648 Scale (myCamera, aUSize, aVSize);
1653 Standard_Real aX1, aY1, aX2, aY2;
1654 Convert (theMinXp, theMinYp, aX1, aY1);
1655 Convert (theMaxXp, theMaxYp, aX2, aY2);
1656 FitAll (aX1, aY1, aX2, aY2);
1659 SetImmediateUpdate (wasUpdateEnabled);
1664 //=======================================================================
1665 //function : SetViewMappingDefault
1667 //=======================================================================
1668 void V3d_View::SetViewMappingDefault()
1670 MyView->SetViewMappingDefault();
1675 //=======================================================================
1676 //function : ResetViewMapping
1678 //=======================================================================
1679 void V3d_View::ResetViewMapping()
1681 MyView->ViewMappingReset();
1686 //=======================================================================
1687 //function : ConvertToGrid
1689 //=======================================================================
1690 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1691 const Standard_Integer Yp,
1694 Standard_Real& Zg) const
1696 Graphic3d_Vertex aVrp;
1697 Standard_Real anX, anY, aZ;
1698 Convert (Xp, Yp, anX, anY, aZ);
1699 aVrp.SetCoord (anX, anY, aZ);
1701 if( MyViewer->Grid()->IsActive() ) {
1702 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1703 aNewVrp.Coord (Xg,Yg,Zg) ;
1705 aVrp.Coord (Xg,Yg,Zg) ;
1708 //=======================================================================
1709 //function : ConvertToGrid
1711 //=======================================================================
1712 void V3d_View::ConvertToGrid(const Standard_Real X,
1713 const Standard_Real Y,
1714 const Standard_Real Z,
1717 Standard_Real& Zg) const
1719 if( MyViewer->Grid()->IsActive() ) {
1720 Graphic3d_Vertex aVrp (X,Y,Z) ;
1721 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1722 aNewVrp.Coord(Xg,Yg,Zg) ;
1724 Xg = X; Yg = Y; Zg = Z;
1728 //=======================================================================
1729 //function : Convert
1731 //=======================================================================
1732 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1734 Standard_Integer aDxw, aDyw ;
1736 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1738 MyWindow->Size (aDxw, aDyw);
1739 Standard_Real aValue;
1741 gp_Pnt aViewDims = myCamera->ViewDimensions();
1742 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1747 //=======================================================================
1748 //function : Convert
1750 //=======================================================================
1751 void V3d_View::Convert(const Standard_Integer Xp,
1752 const Standard_Integer Yp,
1754 Standard_Real& Yv) const
1756 Standard_Integer aDxw, aDyw;
1758 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1760 MyWindow->Size (aDxw, aDyw);
1762 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1763 aPoint = myCamera->ConvertProj2View (aPoint);
1769 //=======================================================================
1770 //function : Convert
1772 //=======================================================================
1773 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1775 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1777 Standard_Integer aDxw, aDyw;
1778 MyWindow->Size (aDxw, aDyw);
1780 gp_Pnt aViewDims = myCamera->ViewDimensions();
1781 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1786 //=======================================================================
1787 //function : Convert
1789 //=======================================================================
1790 void V3d_View::Convert(const Standard_Real Xv,
1791 const Standard_Real Yv,
1792 Standard_Integer& Xp,
1793 Standard_Integer& Yp) const
1795 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1797 Standard_Integer aDxw, aDyw;
1798 MyWindow->Size (aDxw, aDyw);
1800 gp_Pnt aPoint (Xv, Yv, 0.0);
1801 aPoint = myCamera->ConvertView2Proj (aPoint);
1802 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1804 Xp = RealToInt (aPoint.X());
1805 Yp = RealToInt (aPoint.Y());
1808 //=======================================================================
1809 //function : Convert
1811 //=======================================================================
1812 void V3d_View::Convert(const Standard_Integer Xp,
1813 const Standard_Integer Yp,
1816 Standard_Real& Z) const
1818 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1819 Standard_Integer aHeight, aWidth;
1820 MyWindow->Size (aWidth, aHeight);
1822 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1823 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1824 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1826 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
1832 Graphic3d_Vertex aVrp;
1833 aVrp.SetCoord (X, Y, Z);
1835 if( MyViewer->Grid()->IsActive() ) {
1836 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1837 aNewVrp.Coord (X, Y, Z) ;
1841 //=======================================================================
1842 //function : ConvertWithProj
1844 //=======================================================================
1845 void V3d_View::ConvertWithProj(const Standard_Integer Xp,
1846 const Standard_Integer Yp,
1852 Standard_Real& Dz) const
1854 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
1855 Standard_Integer aHeight, aWidth;
1856 MyWindow->Size (aWidth, aHeight);
1858 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1859 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1860 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1862 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
1868 Graphic3d_Vertex aVrp;
1869 aVrp.SetCoord (X, Y, Z);
1871 aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1873 Graphic3d_Vec3d aNormDir;
1874 aNormDir.x() = X - aResult.X();
1875 aNormDir.y() = Y - aResult.Y();
1876 aNormDir.z() = Z - aResult.Z();
1877 aNormDir.Normalize();
1883 if( MyViewer->Grid()->IsActive() ) {
1884 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1885 aNewVrp.Coord (X, Y, Z) ;
1889 //=======================================================================
1890 //function : Convert
1892 //=======================================================================
1893 void V3d_View::Convert(const Standard_Real X,
1894 const Standard_Real Y,
1895 const Standard_Real Z,
1896 Standard_Integer& Xp,
1897 Standard_Integer& Yp) const
1899 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
1900 Standard_Integer aHeight, aWidth;
1901 MyWindow->Size (aWidth, aHeight);
1903 gp_Pnt aPoint = myCamera->Project (gp_Pnt (X, Y, Z));
1905 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1906 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1909 //=======================================================================
1910 //function : Project
1912 //=======================================================================
1913 void V3d_View::Project(const Standard_Real X,
1914 const Standard_Real Y,
1915 const Standard_Real Z,
1917 Standard_Real &Yp) const
1920 MyView->Projects (X, Y, Z, Xp, Yp, Zp);
1923 //=======================================================================
1924 //function : BackgroundColor
1926 //=======================================================================
1927 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1930 Standard_Real& V3) const
1932 Quantity_Color C = BackgroundColor() ;
1933 C.Values(V1,V2,V3,Type) ;
1936 //=======================================================================
1937 //function : BackgroundColor
1939 //=======================================================================
1940 Quantity_Color V3d_View::BackgroundColor() const
1942 return MyBackground.Color() ;
1945 //=======================================================================
1946 //function : GradientBackgroundColors
1948 //=======================================================================
1949 void V3d_View::GradientBackgroundColors(Quantity_Color& Color1,Quantity_Color& Color2) const
1951 MyGradientBackground.Colors(Color1, Color2);
1954 //=======================================================================
1955 //function : GradientBackground
1957 //=======================================================================
1958 Aspect_GradientBackground V3d_View::GradientBackground() const
1960 return MyGradientBackground;
1963 //=======================================================================
1966 //=======================================================================
1967 Standard_Real V3d_View::Scale() const
1969 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1971 Standard_Real aCameraScale;
1973 // Strange behavior for the sake of compatibility.
1974 if (!aDefaultCamera.IsNull())
1976 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1977 aCameraScale = aDefaultScale / myCamera->Scale();
1981 aCameraScale = myCamera->Scale();
1984 return aCameraScale;
1987 //=======================================================================
1988 //function : AxialScale
1990 //=======================================================================
1991 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1993 gp_Pnt anAxialScale = myCamera->AxialScale();
1994 Sx = anAxialScale.X();
1995 Sy = anAxialScale.Y();
1996 Sz = anAxialScale.Z();
1999 //=======================================================================
2002 //=======================================================================
2003 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
2005 gp_Pnt aViewDims = myCamera->ViewDimensions();
2007 Width = aViewDims.X();
2008 Height = aViewDims.Y();
2011 //=======================================================================
2014 //=======================================================================
2015 Standard_Real V3d_View::ZSize() const
2017 gp_Pnt aViewDims = myCamera->ViewDimensions();
2019 return aViewDims.Z();
2022 //=======================================================================
2025 //=======================================================================
2026 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
2027 Standard_Real& Vmin,
2028 Standard_Real& Umax,
2029 Standard_Real& Vmax) const
2031 Standard_Real Wmin,Wmax,U,V,W ;
2032 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
2034 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2037 Bnd_Box aBox = MyView->MinMaxValues();
2038 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2039 MyView->Projects(Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
2040 MyView->Projects(Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
2041 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
2042 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2043 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2044 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2045 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
2046 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2047 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2048 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2049 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
2050 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2051 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2052 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2053 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
2054 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2055 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2056 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2057 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
2058 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2059 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2060 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2061 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
2062 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2063 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2064 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2069 //=======================================================================
2072 //=======================================================================
2073 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
2074 Standard_Real& Ymin,
2075 Standard_Real& Zmin,
2076 Standard_Real& Xmax,
2077 Standard_Real& Ymax,
2078 Standard_Real& Zmax) const
2081 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
2082 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2085 Bnd_Box aBox = MyView->MinMaxValues();
2086 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2091 //=======================================================================
2092 //function : Gravity
2094 //=======================================================================
2095 Standard_Integer V3d_View::Gravity(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2097 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax;
2098 Standard_Integer Nstruct,Npoint ;
2099 Graphic3d_MapOfStructure MySetOfStructures;
2101 MyView->DisplayedStructures (MySetOfStructures);
2102 Nstruct = MySetOfStructures.Extent() ;
2104 Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ;
2106 Npoint = 0 ; X = Y = Z = 0. ;
2107 for (; MyIterator.More(); MyIterator.Next())
2109 const Handle(Graphic3d_Structure)& aStruct = MyIterator.Key();
2110 if (!aStruct->IsEmpty())
2112 Bnd_Box aBox = aStruct->MinMaxValues();
2114 // Check bounding box for validness
2120 // use camera projection to find gravity point
2121 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2123 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2124 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2125 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2126 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax) };
2128 for (Standard_Integer aPntIt = 0; aPntIt < 8; ++aPntIt)
2130 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2132 gp_Pnt aProjected = myCamera->Project (aBndPnt);
2133 const Standard_Real& U = aProjected.X();
2134 const Standard_Real& V = aProjected.Y();
2135 if (Abs(U) <= 1.0 && Abs(V) <= 1.0)
2146 X /= Npoint ; Y /= Npoint ; Z /= Npoint ;
2152 //=======================================================================
2155 //=======================================================================
2156 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2158 gp_Pnt aCameraEye = myCamera->Eye();
2164 //=============================================================================
2165 //function : FocalReferencePoint
2167 //=============================================================================
2168 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2173 //=============================================================================
2174 //function : ProjReferenceAxe
2176 //=============================================================================
2177 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2178 const Standard_Integer Ypix,
2184 Standard_Real& VZ) const
2186 Standard_Real Xo,Yo,Zo;
2188 Convert (Xpix, Ypix, XP, YP, ZP);
2189 if ( Type() == V3d_PERSPECTIVE )
2191 FocalReferencePoint (Xo,Yo,Zo);
2202 //=============================================================================
2205 //=============================================================================
2206 Standard_Real V3d_View::Depth() const
2208 return myCamera->Distance();
2211 //=============================================================================
2214 //=============================================================================
2215 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2217 gp_Dir aCameraDir = myCamera->Direction().Reversed();
2218 Dx = aCameraDir.X();
2219 Dy = aCameraDir.Y();
2220 Dz = aCameraDir.Z();
2223 //=============================================================================
2226 //=============================================================================
2227 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2229 gp_Pnt aCameraCenter = myCamera->Center();
2230 X = aCameraCenter.X();
2231 Y = aCameraCenter.Y();
2232 Z = aCameraCenter.Z();
2235 //=============================================================================
2238 //=============================================================================
2239 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2241 gp_Dir aCameraUp = myCamera->Up();
2247 //=============================================================================
2250 //=============================================================================
2251 Standard_Real V3d_View::Twist() const
2253 Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2254 Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
2255 Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
2256 Standard_Boolean TheStatus ;
2258 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
2262 anUp = gp_Dir (0.,0.,1.) ;
2263 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2265 anUp = gp_Dir (0.,1.,0.) ;
2266 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2269 anUp = gp_Dir (1.,0.,0.) ;
2270 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2272 Yaxis.Coord(X0,Y0,Z0) ;
2275 /* Compute Cross Vector From Up & Origin */
2276 pvx = Y0*Zup - Z0*Yup ;
2277 pvy = Z0*Xup - X0*Zup ;
2278 pvz = X0*Yup - Y0*Xup ;
2279 pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2280 sca = X0*Xup + Y0*Yup + Z0*Zup ;
2283 if( angle > 1. ) angle = 1. ;
2284 else if( angle < -1. ) angle = -1. ;
2285 angle = asin(angle) ;
2286 if( sca < 0. ) angle = M_PI - angle ;
2287 if( angle > 0. && angle < M_PI ) {
2288 sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2289 if( sca < 0. ) angle = DEUXPI - angle ;
2294 //=============================================================================
2295 //function : ShadingModel
2297 //=============================================================================
2298 V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2300 V3d_TypeOfShadingModel SM = (V3d_TypeOfShadingModel)MyViewContext.Model() ;
2304 //=============================================================================
2305 //function : SurfaceDetail
2307 //=============================================================================
2308 V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
2310 V3d_TypeOfSurfaceDetail SM = (V3d_TypeOfSurfaceDetail)MyViewContext.SurfaceDetail() ;
2314 //=============================================================================
2315 //function : TextureEnv
2317 //=============================================================================
2318 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2320 Handle(Graphic3d_TextureEnv) SM = MyViewContext.TextureEnv() ;
2324 //=============================================================================
2325 //function : Visualization
2327 //=============================================================================
2328 V3d_TypeOfVisualization V3d_View::Visualization() const
2330 V3d_TypeOfVisualization V =
2331 (V3d_TypeOfVisualization)MyViewContext.Visualization() ;
2335 //=============================================================================
2336 //function : Antialiasing
2338 //=============================================================================
2339 Standard_Boolean V3d_View::Antialiasing() const
2341 Standard_Boolean A = MyViewContext.AliasingIsOn() ;
2345 //=============================================================================
2348 //=============================================================================
2349 Handle(V3d_Viewer) V3d_View::Viewer() const
2354 //=============================================================================
2355 //function : IfWindow
2357 //=============================================================================
2358 Standard_Boolean V3d_View::IfWindow() const
2360 Standard_Boolean TheStatus = MyView->IsDefined() ;
2364 //=============================================================================
2367 //=============================================================================
2368 Handle(Aspect_Window) V3d_View::Window() const
2373 //=============================================================================
2376 //=============================================================================
2377 V3d_TypeOfView V3d_View::Type() const
2379 return myCamera->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2382 //=============================================================================
2383 //function : SetFocale
2385 //=============================================================================
2386 void V3d_View::SetFocale( const Standard_Real focale )
2388 if (myCamera->IsOrthographic())
2393 Standard_Real aFOVyRad = ATan (focale / (myCamera->Distance() * 2.0));
2395 myCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2400 //=============================================================================
2403 //=============================================================================
2404 Standard_Real V3d_View::Focale() const
2406 if (myCamera->IsOrthographic())
2411 return myCamera->Distance() * 2.0 * Tan(myCamera->FOVy() * M_PI / 360.0);
2414 //=============================================================================
2417 //=============================================================================
2418 Handle(Visual3d_View) V3d_View::View() const
2423 //=============================================================================
2424 //function : ScreenAxis
2426 //=============================================================================
2427 Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2429 Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2430 Standard_Real dx1, dy1, dz1, xx, yy, zz;
2432 Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2433 Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2434 xx = Yup*Zpn - Zup*Ypn;
2435 yy = Zup*Xpn - Xup*Zpn;
2436 zz = Xup*Ypn - Yup*Xpn;
2437 Xaxe.SetCoord (xx, yy, zz);
2438 if (Xaxe.LengthZero()) return Standard_False;
2440 Xaxe.Coord(dx1, dy1, dz1);
2441 xx = Ypn*dz1 - Zpn*dy1;
2442 yy = Zpn*dx1 - Xpn*dz1;
2443 zz = Xpn*dy1 - Ypn*dx1;
2444 Yaxe.SetCoord (xx, yy, zz) ;
2445 if (Yaxe.LengthZero()) return Standard_False;
2448 Zaxe.SetCoord (Xpn, Ypn, Zpn);
2450 return Standard_True;
2453 //=============================================================================
2454 //function : TrsPoint
2456 //=============================================================================
2457 Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2459 Graphic3d_Vertex PP ;
2460 Standard_Real X,Y,Z,XX,YY,ZZ ;
2463 Standard_Integer lr, ur, lc, uc;
2464 lr = Matrix.LowerRow ();
2465 ur = Matrix.UpperRow ();
2466 lc = Matrix.LowerCol ();
2467 uc = Matrix.UpperCol ();
2468 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
2470 PP.SetCoord(X,Y,Z) ;
2474 XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2475 Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2477 YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2478 Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2480 ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2481 Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2482 PP.SetCoord(XX,YY,ZZ) ;
2486 //=======================================================================
2489 //=======================================================================
2490 void V3d_View::Pan (const Standard_Integer theDXp,
2491 const Standard_Integer theDYp,
2492 const Quantity_Factor theZoomFactor,
2493 const Standard_Boolean theToStart)
2495 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2498 //=======================================================================
2499 //function : Panning
2501 //=======================================================================
2502 void V3d_View::Panning (const Standard_Real theDXv,
2503 const Standard_Real theDYv,
2504 const Quantity_Factor theZoomFactor,
2505 const Standard_Boolean theToStart)
2507 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2511 myCamStartOpEye = myCamera->Eye();
2512 myCamStartOpCenter = myCamera->Center();
2515 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2517 gp_Pnt aViewDims = myCamera->ViewDimensions();
2519 myCamera->SetEye (myCamStartOpEye);
2520 myCamera->SetCenter (myCamStartOpCenter);
2521 Translate (myCamera, -theDXv, -theDYv);
2522 Scale (myCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2524 SetImmediateUpdate (wasUpdateEnabled);
2529 //=======================================================================
2532 //=======================================================================
2533 void V3d_View::Zoom (const Standard_Integer theXp1,
2534 const Standard_Integer theYp1,
2535 const Standard_Integer theXp2,
2536 const Standard_Integer theYp2)
2538 Standard_Integer aDx = theXp2 - theXp1;
2539 Standard_Integer aDy = theYp2 - theYp1;
2540 if (aDx != 0 || aDy != 0)
2542 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2543 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2544 SetZoom (aCoeff, Standard_True);
2548 //=======================================================================
2549 //function : StartZoomAtPoint
2551 //=======================================================================
2552 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2553 const Standard_Integer theYp)
2555 MyZoomAtPointX = theXp;
2556 MyZoomAtPointY = theYp;
2559 //=======================================================================
2560 //function : ZoomAtPoint
2562 //=======================================================================
2563 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2564 const Standard_Integer theMouseStartY,
2565 const Standard_Integer theMouseEndX,
2566 const Standard_Integer theMouseEndY)
2568 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2571 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2572 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2573 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2575 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2577 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
2578 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
2580 // ensure that zoom will not be too small or too big.
2581 Standard_Real aCoef = aDZoom;
2582 if (aViewWidth < aCoef * Precision::Confusion())
2584 aCoef = aViewWidth / Precision::Confusion();
2586 else if (aViewWidth > aCoef * 1e12)
2588 aCoef = aViewWidth / 1e12;
2590 if (aViewHeight < aCoef * Precision::Confusion())
2592 aCoef = aViewHeight / Precision::Confusion();
2594 else if (aViewHeight > aCoef * 1e12)
2596 aCoef = aViewHeight / 1e12;
2599 Standard_Real aZoomAtPointXv = 0.0;
2600 Standard_Real aZoomAtPointYv = 0.0;
2601 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2603 V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
2604 V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
2606 myCamera->SetScale (myCamera->Scale() / aCoef);
2607 Translate (myCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2611 SetImmediateUpdate (wasUpdateEnabled);
2616 //=============================================================================
2617 //function : AxialScale
2619 //=============================================================================
2620 void V3d_View::AxialScale (const Standard_Integer Dx,
2621 const Standard_Integer Dy,
2622 const V3d_TypeOfAxe Axis)
2624 if( Dx != 0. || Dy != 0. ) {
2625 Standard_Real Sx, Sy, Sz;
2626 AxialScale( Sx, Sy, Sz );
2627 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2628 dscale = (Dx > 0) ? dscale : 1./dscale;
2629 if( Axis == V3d_X ) Sx = dscale;
2630 if( Axis == V3d_Y ) Sy = dscale;
2631 if( Axis == V3d_Z ) Sz = dscale;
2632 SetAxialScale( Sx, Sy, Sz );
2636 //=============================================================================
2639 //=============================================================================
2640 void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
2641 const Standard_Real Xmin,
2642 const Standard_Real Ymin,
2643 const Standard_Real Xmax,
2644 const Standard_Real Ymax)
2646 Standard_Integer aWinWidth, aWinHeight;
2647 aWindow->Size (aWinWidth, aWinHeight);
2649 Standard_Real aWinAspect = (Standard_Real)aWinWidth / aWinHeight;
2650 Standard_Real aFitSizeU = Abs (Xmax - Xmin);
2651 Standard_Real aFitSizeV = Abs (Ymax - Ymin);
2652 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2653 if (aFitAspect >= aWinAspect)
2655 aFitSizeV = aFitSizeU / aWinAspect;
2659 aFitSizeU = aFitSizeV * aWinAspect;
2662 myCamera->SetAspect (aWinAspect);
2663 Translate (myCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
2664 Scale (myCamera, aFitSizeU, aFitSizeV);
2670 //=============================================================================
2671 //function : StartRotation
2673 //=============================================================================
2675 static Standard_Boolean zRotation = Standard_False;
2677 void V3d_View::StartRotation(const Standard_Integer X,
2678 const Standard_Integer Y,
2679 const Quantity_Ratio zRotationThreshold)
2684 rx = Standard_Real(Convert(x));
2685 ry = Standard_Real(Convert(y));
2687 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2689 zRotation = Standard_False;
2690 if( zRotationThreshold > 0. ) {
2691 Standard_Real dx = Abs(sx - rx/2.);
2692 Standard_Real dy = Abs(sy - ry/2.);
2693 // if( dx > rx/3. || dy > ry/3. ) zRotation = Standard_True;
2694 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2695 if( dx > dd || dy > dd ) zRotation = Standard_True;
2701 //=============================================================================
2702 //function : Rotation
2704 //=============================================================================
2705 void V3d_View::Rotation(const Standard_Integer X,
2706 const Standard_Integer Y)
2709 if( rx == 0. || ry == 0. ) {
2715 Standard_Real dx=0.,dy=0.,dz=0.;
2717 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2718 atan2(sx-rx/2.,ry/2.-sy);
2720 dx = (Standard_Real(X) - sx) * M_PI / rx;
2721 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2723 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2725 Standard_Real dx = (Standard_Real(X - sx)) * M_PI;
2726 Standard_Real dy = (Standard_Real(sy - Y)) * M_PI;
2727 Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2730 if( !myImmediateUpdate ) Update();
2732 myImmediateUpdate = Standard_False;
2733 Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2734 ZFitAll (Zmargin); //Don't do that, perf improvment
2735 myImmediateUpdate = Standard_True;
2740 //=============================================================================
2741 //function : SetComputedMode
2743 //=============================================================================
2744 void V3d_View::SetComputedMode (const Standard_Boolean aMode)
2750 MyView->SetComputedMode (Standard_True);
2756 MyView->SetComputedMode (Standard_False);
2761 //=============================================================================
2762 //function : ComputedMode
2764 //=============================================================================
2765 Standard_Boolean V3d_View::ComputedMode() const
2767 return MyView->ComputedMode();
2770 //=============================================================================
2771 //function : SetBackFacingModel
2773 //=============================================================================
2774 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel aModel)
2776 MyView->SetBackFacingModel (Visual3d_TypeOfBackfacingModel(aModel));
2780 //=============================================================================
2781 //function : BackFacingModel
2783 //=============================================================================
2784 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2786 return V3d_TypeOfBackfacingModel(MyView -> BackFacingModel ());
2789 void V3d_View::Init()
2791 myComputedMode = MyViewer->ComputedMode();
2792 if( !myComputedMode || !MyViewer->DefaultComputedMode() ) {
2793 SetComputedMode(Standard_False);
2797 //=============================================================================
2800 //=============================================================================
2801 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2802 const Graphic3d_BufferType& theBufferType)
2804 Standard_Integer aWinWidth, aWinHeight;
2805 MyWindow->Size (aWinWidth, aWinHeight);
2806 Image_AlienPixMap anImage;
2808 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2811 //=============================================================================
2812 //function : ToPixMap
2814 //=============================================================================
2815 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
2816 const Standard_Integer theWidth,
2817 const Standard_Integer theHeight,
2818 const Graphic3d_BufferType& theBufferType,
2819 const Standard_Boolean theToKeepAspect,
2820 const V3d_StereoDumpOptions theStereoOptions)
2822 Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
2824 // always prefer hardware accelerated offscreen buffer
2825 Graphic3d_PtrFrameBuffer aFBOPtr = NULL;
2826 Graphic3d_PtrFrameBuffer aPrevFBOPtr = (Graphic3d_PtrFrameBuffer )cView->ptrFBO;
2827 Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
2828 Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
2829 if (aPrevFBOPtr != NULL)
2831 MyView->FBOGetDimensions (aPrevFBOPtr,
2832 aPrevFBOVPSizeX, aPrevFBOVPSizeY,
2833 aPrevFBOSizeXMax, aPrevFBOSizeYMax);
2834 if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
2836 MyView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
2837 aFBOPtr = aPrevFBOPtr;
2841 if (aFBOPtr == NULL)
2843 // Try to create hardware accelerated buffer
2844 aFBOPtr = MyView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
2845 if (aFBOPtr != NULL)
2847 MyView->FBOGetDimensions (aFBOPtr,
2848 aFBOVPSizeX, aFBOVPSizeY,
2849 aFBOSizeXMax, aFBOSizeYMax);
2850 // reduce viewport in case of hardware limits
2851 if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
2852 if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
2853 MyView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
2856 cView->ptrFBO = aFBOPtr;
2858 // If hardware accelerated buffer - try to use onscreen buffer
2859 // Results may be bad!
2860 if (aFBOPtr == NULL)
2862 // retrieve window sizes
2863 Standard_Integer aWinWidth, aWinHeight;
2864 MyWindow->Size (aWinWidth, aWinHeight);
2866 // technically we can reduce existing viewport...
2867 // but currently allow only dumping the window itself
2868 if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
2870 return Standard_False;
2874 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2876 aStoreMapping->Copy (myCamera);
2878 if (myCamera->IsStereo())
2880 switch (theStereoOptions)
2883 myCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2886 case V3d_SDO_LEFT_EYE :
2887 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2890 case V3d_SDO_RIGHT_EYE :
2891 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2896 // render immediate structures into back buffer rather than front
2897 Handle(Graphic3d_GraphicDriver) aDriver = Handle(Graphic3d_GraphicDriver)::DownCast (MyView->GraphicDriver());
2898 const Standard_Boolean aPrevImmediateMode = aDriver.IsNull() ? Standard_True : aDriver->SetImmediateModeDrawToFront (*cView, Standard_False);
2900 const Standard_Boolean toAutoUpdate = myImmediateUpdate;
2901 myImmediateUpdate = Standard_False;
2903 myImmediateUpdate = toAutoUpdate;
2905 if (theToKeepAspect)
2907 myCamera->SetAspect ((Standard_Real) aFBOVPSizeX / aFBOVPSizeY);
2910 //workaround for rendering list of Over and Under Layers
2911 if (!MyLayerMgr.IsNull())
2913 MyLayerMgr->Compute();
2918 if (!aDriver.IsNull())
2920 aDriver->SetImmediateModeDrawToFront (*cView, aPrevImmediateMode);
2923 myCamera->Copy (aStoreMapping);
2925 Standard_Boolean isSuccess = Standard_True;
2927 // allocate image buffer for dumping
2928 if (theImage.IsEmpty()
2929 || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
2930 || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
2932 bool isBigEndian = Image_PixMap::IsBigEndianHost();
2933 Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
2934 switch (theBufferType)
2936 case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
2937 case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
2938 case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
2941 isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
2943 isSuccess = isSuccess && MyView->BufferDump (theImage, theBufferType);
2945 // FBO now useless, free resources
2946 if (aFBOPtr != aPrevFBOPtr)
2948 MyView->FBORelease (aFBOPtr);
2950 else if (aPrevFBOPtr != NULL)
2952 MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
2954 cView->ptrFBO = aPrevFBOPtr;
2958 void V3d_View::ImmediateUpdate() const
2960 if (myImmediateUpdate) Update();
2963 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2965 Standard_Boolean aPreviousMode = myImmediateUpdate;
2966 myImmediateUpdate = theImmediateUpdate;
2967 return aPreviousMode;
2970 // =======================================================================
2971 // function : SetCamera
2973 // =======================================================================
2974 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2976 Standard_ASSERT_RAISE (!theCamera.IsNull(), "Void camera is not allowed");
2978 myCamera = theCamera;
2980 MyView->SetCamera (theCamera);
2983 // =======================================================================
2984 // function : GetCamera
2986 // =======================================================================
2987 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
2992 // =======================================================================
2993 // function : FitMinMax
2994 // purpose : Internal
2995 // =======================================================================
2996 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
2997 const Bnd_Box& theBox,
2998 const Standard_Real theMargin,
2999 const Standard_Real theResolution,
3000 const Standard_Boolean theToEnlargeIfLine) const
3002 // Check bounding box for validness
3003 if (theBox.IsVoid())
3005 return Standard_False; // bounding box is out of bounds...
3008 // Apply "axial scaling" to the bounding points.
3009 // It is not the best approach to make this scaling as a part of fit all operation,
3010 // but the axial scale is integrated into camera orientation matrix and the other
3011 // option is to perform frustum plane adjustment algorithm in view camera space,
3012 // which will lead to a number of additional world-view space conversions and
3013 // loosing precision as well.
3014 gp_Pnt aMinCorner = theBox.CornerMin();
3015 gp_Pnt aMaxCorner = theBox.CornerMax();
3016 Standard_Real aXmin = aMinCorner.X() * theCamera->AxialScale().X();
3017 Standard_Real aXmax = aMaxCorner.X() * theCamera->AxialScale().X();
3018 Standard_Real aYmin = aMinCorner.Y() * theCamera->AxialScale().Y();
3019 Standard_Real aYmax = aMaxCorner.Y() * theCamera->AxialScale().Y();
3020 Standard_Real aZmin = aMinCorner.Z() * theCamera->AxialScale().Z();
3021 Standard_Real aZmax = aMaxCorner.Z() * theCamera->AxialScale().Z();
3024 aBBox.Update (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3025 if (aBBox.IsThin (RealEpsilon()))
3027 return Standard_False; // nothing to fit all
3030 gp_Pnt aBBCenter ((aXmin + aXmax) * 0.5, (aYmin + aYmax) * 0.5, (aZmin + aZmax) * 0.5);
3032 gp_Pln aFrustumLeft;
3033 gp_Pln aFrustumRight;
3034 gp_Pln aFrustumBottom;
3036 gp_Pln aFrustumNear;
3038 theCamera->Frustum (aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar);
3040 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3041 gp_Dir aCamDir = theCamera->Direction();
3042 gp_Dir aCamSide = aCamDir ^ aCamUp;
3044 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3045 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3046 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3047 // set up perspective-correct camera projection matching the bounding box.
3048 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3049 // The zooming can be done by calculating view plane size matching the bounding box at center of
3050 // the bounding box. The only limitation here is that the scale of camera should define size of
3051 // its view plane passing through the camera center, and the center of camera should be on the
3052 // same line with the center of bounding box.
3054 // The following method is applied:
3055 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3056 // 2) Determine new location of frustum planes, "matching" the bounding box.
3057 // 3) Determine new camera projection vector using the normalized asymmetry.
3058 // 4) Determine new zooming in view space.
3060 // Determine normalized projection asymmetry (if any).
3062 Standard_Real anAssymX = Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction()))
3063 - Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction()));
3064 Standard_Real anAssymY = Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction()))
3065 - Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction()));
3067 // Determine how far should be the frustum planes placed from center
3068 // of bounding box, in order to match the bounding box closely.
3069 gp_Pln aMatchSide[6] = {aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar};
3070 Standard_Real aMatchDistance[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
3071 for (Standard_Integer anIt = 0; anIt < 6; ++anIt)
3073 const gp_Dir& aPlaneN = aMatchSide[anIt].Axis().Direction();
3076 aPlaneTrsf.SetTransformation (gp_Ax3(), gp_Ax3 (aBBCenter, aPlaneN));
3077 Bnd_Box aRelativeBBox = aBBox.Transformed (aPlaneTrsf);
3079 Standard_Real aDummy = 0.0;
3080 Standard_Real aZmin = 0.0;
3081 Standard_Real aZmax = 0.0;
3082 aRelativeBBox.Get (aDummy, aDummy, aZmin, aDummy, aDummy, aZmax);
3083 aMatchDistance[anIt] = -aZmin;
3085 // The center of camera is placed on the same line with center of bounding box.
3086 // The view plane section crosses the bounding box at its center.
3087 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3088 // into view section size between the point and the frustum plane.
3090 // /|\ right half of frame //
3092 // point o<-- distance * coeff -->//---- (view plane section)
3102 aMatchDistance[0] *= Sqrt(1 + Pow (Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction())), 2.0));
3103 aMatchDistance[1] *= Sqrt(1 + Pow (Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction())), 2.0));
3104 aMatchDistance[2] *= Sqrt(1 + Pow (Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction())), 2.0));
3105 aMatchDistance[3] *= Sqrt(1 + Pow (Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction())), 2.0));
3106 aMatchDistance[4] *= Sqrt(1 + Pow (Tan ( aCamDir.Angle (aFrustumNear.Axis().Direction())), 2.0));
3107 aMatchDistance[5] *= Sqrt(1 + Pow (Tan (-aCamDir.Angle (aFrustumFar.Axis().Direction())), 2.0));
3109 Standard_Real aViewSizeXv = aMatchDistance[0] + aMatchDistance[1];
3110 Standard_Real aViewSizeYv = aMatchDistance[2] + aMatchDistance[3];
3111 Standard_Real aViewSizeZv = aMatchDistance[4] + aMatchDistance[5];
3113 // Place center of camera on the same line with center of bounding
3114 // box applying corresponding projection asymmetry (if any).
3115 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3116 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3117 Standard_Real anOffsetXv = (aMatchDistance[1] - aMatchDistance[0]) * 0.5 + anAssymXv;
3118 Standard_Real anOffsetYv = (aMatchDistance[3] - aMatchDistance[2]) * 0.5 + anAssymYv;
3119 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3120 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3121 gp_Pnt aNewCenter = aBBCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3123 gp_Trsf aCenterTrsf;
3124 aCenterTrsf.SetTranslation (theCamera->Center(), aNewCenter);
3125 theCamera->Transform (aCenterTrsf);
3126 theCamera->SetDistance (aMatchDistance[5] + aMatchDistance[4]);
3128 // Bounding box collapses to a point or thin line going in depth of the screen
3129 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3131 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3133 return Standard_True; // This is just one point or line and zooming has no effect.
3136 // Looking along line and "theToEnlargeIfLine" is requested.
3137 // Fit view to see whole scene on rotation.
3138 aViewSizeXv = aViewSizeZv;
3139 aViewSizeYv = aViewSizeZv;
3142 Scale (theCamera, aViewSizeXv * (1.0 + theMargin), aViewSizeYv * (1.0 + theMargin));
3144 return Standard_True;
3147 // =======================================================================
3149 // purpose : Internal
3150 // =======================================================================
3151 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3152 const Standard_Real theSizeXv,
3153 const Standard_Real theSizeYv) const
3155 Standard_Real anAspect = theCamera->Aspect();
3156 Standard_Real aMaxSize = Max (theSizeXv / anAspect, theSizeYv);
3157 theCamera->SetScale (aMaxSize);
3160 // =======================================================================
3161 // function : Translate
3162 // purpose : Internal
3163 // =======================================================================
3164 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3165 const Standard_Real theDXv,
3166 const Standard_Real theDYv) const
3168 const gp_Pnt& aCenter = theCamera->Center();
3169 const gp_Dir& aDir = theCamera->Direction();
3170 const gp_Dir& anUp = theCamera->Up();
3171 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3173 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3174 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3175 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3177 aPanTrsf.SetTranslation (aCameraPan);
3179 theCamera->Transform (aPanTrsf);
3182 // =======================================================================
3183 // function : IsCullingEnabled
3185 // =======================================================================
3186 Standard_Boolean V3d_View::IsCullingEnabled() const
3188 Graphic3d_CView* aView = (Graphic3d_CView* )MyView->CView();
3189 return aView->IsCullingEnabled;
3192 // =======================================================================
3193 // function : SetFrustumCulling
3195 // =======================================================================
3196 void V3d_View::SetFrustumCulling (const Standard_Boolean theToClip)
3198 Graphic3d_CView* aView = (Graphic3d_CView* )MyView->CView();
3199 aView->IsCullingEnabled = theToClip;