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 24-09-98 : CAL ; Ajout d'un parametre a V3d_View::SetPlotter.
54 06-10-98 : CAL ; Ajout d'un TIMER si CSF_GraphicTimer est definie.
55 16-10-98 : CAL ; Retrait d'un TIMER si CSF_GraphicTimer est definie.
56 06-11-98 : CAL ; PRO ?????. Probleme dans ZFitAll si un point dans la vue.
57 13-06-98 : FMN ; PRO14896: Correction sur la gestion de la perspective (cf Programming Guinde)
58 29-OCT-98 : DCB : Adding ScreenCopy () method.
59 10-11-99 : GG ; PRO19603 Add Redraw( area ) method
61 -> Don't increase too much the ZSize.
62 -> Initialize correctly the Z clipping and D cueing
64 IMP100701 : SZV ; Add ToPixMap() method
68 About FitAll() multiple. This probleme is caused by missing
69 precision of transformation matrices. If it is supposed that
70 projection is made in the plane (U,V), there is a difference
71 after several Zoom - compared to the exact value (cf ZoomX).
72 Don't forget that the matrices work in float and not in double.
73 To solve the problem (for lack of a better solution) I make 2 passes.
75 ************************************************************************/
77 //GER61351 //GG_15/12/99 Add SetBackgroundColor() and BackgroundColor() methods
80 #define IMP020300 //GG Don't use ZFitAll in during Rotation
81 // for perf improvment
83 #define IMP210600 //GG Avoid to have infinite loop when call Rotation() method
84 // without call before StartRotation().
85 // This problem occurs when CTRL MB3 is maintain press betwwen 2 views.
87 #define IMP250900 //GG Enable rotation around screen Z axis when
88 // rotation begin far the center of the screen.
89 // Thanks to Patrick REGINSTER (SAMTECH)
90 // GG 21/12/00 Due to a regression on the previous specifications
91 // this new functionnality is right now deactivated
92 // by default (see StartRotation(...,zRotationThreshold)
95 #define BUC60952 //GG Enable to rotate around the view axis
96 // and the required view point
98 #define RIC120302 //GG Add a NEW SetWindow method which enable
99 // to connect a graphic widget and context to OGL.
101 #define IMP260302 //GG To avoid conflicting in Window destructor
102 // nullify this handle in Remove method
104 #define OCC280 //SAV fix for FitAll problem in the perspective view.
106 #define OCC1188 //SAV Added methods to set background image
108 /*----------------------------------------------------------------------*/
113 #include <Standard_TypeMismatch.hxx>
114 #include <Standard_ShortReal.hxx>
115 #include <Standard_Assert.hxx>
116 #include <Standard_ErrorHandler.hxx>
117 #include <Standard_DivideByZero.hxx>
119 #include <Visual3d_TransientManager.hxx>
120 #include <Visual3d_ViewManager.hxx>
121 #include <Visual3d_Light.hxx>
122 #include <Visual3d_Layer.hxx>
125 #include <V3d_View.ixx>
126 #include <V3d_BadValue.hxx>
127 #include <V3d_StereoDumpOptions.hxx>
129 #include <Image_AlienPixMap.hxx>
131 #include <gp_Dir.hxx>
132 #include <gp_Pln.hxx>
133 #include <TColStd_Array2OfReal.hxx>
134 #include <TColStd_HSequenceOfInteger.hxx>
136 #include <Bnd_Box.hxx>
138 #include <Precision.hxx>
140 #include <Graphic3d_Structure.hxx>
141 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
142 #include <Graphic3d_MapOfStructure.hxx>
143 #include <Graphic3d_TextureEnv.hxx>
144 #include <Graphic3d_AspectMarker3d.hxx>
145 #include <Graphic3d_GraphicDriver.hxx>
148 #include <Aspect_GenericColorMap.hxx>
149 #include <Aspect_TypeMap.hxx>
150 #include <Aspect_WidthMap.hxx>
151 #include <Aspect_MarkMap.hxx>
152 #include <Aspect_FontMap.hxx>
153 #include <Aspect.hxx>
155 #define V3d_FLAG_COMPUTATION 0x00000004
158 #include <OSD_Environment.hxx>
160 /*----------------------------------------------------------------------*/
165 #define DEUXPI (2. * M_PI)
167 //=============================================================================
168 //function : Constructor
170 //=============================================================================
171 V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) :
172 MyProjModel(V3d_TPM_SCREEN),
173 MyViewer(VM.operator->()),
176 myActiveLightsIterator(),
177 SwitchSetFront(Standard_False),
179 myAutoZFitIsOn (Standard_True),
180 myAutoZFitScaleFactor (1.0)
182 myImmediateUpdate = Standard_False;
183 MyView = new Visual3d_View(MyViewer->Viewer());
185 // { Begin to retrieve the definition from ViewContext.
186 // Step MyViewContext = MyView->Context() ;
187 // to permit MyView->SetContext to compare
188 // the old and the new context.
189 // No problem for MyViewMapping, MyViewOrientation
190 // as MyView->SetViewMapping and MyView->SetViewOrientation
191 // don't try to optimize the modifications introduced to
192 // viewmapping and vieworientation.
195 if ((MyView->Context ()).AliasingIsOn ())
196 MyViewContext.SetAliasingOn ();
198 MyViewContext.SetAliasingOff ();
201 MyViewContext.SetDepthCueingBackPlane
202 ((MyView->Context ()).DepthCueingBackPlane ());
203 MyViewContext.SetDepthCueingFrontPlane
204 ((MyView->Context ()).DepthCueingFrontPlane ());
206 if ((MyView->Context ()).DepthCueingIsOn ())
207 MyViewContext.SetDepthCueingOn ();
209 MyViewContext.SetDepthCueingOff ();
212 MyViewContext.SetZClippingBackPlane
213 ((MyView->Context ()).ZClippingBackPlane ());
214 MyViewContext.SetZClippingFrontPlane
215 ((MyView->Context ()).ZClippingFrontPlane ());
217 if ((MyView->Context ()).FrontZClippingIsOn ())
218 MyViewContext.SetFrontZClippingOn ();
220 MyViewContext.SetFrontZClippingOff ();
222 if ((MyView->Context ()).BackZClippingIsOn ())
223 MyViewContext.SetBackZClippingOn ();
225 MyViewContext.SetBackZClippingOff ();
227 // Visualization and Shading Model
228 MyViewContext.SetModel ((MyView->Context ()).Model ());
229 MyViewContext.SetVisualization ((MyView->Context ()).Visualization ());
232 MyViewContext.SetSurfaceDetail (MyView->Context ().SurfaceDetail ());
233 MyViewContext.SetTextureEnv (MyView->Context ().TextureEnv ());
234 // } End of retrieval of the definition of ViewContext.
236 MyBackground = VM->GetBackgroundColor() ;
237 MyGradientBackground = VM->GetGradientBackground() ;
240 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
241 aCamera->SetFOVy (45.0);
242 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
243 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
246 SetAxis (0.,0.,0.,1.,1.,1.);
247 SetVisualization (VM->DefaultVisualization());
248 SetShadingModel (VM->DefaultShadingModel());
249 SetSurfaceDetail (VM->DefaultSurfaceDetail());
252 SetProj (VM->DefaultViewProj());
253 SetSize (VM->DefaultViewSize());
254 Standard_Real zsize = VM->DefaultViewSize();
256 SetZClippingDepth (0.);
257 SetZClippingWidth (zsize);
258 SetZCueingDepth (0.);
259 SetZCueingWidth (zsize);
260 SetDepth (VM->DefaultViewSize()/2.0);
261 SetViewMappingDefault();
264 myImmediateUpdate = Standard_True;
266 aCamera->SetProjectionType ((Type == V3d_ORTHOGRAPHIC)
267 ? Graphic3d_Camera::Projection_Orthographic
268 : Graphic3d_Camera::Projection_Perspective);
270 MyTransparencyFlag = Standard_False;
273 //=============================================================================
274 //function : Constructor
276 //=============================================================================
277 V3d_View::V3d_View(const Handle(V3d_Viewer)& theVM,const Handle(V3d_View)& theView) :
278 MyProjModel(V3d_TPM_SCREEN),
279 MyViewer(theVM.operator->()),
282 myActiveLightsIterator(),
283 SwitchSetFront(Standard_False),
286 Handle(Visual3d_View) aFromView = theView->View();
288 myImmediateUpdate = Standard_False;
289 MyView = new Visual3d_View (MyViewer->Viewer());
291 for (theView->InitActiveLights(); theView->MoreActiveLights(); theView->NextActiveLights())
293 MyActiveLights.Append (theView->ActiveLight());
296 MyViewContext = aFromView->Context() ;
298 SetCamera (new Graphic3d_Camera (theView->Camera()));
299 myAutoZFitIsOn = theView->AutoZFitMode();
300 myAutoZFitScaleFactor = theView->AutoZFitScaleFactor();
302 MyBackground = aFromView->Background() ;
303 MyGradientBackground = aFromView->GradientBackground();
305 MyView->SetContext (MyViewContext) ;
307 SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
309 theVM->AddView (this);
313 myImmediateUpdate = Standard_True;
316 //=============================================================================
317 //function : SetMagnify
319 //=============================================================================
320 void V3d_View::SetMagnify(const Handle(Aspect_Window)& TheWindow,
321 const Handle(V3d_View)& aPreviousView,
322 const Standard_Integer x1,
323 const Standard_Integer y1,
324 const Standard_Integer x2,
325 const Standard_Integer y2)
327 if( !MyView->IsDefined() ) {
328 Standard_Real a,b,c,d;
329 aPreviousView->Convert(x1,y1,a,b);
330 aPreviousView->Convert(x2,y2,c,d);
331 MyView->SetWindow(TheWindow) ;
332 FitAll(TheWindow,a,b,c,d);
333 MyView->SetContext(MyViewContext) ;
334 MyView->SetBackground(MyBackground) ;
335 MyViewer->SetViewOn(this) ;
336 MyWindow = TheWindow;
338 SetViewMappingDefault();
342 //=============================================================================
343 //function : SetWindow
345 //=============================================================================
346 void V3d_View::SetWindow(const Handle(Aspect_Window)& TheWindow)
348 Standard_MultiplyDefined_Raise_if( MyView->IsDefined(),
349 "V3d_View::SetWindow, window of view already defined");
351 MyView->SetWindow(TheWindow) ;
352 // AGV: Method V3d_View::SetWindow() should assign the field MyWindow before
353 // calling Redraw(). Otherwise it is impossible to call certain methods of
354 // V3d_View like Convert() inside the context of Redraw(),
355 // particularly in class NIS_View.
356 MyWindow = TheWindow;
357 // SetWindow carries out SetRatio and modifies
358 MyView->SetContext(MyViewContext) ;
359 MyView->SetBackground(MyBackground) ;
360 MyViewer->SetViewOn(this) ;
364 //=============================================================================
365 //function : SetWindow
367 //=============================================================================
368 void V3d_View::SetWindow(const Handle(Aspect_Window)& aWindow,
369 const Aspect_RenderingContext aContext,
370 const Aspect_GraphicCallbackProc& aDisplayCB,
371 const Standard_Address aClientData)
373 Standard_MultiplyDefined_Raise_if( MyView->IsDefined(),
374 "V3d_View::SetWindow, "
375 "window of view already defined");
376 // AGV: Method V3d_View::SetWindow() should assign the field MyWindow before
377 // calling Redraw(). Otherwise it is impossible to call certain methods of
378 // V3d_View like Convert() inside the context of Redraw(),
379 // particularly in class NIS_View.
381 MyView->SetWindow(aWindow, aContext, aDisplayCB, aClientData) ;
382 MyView->SetContext(MyViewContext) ;
383 MyView->SetBackground(MyBackground) ;
384 MyViewer->SetViewOn(this) ;
388 //=============================================================================
391 //=============================================================================
392 void V3d_View::Remove() const
394 MyViewer->DelView (this);
396 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
400 //=============================================================================
403 //=============================================================================
404 void V3d_View::Update() const
406 if( MyView->IsDefined() ) MyView->Update() ;
409 //=============================================================================
412 //=============================================================================
413 void V3d_View::Redraw() const
415 if( MyView->IsDefined() ) MyView->Redraw() ;
418 //=============================================================================
421 //=============================================================================
422 void V3d_View::Redraw(const Standard_Integer xc,const Standard_Integer yc,
423 const Standard_Integer width,const Standard_Integer height) const
425 if( MyView->IsDefined() ) MyView->Redraw(xc,yc,width,height) ;
428 //=============================================================================
431 //=============================================================================
432 Standard_Boolean V3d_View::IsEmpty() const
434 Standard_Boolean TheStatus = Standard_True ;
435 if( MyView->IsDefined() ) {
436 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
437 if( Nstruct > 0 ) TheStatus = Standard_False ;
442 //=============================================================================
443 //function : UpdateLights
445 //=============================================================================
446 void V3d_View::UpdateLights() const
448 MyView->SetContext(MyViewContext);
452 //=============================================================================
453 //function : DoMapping
455 //=============================================================================
456 void V3d_View::DoMapping()
458 if( MyView->IsDefined() ) {
459 (MyView->Window())->DoMapping() ;
463 //=============================================================================
464 //function : MustBeResized
466 //=============================================================================
467 void V3d_View::MustBeResized()
469 if ( !MyLayerMgr.IsNull() )
470 MyLayerMgr->Resized();
472 if( MyView->IsDefined() ) {
478 //=============================================================================
479 //function : SetBackgroundColor
481 //=============================================================================
482 void V3d_View::SetBackgroundColor(const Quantity_TypeOfColor Type, const Standard_Real v1, const Standard_Real v2, const Standard_Real v3)
484 Standard_Real V1 = Max( Min( v1, 1.0 ), 0.0 );
485 Standard_Real V2 = Max( Min( v2, 1.0 ), 0.0 );
486 Standard_Real V3 = Max( Min( v3, 1.0 ), 0.0 );
488 Quantity_Color C( V1, V2, V3, Type );
489 SetBackgroundColor( C );
492 //=============================================================================
493 //function : SetBackgroundColor
495 //=============================================================================
496 void V3d_View::SetBackgroundColor(const Quantity_Color &Color)
498 MyBackground.SetColor( Color );
499 if ( MyView->IsDefined() )
500 MyView->SetBackground( MyBackground );
502 if ( !MyLayerMgr.IsNull() )
503 MyLayerMgr->Resized();
506 //=============================================================================
507 //function : SetBackgroundColor
509 //=============================================================================
510 void V3d_View::SetBackgroundColor(const Quantity_NameOfColor Name)
512 Quantity_Color C( Name );
513 SetBackgroundColor( C );
516 //=============================================================================
517 //function : SetBgGradientColors
519 //=============================================================================
520 void V3d_View::SetBgGradientColors( const Quantity_Color& Color1,
521 const Quantity_Color& Color2,
522 const Aspect_GradientFillMethod FillStyle,
523 const Standard_Boolean status)
525 MyGradientBackground.SetColors(Color1, Color2, FillStyle);
526 if ( MyView->IsDefined() )
527 MyView->SetGradientBackground( MyGradientBackground, status );
530 //=============================================================================
531 //function : SetBgGradientColors
533 //=============================================================================
534 void V3d_View::SetBgGradientColors( const Quantity_NameOfColor Color1,
535 const Quantity_NameOfColor Color2,
536 const Aspect_GradientFillMethod FillStyle,
537 const Standard_Boolean status )
539 Quantity_Color C1( Color1 );
540 Quantity_Color C2( Color2 );
541 MyGradientBackground.SetColors( C1, C2, FillStyle );
542 if ( MyView->IsDefined() )
543 MyView->SetGradientBackground( MyGradientBackground, status );
546 //=============================================================================
547 //function : SetBgGradientStyle
549 //=============================================================================
550 void V3d_View::SetBgGradientStyle( const Aspect_GradientFillMethod FillStyle,
551 const Standard_Boolean update)
553 Quantity_Color Color1, Color2;
554 MyGradientBackground.Colors( Color1, Color2 );
555 MyGradientBackground.SetColors( Color1, Color2, FillStyle );
556 if( MyView->IsDefined() )
557 MyView->SetBgGradientStyle( FillStyle, update ) ;
560 //=============================================================================
561 //function : SetBackgroundImage
563 //=============================================================================
564 void V3d_View::SetBackgroundImage( const Standard_CString FileName,
565 const Aspect_FillMethod FillStyle,
566 const Standard_Boolean update )
569 if( MyView->IsDefined() )
570 MyView->SetBackgroundImage( FileName, FillStyle, update ) ;
574 //=============================================================================
575 //function : SetBgImageStyle
577 //=============================================================================
578 void V3d_View::SetBgImageStyle( const Aspect_FillMethod FillStyle,
579 const Standard_Boolean update )
582 if( MyView->IsDefined() )
583 MyView->SetBgImageStyle( FillStyle, update ) ;
587 //=============================================================================
590 //=============================================================================
591 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)
593 Standard_Real D,Nx = Vx,Ny = Vy,Nz = Vz ;
595 D = Sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) ;
596 V3d_BadValue_Raise_if ( D <= 0. , "V3d_View::SetAxis, bad axis");
597 Nx /= D ; Ny /= D ; Nz /= D ;
598 MyDefaultViewPoint.SetCoord(X,Y,Z) ;
599 MyDefaultViewAxis.SetCoord(Nx,Ny,Nz) ;
602 //=============================================================================
603 //function : SetShadingModel
605 //=============================================================================
606 void V3d_View::SetShadingModel(const V3d_TypeOfShadingModel Model)
608 MyViewContext.SetModel((Visual3d_TypeOfModel) Model) ;
609 MyView->SetContext(MyViewContext) ;
612 //=============================================================================
613 //function : SetSurfaceDetail
615 //=============================================================================
616 void V3d_View::SetSurfaceDetail(const V3d_TypeOfSurfaceDetail Model)
618 MyViewContext.SetSurfaceDetail((Visual3d_TypeOfSurfaceDetail) Model) ;
619 MyView->SetContext(MyViewContext) ;
622 //=============================================================================
623 //function : SetTextureEnv
625 //=============================================================================
626 void V3d_View::SetTextureEnv(const Handle(Graphic3d_TextureEnv)& ATexture)
628 MyViewContext.SetTextureEnv(ATexture) ;
629 MyView->SetContext(MyViewContext) ;
632 //=============================================================================
633 //function : SetVisualization
635 //=============================================================================
636 void V3d_View::SetVisualization(const V3d_TypeOfVisualization Mode)
638 MyViewContext.SetVisualization((Visual3d_TypeOfVisualization) Mode);
639 MyView->SetContext(MyViewContext) ;
642 //=============================================================================
643 //function : SetFront
645 //=============================================================================
646 void V3d_View::SetFront()
648 gp_Ax3 a = MyViewer->PrivilegedPlane();
649 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
651 a.Direction().Coord(vx,vy,vz);
652 a.YDirection().Coord(xu,yu,zu);
653 a.Location().Coord(xo,yo,zo);
655 myCamera->SetCenter (gp_Pnt (xo, yo, zo));
657 myCamera->SetDirection (gp_Dir (vx, vy, vz));
659 myCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
660 myCamera->SetUp (gp_Dir (xu, yu, zu));
664 SwitchSetFront = !SwitchSetFront;
669 //=============================================================================
672 //=============================================================================
673 void V3d_View::Rotate (const Standard_Real ax,
674 const Standard_Real ay,
675 const Standard_Real az,
676 const Standard_Boolean Start)
678 Standard_Real Ax = ax;
679 Standard_Real Ay = ay;
680 Standard_Real Az = az;
682 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
683 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
684 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
685 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
686 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
687 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
691 myCamStartOpUp = myCamera->Up();
692 myCamStartOpEye = myCamera->Eye();
693 myCamStartOpCenter = myCamera->Center();
696 myCamera->SetUp (myCamStartOpUp);
697 myCamera->SetEye (myCamStartOpEye);
698 myCamera->SetCenter (myCamStartOpCenter);
700 // rotate camera around 3 initial axes
701 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
702 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
703 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
704 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
706 gp_Trsf aRot[3], aTrsf;
707 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
708 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
709 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
710 aTrsf.Multiply (aRot[0]);
711 aTrsf.Multiply (aRot[1]);
712 aTrsf.Multiply (aRot[2]);
714 myCamera->Transform (aTrsf);
721 //=============================================================================
724 //=============================================================================
725 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
726 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
729 Standard_Real Ax = ax ;
730 Standard_Real Ay = ay ;
731 Standard_Real Az = az ;
733 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
734 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
735 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
736 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
737 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
738 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
742 myGravityReferencePoint.SetCoord (X, Y, Z);
743 myCamStartOpUp = myCamera->Up();
744 myCamStartOpEye = myCamera->Eye();
745 myCamStartOpCenter = myCamera->Center();
748 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
750 myCamera->SetUp (myCamStartOpUp);
751 myCamera->SetEye (myCamStartOpEye);
752 myCamera->SetCenter (myCamStartOpCenter);
754 // rotate camera around 3 initial axes
755 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
757 gp_Dir aZAxis (myCamera->Direction().Reversed());
758 gp_Dir aYAxis (myCamera->Up());
759 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
761 gp_Trsf aRot[3], aTrsf;
762 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
763 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
764 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
765 aTrsf.Multiply (aRot[0]);
766 aTrsf.Multiply (aRot[1]);
767 aTrsf.Multiply (aRot[2]);
769 myCamera->Transform (aTrsf);
776 //=============================================================================
779 //=============================================================================
780 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
784 Rotate(angle,0.,0.,Start);
787 Rotate(0.,angle,0.,Start);
790 Rotate(0.,0.,angle,Start);
795 //=============================================================================
798 //=============================================================================
799 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
800 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
802 Standard_Real Angle = angle ;
804 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
805 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
809 myGravityReferencePoint.SetCoord (X, Y, Z);
810 myCamStartOpUp = myCamera->Up();
811 myCamStartOpEye = myCamera->Eye();
812 myCamStartOpCenter = myCamera->Center();
816 myViewAxis.SetCoord(1.,0.,0.) ;
819 myViewAxis.SetCoord(0.,1.,0.) ;
822 myViewAxis.SetCoord(0.,0.,1.) ;
826 myCamStartOpUp = myCamera->Up();
827 myCamStartOpEye = myCamera->Eye();
828 myCamStartOpCenter = myCamera->Center();
831 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
833 myCamera->SetUp (myCamStartOpUp);
834 myCamera->SetEye (myCamStartOpEye);
835 myCamera->SetCenter (myCamStartOpCenter);
837 // rotate camera around passed axis
839 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
840 gp_Dir aRAxis ((Axe == V3d_X) ? 1.0 : 0.0,
841 (Axe == V3d_Y) ? 1.0 : 0.0,
842 (Axe == V3d_Z) ? 1.0 : 0.0);
844 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
845 myCamera->Transform (aRotation);
852 //=============================================================================
855 //=============================================================================
856 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
858 Standard_Real Angle = angle;
860 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
861 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
864 myCamStartOpUp = myCamera->Up();
865 myCamStartOpEye = myCamera->Eye();
866 myCamStartOpCenter = myCamera->Center();
869 const Graphic3d_Vertex& aPnt = MyDefaultViewPoint;
870 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
872 myCamera->SetUp (myCamStartOpUp);
873 myCamera->SetEye (myCamStartOpEye);
874 myCamera->SetCenter (myCamStartOpCenter);
877 gp_Pnt aRCenter (aPnt.X(), aPnt.Y(), aPnt.Z());
878 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
879 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
880 myCamera->Transform (aRotation);
887 //=============================================================================
890 //=============================================================================
891 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
893 Standard_Real Ax = ax;
894 Standard_Real Ay = ay;
895 Standard_Real Az = az;
897 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
898 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
899 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
900 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
901 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
902 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
905 myCamStartOpUp = myCamera->Up();
906 myCamStartOpEye = myCamera->Eye();
907 myCamStartOpCenter = myCamera->Center();
910 myCamera->SetUp (myCamStartOpUp);
911 myCamera->SetEye (myCamStartOpEye);
912 myCamera->SetCenter (myCamStartOpCenter);
914 // rotate camera around 3 initial axes
915 gp_Pnt aRCenter = myCamera->Eye();
916 gp_Dir aZAxis (myCamera->Direction().Reversed());
917 gp_Dir aYAxis (myCamera->Up());
918 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
920 gp_Trsf aRot[3], aTrsf;
921 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
922 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
923 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
924 aTrsf.Multiply (aRot[0]);
925 aTrsf.Multiply (aRot[1]);
926 aTrsf.Multiply (aRot[2]);
928 myCamera->Transform (aTrsf);
935 //=============================================================================
938 //=============================================================================
939 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
943 Turn(angle,0.,0.,Start);
946 Turn(0.,angle,0.,Start);
949 Turn(0.,0.,angle,Start);
954 //=============================================================================
957 //=============================================================================
958 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
960 Standard_Real Angle = angle ;
962 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
963 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
966 myCamStartOpUp = myCamera->Up();
967 myCamStartOpEye = myCamera->Eye();
968 myCamStartOpCenter = myCamera->Center();
971 myCamera->SetUp (myCamStartOpUp);
972 myCamera->SetEye (myCamStartOpEye);
973 myCamera->SetCenter (myCamStartOpCenter);
975 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
978 gp_Pnt aRCenter = myCamera->Eye();
979 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
980 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
981 myCamera->Transform (aRotation);
988 //=============================================================================
989 //function : SetTwist
991 //=============================================================================
992 void V3d_View::SetTwist(const Standard_Real angle)
994 Standard_Real Angle = angle ;
995 Standard_Boolean TheStatus;
997 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
998 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
1000 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1003 anUp = gp_Dir (0.0, 0.0, 1.0);
1005 TheStatus = ScreenAxis(aReferencePlane, anUp,
1006 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1008 anUp = gp_Dir (0.0, 1.0, 0.0);
1009 TheStatus = ScreenAxis(aReferencePlane, anUp,
1010 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1013 anUp = gp_Dir (1.0, 0.0, 0.0);
1014 TheStatus = ScreenAxis(aReferencePlane, anUp,
1015 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1018 V3d_BadValue_Raise_if( !TheStatus,"V3d_ViewSetTwist, alignment of Eye,At,Up,");
1020 gp_Pnt aRCenter = myCamera->Center();
1021 gp_Dir aZAxis (myCamera->Direction().Reversed());
1024 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
1026 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1027 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1029 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1030 myCamera->Transform (aTrsf);
1037 //=============================================================================
1038 //function : SetAutoZFitMode
1040 //=============================================================================
1041 void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn, const Standard_Real theScaleFactor)
1043 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
1044 myAutoZFitScaleFactor = theScaleFactor;
1045 myAutoZFitIsOn = theIsOn;
1048 //=============================================================================
1049 //function : AutoZFitMode
1051 //=============================================================================
1052 Standard_Boolean V3d_View::AutoZFitMode() const
1054 return myAutoZFitIsOn;
1057 //=============================================================================
1058 //function : AutoZFitScaleFactor
1060 //=============================================================================
1061 Standard_Real V3d_View::AutoZFitScaleFactor () const
1063 return myAutoZFitScaleFactor;
1066 //=============================================================================
1069 //=============================================================================
1070 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1072 Standard_Real aTwistBefore = Twist();
1074 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1076 myCamera->SetEye (gp_Pnt (X, Y, Z));
1077 SetTwist (aTwistBefore);
1081 SetImmediateUpdate (wasUpdateEnabled);
1086 //=============================================================================
1087 //function : SetDepth
1089 //=============================================================================
1090 void V3d_View::SetDepth(const Standard_Real Depth)
1092 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1096 // Move eye using center (target) as anchor.
1097 myCamera->SetDistance (Depth);
1101 // Move the view ref point instead of the eye.
1102 gp_Vec aDir (myCamera->Direction());
1103 gp_Pnt aCameraEye = myCamera->Eye();
1104 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1106 myCamera->SetCenter (aCameraCenter);
1114 //=============================================================================
1115 //function : SetProj
1117 //=============================================================================
1118 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1120 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1121 "V3d_View::SetProj, null projection vector");
1123 Standard_Real aTwistBefore = Twist();
1125 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1127 myCamera->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1129 if (MyProjModel == V3d_TPM_SCREEN)
1131 SetTwist(aTwistBefore);
1136 SetImmediateUpdate (wasUpdateEnabled);
1141 //=============================================================================
1142 //function : SetProj
1144 //=============================================================================
1145 void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1147 Standard_Real Xpn=0;
1148 Standard_Real Ypn=0;
1149 Standard_Real Zpn=0;
1151 switch (Orientation) {
1162 const Graphic3d_Vector& aBck = V3d::GetProjAxis (Orientation);
1164 // retain camera panning from origin when switching projection
1165 gp_Pnt anOriginVCS = myCamera->ConvertWorld2View (gp::Origin());
1166 Standard_Real aPanX = anOriginVCS.X();
1167 Standard_Real aPanY = anOriginVCS.Y();
1169 myCamera->SetCenter (gp_Pnt (0, 0, 0));
1170 myCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1171 myCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
1172 myCamera->OrthogonalizeUp();
1174 Panning (aPanX, aPanY);
1181 //=============================================================================
1184 //=============================================================================
1185 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1187 Standard_Real aTwistBefore = Twist();
1189 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1191 myCamera->SetCenter (gp_Pnt (X, Y, Z));
1193 SetTwist (aTwistBefore);
1197 SetImmediateUpdate (wasUpdateEnabled);
1202 //=============================================================================
1205 //=============================================================================
1206 void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standard_Real Vz)
1208 Standard_Boolean TheStatus ;
1209 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0. ,
1210 "V3d_View::SetUp, nullUp vector");
1212 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1213 gp_Dir anUp (Vx, Vy, Vz);
1215 TheStatus = ScreenAxis(aReferencePlane,anUp,
1216 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1218 anUp = gp_Dir (0.0, 0.0, 1.0);
1219 TheStatus = ScreenAxis(aReferencePlane,anUp,
1220 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1223 anUp = gp_Dir (0.0, 1.0, 0.0);
1224 TheStatus = ScreenAxis(aReferencePlane,anUp,
1225 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1228 anUp = gp_Dir (1.0, 0.0, 0.0);
1229 TheStatus = ScreenAxis(aReferencePlane,anUp,
1230 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1232 V3d_BadValue_Raise_if( !TheStatus,"V3d_View::Setup, alignment of Eye,At,Up");
1234 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1235 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1237 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1244 //=============================================================================
1247 //=============================================================================
1248 void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
1250 Standard_Boolean TheStatus ;
1252 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1255 const Graphic3d_Vector& aViewReferenceUp = V3d::GetProjAxis(Orientation) ;
1256 anUp = gp_Dir (aViewReferenceUp.X(), aViewReferenceUp.Y(), aViewReferenceUp.Z());
1258 TheStatus = ScreenAxis(aReferencePlane,anUp,
1259 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1261 anUp = gp_Dir (0.,0.,1.);
1262 TheStatus = ScreenAxis(aReferencePlane,anUp,
1263 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1266 anUp = gp_Dir (0.,1.,0.);
1267 TheStatus = ScreenAxis(aReferencePlane,anUp,
1268 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1271 anUp = gp_Dir (1.,0.,0.);
1272 TheStatus = ScreenAxis(aReferencePlane,anUp,
1273 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1275 V3d_BadValue_Raise_if( !TheStatus, "V3d_View::SetUp, alignment of Eye,At,Up");
1277 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1278 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1280 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1287 //=============================================================================
1288 //function : SetViewOrientationDefault
1290 //=============================================================================
1291 void V3d_View::SetViewOrientationDefault()
1293 MyView->SetViewOrientationDefault() ;
1298 //=============================================================================
1299 //function : ResetViewOrientation
1301 //=============================================================================
1302 void V3d_View::ResetViewOrientation()
1304 MyView->ViewOrientationReset() ;
1309 //=============================================================================
1312 //=============================================================================
1313 void V3d_View::Reset( const Standard_Boolean update )
1315 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1317 if (!aDefaultCamera.IsNull())
1319 myCamera->CopyMappingData (aDefaultCamera);
1320 myCamera->CopyOrientationData (aDefaultCamera);
1325 SwitchSetFront = Standard_False;
1327 if( !myImmediateUpdate && update ) Update();
1330 //=======================================================================
1331 //function : SetCenter
1333 //=======================================================================
1334 void V3d_View::SetCenter (const Standard_Integer theXp,
1335 const Standard_Integer theYp)
1337 Standard_Real aXv, aYv;
1338 Convert (theXp, theYp, aXv, aYv);
1339 Translate (myCamera, aXv, aYv);
1344 //=============================================================================
1345 //function : SetSize
1347 //=============================================================================
1348 void V3d_View::SetSize (const Standard_Real theSize)
1350 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1352 myCamera->SetScale (myCamera->Aspect() >= 1.0 ? theSize / myCamera->Aspect() : theSize);
1359 //=============================================================================
1360 //function : SetZSize
1362 //=============================================================================
1363 void V3d_View::SetZSize(const Standard_Real Size)
1365 Standard_Real Zmax = Size/2.;
1367 Standard_Real aDistance = myCamera->Distance();
1373 Standard_Real Front = MyViewContext.ZClippingFrontPlane();
1374 Standard_Real Back = MyViewContext.ZClippingBackPlane();
1376 // ShortReal precision factor used to add meaningful tolerance to
1377 // ZNear, ZFar values in order to avoid equality after type conversion
1378 // to ShortReal matrices type.
1379 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1381 Standard_Real aZFar = Zmax + aDistance * 2.0;
1382 Standard_Real aZNear = -Zmax + aDistance;
1383 aZNear -= Abs (aZNear) * aPrecision;
1384 aZFar += Abs (aZFar) * aPrecision;
1386 if (!myCamera->IsOrthographic())
1388 if (aZFar < aPrecision)
1390 // Invalid case when both values are negative
1391 aZNear = aPrecision;
1392 aZFar = aPrecision * 2.0;
1394 else if (aZNear < Abs (aZFar) * aPrecision)
1396 // Z is less than 0.0, try to fix it using any appropriate z-scale
1397 aZNear = Abs (aZFar) * aPrecision;
1401 // If range is too small
1402 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1404 aZFar = aZNear + Abs (aZFar) * aPrecision;
1407 myCamera->SetZRange (aZNear, aZFar);
1409 if (MyViewContext.FrontZClippingIsOn() ||
1410 MyViewContext.BackZClippingIsOn())
1412 MyViewContext.SetZClippingFrontPlane (Front);
1413 MyViewContext.SetZClippingBackPlane (Back);
1414 MyView->SetContext (MyViewContext);
1418 //=============================================================================
1419 //function : SetZoom
1421 //=============================================================================
1422 void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1424 V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
1428 myCamStartOpEye = myCamera->Eye();
1429 myCamStartOpCenter = myCamera->Center();
1432 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
1433 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
1435 // ensure that zoom will not be too small or too big
1436 Standard_Real coef = Coef;
1437 if (aViewWidth < coef * Precision::Confusion())
1439 coef = aViewWidth / Precision::Confusion();
1441 else if (aViewWidth > coef * 1e12)
1443 coef = aViewWidth / 1e12;
1445 if (aViewHeight < coef * Precision::Confusion())
1447 coef = aViewHeight / Precision::Confusion();
1449 else if (aViewHeight > coef * 1e12)
1451 coef = aViewHeight / 1e12;
1454 myCamera->SetEye (myCamStartOpEye);
1455 myCamera->SetCenter (myCamStartOpCenter);
1456 myCamera->SetScale (myCamera->Scale() / Coef);
1462 //=============================================================================
1463 //function : SetScale
1465 //=============================================================================
1466 void V3d_View::SetScale( const Standard_Real Coef )
1468 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1470 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1472 // Strange behavior for the sake of compatibility.
1473 if (!aDefaultCamera.IsNull())
1475 myCamera->SetAspect (aDefaultCamera->Aspect());
1476 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1477 myCamera->SetScale (aDefaultScale / Coef);
1481 myCamera->SetScale (myCamera->Scale() / Coef);
1489 //=============================================================================
1490 //function : SetAxialScale
1492 //=============================================================================
1493 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1495 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1497 myCamera->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1501 //=============================================================================
1504 //=============================================================================
1505 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1507 Standard_ASSERT_RAISE (theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1509 if (MyView->NumberOfDisplayedStructures() == 0)
1514 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
1515 MyView->MinMaxValues (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1516 gp_XYZ aMin (aXmin, aYmin, aZmin);
1517 gp_XYZ aMax (aXmax, aYmax, aZmax);
1519 if (!FitMinMax (myCamera, aMin, aMax, theMargin, 10.0 * Precision::Confusion()))
1526 if (myImmediateUpdate || theToUpdate)
1532 //=============================================================================
1533 //function : AutoZFit
1535 //=============================================================================
1536 void V3d_View::AutoZFit()
1538 if (!AutoZFitMode())
1543 ZFitAll (myAutoZFitScaleFactor);
1546 //=============================================================================
1547 //function : ZFitAll
1549 //=============================================================================
1550 void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
1552 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
1554 // Method changes ZNear and ZFar planes of camera so as to fit the graphical structures
1555 // by their real boundaries (computed ignoring infinite flag) into the viewing volume.
1556 // In addition to the graphical boundaries, the usual min max used for fitting perspective
1557 // camera. To avoid numeric errors for perspective camera the negative ZNear values are
1558 // fixed using tolerance distance, relative to boundaries size. The tolerance distance
1559 // should be computed using information on boundaries of primary application actors,
1560 // (e.g. representing the displayed model) - to ensure that they are not unreasonably clipped.
1562 Standard_Real aMinMax[6]; // applicative min max boundaries
1563 View()->MinMaxValues (aMinMax[0], aMinMax[1], aMinMax[2],
1564 aMinMax[3], aMinMax[4], aMinMax[5],
1567 Standard_Real aGraphicBB[6]; // real graphical boundaries (not accounting infinite flag).
1568 View()->MinMaxValues (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2],
1569 aGraphicBB[3], aGraphicBB[4], aGraphicBB[5],
1572 // Check if anything can be adjusted
1573 Standard_Real aLim = (ShortRealLast() - 1.0);
1574 if (Abs (aGraphicBB[0]) > aLim || Abs (aGraphicBB[1]) > aLim || Abs (aGraphicBB[2]) > aLim ||
1575 Abs (aGraphicBB[3]) > aLim || Abs (aGraphicBB[4]) > aLim || Abs (aGraphicBB[5]) > aLim)
1582 // Measure depth of boundary points from camera eye
1583 gp_Pnt aPntsToMeasure[16] =
1585 gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[2]),
1586 gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[5]),
1587 gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[2]),
1588 gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[5]),
1589 gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[2]),
1590 gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[5]),
1591 gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[2]),
1592 gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[5]),
1594 gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2]),
1595 gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[5]),
1596 gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[2]),
1597 gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[5]),
1598 gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[2]),
1599 gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[5]),
1600 gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[2]),
1601 gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[5])
1605 gp_Dir aCamDir = myCamera->Direction();
1606 gp_Pnt aCamEye = myCamera->Eye();
1607 gp_Pln aCamPln (aCamEye, aCamDir);
1609 Standard_Real aModelMinDist = RealLast();
1610 Standard_Real aModelMaxDist = RealFirst();
1611 Standard_Real aGraphicMinDist = RealLast();
1612 Standard_Real aGraphicMaxDist = RealFirst();
1614 const gp_XYZ& anAxialScale = myCamera->AxialScale();
1616 // Get minimum and maximum distances to the eye plane
1617 for (Standard_Integer aPntIt = 0; aPntIt < 16; ++aPntIt)
1619 gp_Pnt aMeasurePnt = aPntsToMeasure[aPntIt];
1621 if (Abs (aMeasurePnt.X()) > aLim || Abs (aMeasurePnt.Y()) > aLim || Abs (aMeasurePnt.Z()) > aLim)
1626 aMeasurePnt = gp_Pnt (aMeasurePnt.X() * anAxialScale.X(),
1627 aMeasurePnt.Y() * anAxialScale.Y(),
1628 aMeasurePnt.Z() * anAxialScale.Z());
1630 Standard_Real aDistance = aCamPln.Distance (aMeasurePnt);
1632 // Check if the camera is intruded into the scene
1633 if (aCamDir.IsOpposite (gp_Vec (aCamEye, aMeasurePnt), M_PI * 0.5))
1638 Standard_Real& aChangeMinDist = aPntIt >= 8 ? aGraphicMinDist : aModelMinDist;
1639 Standard_Real& aChangeMaxDist = aPntIt >= 8 ? aGraphicMaxDist : aModelMaxDist;
1640 aChangeMinDist = Min (aDistance, aChangeMinDist);
1641 aChangeMaxDist = Max (aDistance, aChangeMaxDist);
1644 // Compute depth of bounding box center
1645 Standard_Real aMidDepth = (aGraphicMinDist + aGraphicMaxDist) * 0.5;
1646 Standard_Real aHalfDepth = (aGraphicMaxDist - aGraphicMinDist) * 0.5;
1648 // ShortReal precision factor used to add meaningful tolerance to
1649 // ZNear, ZFar values in order to avoid equality after type conversion
1650 // to ShortReal matrices type.
1651 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1653 // Compute enlarged or shrank near and far z ranges
1654 Standard_Real aZNear = aMidDepth - aHalfDepth * theScaleFactor;
1655 Standard_Real aZFar = aMidDepth + aHalfDepth * theScaleFactor;
1656 aZNear -= Abs (aZNear) * aPrecision;
1657 aZFar += Abs (aZFar) * aPrecision;
1659 if (!myCamera->IsOrthographic())
1661 if (aZFar >= aPrecision)
1663 // To avoid numeric errors... (See comments in the beginning of the method).
1664 // Choose between model distance and graphical distance, as the model boundaries
1665 // might be infinite if all structures have infinite flag.
1666 const Standard_Real aGraphicDepth = aGraphicMaxDist >= aGraphicMinDist
1667 ? aGraphicMaxDist - aGraphicMinDist : RealLast();
1669 const Standard_Real aModelDepth = aModelMaxDist >= aModelMinDist
1670 ? aModelMaxDist - aModelMinDist : RealLast();
1672 const Standard_Real aMinDepth = Min (aModelDepth, aGraphicDepth);
1673 const Standard_Real aZTolerance =
1674 Max (Abs (aMinDepth) * aPrecision, aPrecision);
1676 if (aZNear < aZTolerance)
1678 aZNear = aZTolerance;
1681 else // aZFar < aPrecision - Invalid case when both ZNear and ZFar are negative
1683 aZNear = aPrecision;
1684 aZFar = aPrecision * 2.0;
1688 // If range is too small
1689 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1691 aZFar = aZNear + Abs (aZFar) * aPrecision;
1694 myCamera->SetZRange (aZNear, aZFar);
1699 //=============================================================================
1700 //function : DepthFitAll
1702 //=============================================================================
1703 void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1704 const Quantity_Coefficient Margin)
1706 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1707 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1708 Standard_Real Dx,Dy,Dz,Size;
1710 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1712 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1717 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
1719 Standard_Real LIM = ShortRealLast() -1.;
1720 if (Abs(Xmin) > LIM || Abs(Ymin) > LIM || Abs(Zmin) > LIM
1721 || Abs(Xmax) > LIM || Abs(Ymax) > LIM || Abs(Zmax) > LIM ) {
1726 if (Xmin == Xmax && Ymin == Ymax && Zmin == Zmax) {
1730 MyView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
1731 MyView->Projects(Xmax,Ymax,Zmax,U1,V1,W1) ;
1732 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1733 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1734 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1735 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
1736 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1737 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1738 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1739 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
1740 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1741 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1742 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1743 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
1744 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1745 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1746 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1747 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
1748 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1749 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1750 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1751 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
1752 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1753 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1754 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1755 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
1756 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1757 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1758 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1761 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1762 Dz = 2.*Wmax + Margin * Wmax;
1764 // Compute depth value
1765 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1766 Dx += Margin * Dx; Dy += Margin * Dy;
1767 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1770 SetDepth( Aspect * Size / 2.);
1776 //=============================================================================
1779 //=============================================================================
1780 void V3d_View::FitAll(const Standard_Real theMinXv,
1781 const Standard_Real theMinYv,
1782 const Standard_Real theMaxXv,
1783 const Standard_Real theMaxYv)
1785 FitAll (MyWindow, theMinXv, theMinYv, theMaxXv, theMaxYv);
1788 //=============================================================================
1789 //function : WindowFitAll
1791 //=============================================================================
1792 void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1793 const Standard_Integer Ymin,
1794 const Standard_Integer Xmax,
1795 const Standard_Integer Ymax)
1797 WindowFit(Xmin,Ymin,Xmax,Ymax);
1800 //=======================================================================
1801 //function : WindowFit
1803 //=======================================================================
1804 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1805 const Standard_Integer theMinYp,
1806 const Standard_Integer theMaxXp,
1807 const Standard_Integer theMaxYp)
1809 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1811 if (!myCamera->IsOrthographic())
1813 // normalize view coordiantes
1814 Standard_Integer aWinWidth, aWinHeight;
1815 MyWindow->Size (aWinWidth, aWinHeight);
1817 // z coordinate of camera center
1818 Standard_Real aDepth = myCamera->Project (myCamera->Center()).Z();
1820 // camera projection coordinate are in NDC which are normalized [-1, 1]
1821 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1822 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1823 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1824 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1826 // compute camera panning
1827 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1828 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1829 gp_Pnt aPanTo = myCamera->ConvertProj2View (aFitCenter);
1830 gp_Pnt aPanFrom = myCamera->ConvertProj2View (aScreenCenter);
1831 gp_Vec aPanVec (aPanFrom, aPanTo);
1833 // compute section size
1834 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1835 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1836 gp_Pnt aViewBotLeft = myCamera->ConvertProj2View (aFitBotLeft);
1837 gp_Pnt aViewTopRight = myCamera->ConvertProj2View (aFitTopRight);
1839 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1840 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1842 Translate (myCamera, aPanVec.X(), -aPanVec.Y());
1843 Scale (myCamera, aUSize, aVSize);
1848 Standard_Real aX1, aY1, aX2, aY2;
1849 Convert (theMinXp, theMinYp, aX1, aY1);
1850 Convert (theMaxXp, theMaxYp, aX2, aY2);
1851 FitAll (aX1, aY1, aX2, aY2);
1854 SetImmediateUpdate (wasUpdateEnabled);
1859 //=======================================================================
1860 //function : SetViewMappingDefault
1862 //=======================================================================
1863 void V3d_View::SetViewMappingDefault()
1865 MyView->SetViewMappingDefault();
1870 //=======================================================================
1871 //function : ResetViewMapping
1873 //=======================================================================
1874 void V3d_View::ResetViewMapping()
1876 MyView->ViewMappingReset();
1881 //=======================================================================
1882 //function : ConvertToGrid
1884 //=======================================================================
1885 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1886 const Standard_Integer Yp,
1889 Standard_Real& Zg) const
1891 Graphic3d_Vertex aVrp;
1892 Standard_Real anX, anY, aZ;
1893 Convert (Xp, Yp, anX, anY, aZ);
1894 aVrp.SetCoord (anX, anY, aZ);
1896 if( MyViewer->Grid()->IsActive() ) {
1897 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1898 aNewVrp.Coord (Xg,Yg,Zg) ;
1900 aVrp.Coord (Xg,Yg,Zg) ;
1903 //=======================================================================
1904 //function : ConvertToGrid
1906 //=======================================================================
1907 void V3d_View::ConvertToGrid(const Standard_Real X,
1908 const Standard_Real Y,
1909 const Standard_Real Z,
1912 Standard_Real& Zg) const
1914 if( MyViewer->Grid()->IsActive() ) {
1915 Graphic3d_Vertex aVrp (X,Y,Z) ;
1916 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1917 aNewVrp.Coord(Xg,Yg,Zg) ;
1919 Xg = X; Yg = Y; Zg = Z;
1923 //=======================================================================
1924 //function : Convert
1926 //=======================================================================
1927 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1929 Standard_Integer aDxw, aDyw ;
1931 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1933 MyWindow->Size (aDxw, aDyw);
1934 Standard_Real aValue;
1936 gp_Pnt aViewDims = myCamera->ViewDimensions();
1937 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1942 //=======================================================================
1943 //function : Convert
1945 //=======================================================================
1946 void V3d_View::Convert(const Standard_Integer Xp,
1947 const Standard_Integer Yp,
1949 Standard_Real& Yv) const
1951 Standard_Integer aDxw, aDyw;
1953 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1955 MyWindow->Size (aDxw, aDyw);
1957 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1958 aPoint = myCamera->ConvertProj2View (aPoint);
1964 //=======================================================================
1965 //function : Convert
1967 //=======================================================================
1968 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1970 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1972 Standard_Integer aDxw, aDyw;
1973 MyWindow->Size (aDxw, aDyw);
1975 gp_Pnt aViewDims = myCamera->ViewDimensions();
1976 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1981 //=======================================================================
1982 //function : Convert
1984 //=======================================================================
1985 void V3d_View::Convert(const Standard_Real Xv,
1986 const Standard_Real Yv,
1987 Standard_Integer& Xp,
1988 Standard_Integer& Yp) const
1990 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1992 Standard_Integer aDxw, aDyw;
1993 MyWindow->Size (aDxw, aDyw);
1995 gp_Pnt aPoint (Xv, Yv, 0.0);
1996 aPoint = myCamera->ConvertView2Proj (aPoint);
1997 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1999 Xp = RealToInt (aPoint.X());
2000 Yp = RealToInt (aPoint.Y());
2003 //=======================================================================
2004 //function : Convert
2006 //=======================================================================
2007 void V3d_View::Convert(const Standard_Integer Xp,
2008 const Standard_Integer Yp,
2011 Standard_Real& Z) const
2013 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
2014 Standard_Integer aHeight, aWidth;
2015 MyWindow->Size (aWidth, aHeight);
2017 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
2018 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
2019 Standard_Real aZ = 2.0 * 0.0 - 1.0;
2021 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
2027 Graphic3d_Vertex aVrp;
2028 aVrp.SetCoord (X, Y, Z);
2030 if( MyViewer->Grid()->IsActive() ) {
2031 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
2032 aNewVrp.Coord (X, Y, Z) ;
2036 //=======================================================================
2037 //function : ConvertWithProj
2039 //=======================================================================
2040 void V3d_View::ConvertWithProj(const Standard_Integer Xp,
2041 const Standard_Integer Yp,
2047 Standard_Real& Dz) const
2049 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
2050 Standard_Integer aHeight, aWidth;
2051 MyWindow->Size (aWidth, aHeight);
2053 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
2054 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
2055 Standard_Real aZ = 2.0 * 0.0 - 1.0;
2057 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
2063 Graphic3d_Vertex aVrp;
2064 aVrp.SetCoord (X, Y, Z);
2066 aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
2068 Dx = X - aResult.X();
2069 Dy = Y - aResult.Y();
2070 Dz = Z - aResult.Z();
2072 if( MyViewer->Grid()->IsActive() ) {
2073 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
2074 aNewVrp.Coord (X, Y, Z) ;
2078 //=======================================================================
2079 //function : Convert
2081 //=======================================================================
2082 void V3d_View::Convert(const Standard_Real X,
2083 const Standard_Real Y,
2084 const Standard_Real Z,
2085 Standard_Integer& Xp,
2086 Standard_Integer& Yp) const
2088 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
2089 Standard_Integer aHeight, aWidth;
2090 MyWindow->Size (aWidth, aHeight);
2092 gp_Pnt aPoint = myCamera->Project (gp_Pnt (X, Y, Z));
2094 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
2095 Yp = RealToInt ((aPoint.Y() + 1) * 0.5 * aHeight);
2098 //=======================================================================
2099 //function : Project
2101 //=======================================================================
2102 void V3d_View::Project(const Standard_Real X,
2103 const Standard_Real Y,
2104 const Standard_Real Z,
2106 Standard_Real &Yp) const
2109 MyView->Projects (X, Y, Z, Xp, Yp, Zp);
2112 //=======================================================================
2113 //function : BackgroundColor
2115 //=======================================================================
2116 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
2119 Standard_Real& V3) const
2121 Quantity_Color C = BackgroundColor() ;
2122 C.Values(V1,V2,V3,Type) ;
2125 //=======================================================================
2126 //function : BackgroundColor
2128 //=======================================================================
2129 Quantity_Color V3d_View::BackgroundColor() const
2131 return MyBackground.Color() ;
2134 //=======================================================================
2135 //function : GradientBackgroundColors
2137 //=======================================================================
2138 void V3d_View::GradientBackgroundColors(Quantity_Color& Color1,Quantity_Color& Color2) const
2140 MyGradientBackground.Colors(Color1, Color2);
2143 //=======================================================================
2144 //function : GradientBackground
2146 //=======================================================================
2147 Aspect_GradientBackground V3d_View::GradientBackground() const
2149 return MyGradientBackground;
2152 //=======================================================================
2155 //=======================================================================
2156 Standard_Real V3d_View::Scale() const
2158 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
2160 Standard_Real aCameraScale;
2162 // Strange behavior for the sake of compatibility.
2163 if (!aDefaultCamera.IsNull())
2165 Standard_Real aDefaultScale = aDefaultCamera->Scale();
2166 aCameraScale = aDefaultScale / myCamera->Scale();
2170 aCameraScale = myCamera->Scale();
2173 return aCameraScale;
2176 //=======================================================================
2177 //function : AxialScale
2179 //=======================================================================
2180 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
2182 gp_Pnt anAxialScale = myCamera->AxialScale();
2183 Sx = anAxialScale.X();
2184 Sy = anAxialScale.Y();
2185 Sz = anAxialScale.Z();
2188 //=======================================================================
2191 //=======================================================================
2192 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
2194 gp_Pnt aViewDims = myCamera->ViewDimensions();
2196 Width = aViewDims.X();
2197 Height = aViewDims.Y();
2200 //=======================================================================
2203 //=======================================================================
2204 Standard_Real V3d_View::ZSize() const
2206 gp_Pnt aViewDims = myCamera->ViewDimensions();
2208 return aViewDims.Z();
2211 //=======================================================================
2214 //=======================================================================
2215 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
2216 Standard_Real& Vmin,
2217 Standard_Real& Umax,
2218 Standard_Real& Vmax) const
2220 Standard_Real Wmin,Wmax,U,V,W ;
2221 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
2223 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2226 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
2227 MyView->Projects(Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
2228 MyView->Projects(Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
2229 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
2230 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2231 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2232 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2233 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
2234 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2235 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2236 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2237 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
2238 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2239 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2240 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2241 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
2242 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2243 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2244 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2245 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
2246 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2247 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2248 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2249 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
2250 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2251 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2252 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2257 //=======================================================================
2260 //=======================================================================
2261 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
2262 Standard_Real& Ymin,
2263 Standard_Real& Zmin,
2264 Standard_Real& Xmax,
2265 Standard_Real& Ymax,
2266 Standard_Real& Zmax) const
2269 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
2270 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2273 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
2278 //=======================================================================
2279 //function : Gravity
2281 //=======================================================================
2282 Standard_Integer V3d_View::Gravity(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2284 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax;
2285 Standard_Integer Nstruct,Npoint ;
2286 Graphic3d_MapOfStructure MySetOfStructures;
2288 MyView->DisplayedStructures (MySetOfStructures);
2289 Nstruct = MySetOfStructures.Extent() ;
2291 Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ;
2293 Npoint = 0 ; X = Y = Z = 0. ;
2294 for (; MyIterator.More(); MyIterator.Next())
2296 const Handle(Graphic3d_Structure)& aStruct = MyIterator.Key();
2297 if (!aStruct->IsEmpty())
2299 aStruct->MinMaxValues (Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
2301 // Check bounding box for validness
2302 Standard_Real aLim = (ShortRealLast() - 1.0);
2303 if (Abs (Xmin) > aLim || Abs (Ymin) > aLim || Abs (Zmin) > aLim ||
2304 Abs (Xmax) > aLim || Abs (Ymax) > aLim || Abs (Zmax) > aLim)
2309 // use camera projection to find gravity point
2311 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2312 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2313 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2314 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax) };
2316 for (Standard_Integer aPntIt = 0; aPntIt < 8; ++aPntIt)
2318 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2320 gp_Pnt aProjected = myCamera->Project (aBndPnt);
2321 const Standard_Real& U = aProjected.X();
2322 const Standard_Real& V = aProjected.Y();
2323 if (Abs(U) <= 1.0 && Abs(V) <= 1.0)
2334 X /= Npoint ; Y /= Npoint ; Z /= Npoint ;
2340 //=======================================================================
2343 //=======================================================================
2344 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2346 gp_Pnt aCameraEye = myCamera->Eye();
2352 //=============================================================================
2353 //function : FocalReferencePoint
2355 //=============================================================================
2356 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2361 //=============================================================================
2362 //function : ProjReferenceAxe
2364 //=============================================================================
2365 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2366 const Standard_Integer Ypix,
2372 Standard_Real& VZ) const
2374 Standard_Real Xo,Yo,Zo;
2376 Convert (Xpix, Ypix, XP, YP, ZP);
2377 if ( Type() == V3d_PERSPECTIVE )
2379 FocalReferencePoint (Xo,Yo,Zo);
2390 //=============================================================================
2393 //=============================================================================
2394 Standard_Real V3d_View::Depth() const
2396 return myCamera->Distance();
2399 //=============================================================================
2402 //=============================================================================
2403 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2405 gp_Dir aCameraDir = myCamera->Direction().Reversed();
2406 Dx = aCameraDir.X();
2407 Dy = aCameraDir.Y();
2408 Dz = aCameraDir.Z();
2411 //=============================================================================
2414 //=============================================================================
2415 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2417 gp_Pnt aCameraCenter = myCamera->Center();
2418 X = aCameraCenter.X();
2419 Y = aCameraCenter.Y();
2420 Z = aCameraCenter.Z();
2423 //=============================================================================
2426 //=============================================================================
2427 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2429 gp_Dir aCameraUp = myCamera->Up();
2435 //=============================================================================
2438 //=============================================================================
2439 Standard_Real V3d_View::Twist() const
2441 Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2442 Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
2443 Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
2444 Standard_Boolean TheStatus ;
2446 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
2450 anUp = gp_Dir (0.,0.,1.) ;
2451 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2453 anUp = gp_Dir (0.,1.,0.) ;
2454 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2457 anUp = gp_Dir (1.,0.,0.) ;
2458 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2460 Yaxis.Coord(X0,Y0,Z0) ;
2463 /* Compute Cross Vector From Up & Origin */
2464 pvx = Y0*Zup - Z0*Yup ;
2465 pvy = Z0*Xup - X0*Zup ;
2466 pvz = X0*Yup - Y0*Xup ;
2467 pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2468 sca = X0*Xup + Y0*Yup + Z0*Zup ;
2471 if( angle > 1. ) angle = 1. ;
2472 else if( angle < -1. ) angle = -1. ;
2473 angle = asin(angle) ;
2474 if( sca < 0. ) angle = M_PI - angle ;
2475 if( angle > 0. && angle < M_PI ) {
2476 sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2477 if( sca < 0. ) angle = DEUXPI - angle ;
2482 //=============================================================================
2483 //function : ShadingModel
2485 //=============================================================================
2486 V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2488 V3d_TypeOfShadingModel SM = (V3d_TypeOfShadingModel)MyViewContext.Model() ;
2492 //=============================================================================
2493 //function : SurfaceDetail
2495 //=============================================================================
2496 V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
2498 V3d_TypeOfSurfaceDetail SM = (V3d_TypeOfSurfaceDetail)MyViewContext.SurfaceDetail() ;
2502 //=============================================================================
2503 //function : TextureEnv
2505 //=============================================================================
2506 Handle_Graphic3d_TextureEnv V3d_View::TextureEnv() const
2508 Handle(Graphic3d_TextureEnv) SM = MyViewContext.TextureEnv() ;
2512 //=============================================================================
2513 //function : Visualization
2515 //=============================================================================
2516 V3d_TypeOfVisualization V3d_View::Visualization() const
2518 V3d_TypeOfVisualization V =
2519 (V3d_TypeOfVisualization)MyViewContext.Visualization() ;
2523 //=============================================================================
2524 //function : Antialiasing
2526 //=============================================================================
2527 Standard_Boolean V3d_View::Antialiasing() const
2529 Standard_Boolean A = MyViewContext.AliasingIsOn() ;
2533 //=============================================================================
2536 //=============================================================================
2537 Handle(V3d_Viewer) V3d_View::Viewer() const
2542 //=============================================================================
2543 //function : IfWindow
2545 //=============================================================================
2546 Standard_Boolean V3d_View::IfWindow() const
2548 Standard_Boolean TheStatus = MyView->IsDefined() ;
2552 //=============================================================================
2555 //=============================================================================
2556 Handle(Aspect_Window) V3d_View::Window() const
2561 //=============================================================================
2564 //=============================================================================
2565 V3d_TypeOfView V3d_View::Type() const
2567 return myCamera->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2570 //=============================================================================
2571 //function : SetFocale
2573 //=============================================================================
2574 void V3d_View::SetFocale( const Standard_Real focale )
2576 if (myCamera->IsOrthographic())
2581 Standard_Real aFOVyRad = ATan (focale / (myCamera->Distance() * 2.0));
2583 myCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2588 //=============================================================================
2591 //=============================================================================
2592 Standard_Real V3d_View::Focale() const
2594 if (myCamera->IsOrthographic())
2599 return myCamera->Distance() * 2.0 * Tan(myCamera->FOVy() * M_PI / 360.0);
2602 //=============================================================================
2605 //=============================================================================
2606 Handle(Visual3d_View) V3d_View::View() const
2611 //=============================================================================
2612 //function : ScreenAxis
2614 //=============================================================================
2615 Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2617 Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2618 Standard_Real dx1, dy1, dz1, xx, yy, zz;
2620 Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2621 Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2622 xx = Yup*Zpn - Zup*Ypn;
2623 yy = Zup*Xpn - Xup*Zpn;
2624 zz = Xup*Ypn - Yup*Xpn;
2625 Xaxe.SetCoord (xx, yy, zz);
2626 if (Xaxe.LengthZero()) return Standard_False;
2628 Xaxe.Coord(dx1, dy1, dz1);
2629 xx = Ypn*dz1 - Zpn*dy1;
2630 yy = Zpn*dx1 - Xpn*dz1;
2631 zz = Xpn*dy1 - Ypn*dx1;
2632 Yaxe.SetCoord (xx, yy, zz) ;
2633 if (Yaxe.LengthZero()) return Standard_False;
2636 Zaxe.SetCoord (Xpn, Ypn, Zpn);
2638 return Standard_True;
2641 //=============================================================================
2642 //function : TrsPoint
2644 //=============================================================================
2645 Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2647 Graphic3d_Vertex PP ;
2648 Standard_Real X,Y,Z,XX,YY,ZZ ;
2651 Standard_Integer lr, ur, lc, uc;
2652 lr = Matrix.LowerRow ();
2653 ur = Matrix.UpperRow ();
2654 lc = Matrix.LowerCol ();
2655 uc = Matrix.UpperCol ();
2656 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
2658 PP.SetCoord(X,Y,Z) ;
2662 XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2663 Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2665 YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2666 Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2668 ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2669 Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2670 PP.SetCoord(XX,YY,ZZ) ;
2674 //=======================================================================
2677 //=======================================================================
2678 void V3d_View::Pan (const Standard_Integer theDXp,
2679 const Standard_Integer theDYp,
2680 const Quantity_Factor theZoomFactor,
2681 const Standard_Boolean theToStart)
2683 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2686 //=======================================================================
2687 //function : Panning
2689 //=======================================================================
2690 void V3d_View::Panning (const Standard_Real theDXv,
2691 const Standard_Real theDYv,
2692 const Quantity_Factor theZoomFactor,
2693 const Standard_Boolean theToStart)
2695 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2699 myCamStartOpEye = myCamera->Eye();
2700 myCamStartOpCenter = myCamera->Center();
2703 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2705 gp_Pnt aViewDims = myCamera->ViewDimensions();
2707 myCamera->SetEye (myCamStartOpEye);
2708 myCamera->SetCenter (myCamStartOpCenter);
2709 Translate (myCamera, -theDXv, -theDYv);
2710 Scale (myCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2712 SetImmediateUpdate (wasUpdateEnabled);
2717 //=======================================================================
2720 //=======================================================================
2721 void V3d_View::Zoom (const Standard_Integer theXp1,
2722 const Standard_Integer theYp1,
2723 const Standard_Integer theXp2,
2724 const Standard_Integer theYp2)
2726 Standard_Integer aDx = theXp2 - theXp1;
2727 Standard_Integer aDy = theYp2 - theYp1;
2728 if (aDx != 0 || aDy != 0)
2730 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2731 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2732 SetZoom (aCoeff, Standard_True);
2736 //=======================================================================
2737 //function : StartZoomAtPoint
2739 //=======================================================================
2740 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2741 const Standard_Integer theYp)
2743 MyZoomAtPointX = theXp;
2744 MyZoomAtPointY = theYp;
2747 //=======================================================================
2748 //function : ZoomAtPoint
2750 //=======================================================================
2751 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2752 const Standard_Integer theMouseStartY,
2753 const Standard_Integer theMouseEndX,
2754 const Standard_Integer theMouseEndY)
2756 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2759 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2760 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2761 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2763 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2765 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
2766 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
2768 // ensure that zoom will not be too small or too big.
2769 Standard_Real aCoef = aDZoom;
2770 if (aViewWidth < aCoef * Precision::Confusion())
2772 aCoef = aViewWidth / Precision::Confusion();
2774 else if (aViewWidth > aCoef * 1e12)
2776 aCoef = aViewWidth / 1e12;
2778 if (aViewHeight < aCoef * Precision::Confusion())
2780 aCoef = aViewHeight / Precision::Confusion();
2782 else if (aViewHeight > aCoef * 1e12)
2784 aCoef = aViewHeight / 1e12;
2787 Standard_Real aZoomAtPointXv = 0.0;
2788 Standard_Real aZoomAtPointYv = 0.0;
2789 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2791 V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
2792 V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
2794 myCamera->SetScale (myCamera->Scale() / aCoef);
2795 Translate (myCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2799 SetImmediateUpdate (wasUpdateEnabled);
2804 //=============================================================================
2805 //function : AxialScale
2807 //=============================================================================
2808 void V3d_View::AxialScale (const Standard_Integer Dx,
2809 const Standard_Integer Dy,
2810 const V3d_TypeOfAxe Axis)
2812 if( Dx != 0. || Dy != 0. ) {
2813 Standard_Real Sx, Sy, Sz;
2814 AxialScale( Sx, Sy, Sz );
2815 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2816 dscale = (Dx > 0) ? dscale : 1./dscale;
2817 if( Axis == V3d_X ) Sx = dscale;
2818 if( Axis == V3d_Y ) Sy = dscale;
2819 if( Axis == V3d_Z ) Sz = dscale;
2820 SetAxialScale( Sx, Sy, Sz );
2824 //=============================================================================
2827 //=============================================================================
2828 void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
2829 const Standard_Real Xmin,
2830 const Standard_Real Ymin,
2831 const Standard_Real Xmax,
2832 const Standard_Real Ymax)
2834 Standard_Integer aWinWidth, aWinHeight;
2835 aWindow->Size (aWinWidth, aWinHeight);
2837 Standard_Real aWinAspect = (Standard_Real)aWinWidth / aWinHeight;
2838 Standard_Real aFitSizeU = Abs (Xmax - Xmin);
2839 Standard_Real aFitSizeV = Abs (Ymax - Ymin);
2840 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2841 if (aFitAspect >= aWinAspect)
2843 aFitSizeV = aFitSizeU / aWinAspect;
2847 aFitSizeU = aFitSizeV * aWinAspect;
2850 myCamera->SetAspect (aWinAspect);
2851 Translate (myCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
2852 Scale (myCamera, aFitSizeU, aFitSizeV);
2858 //=============================================================================
2859 //function : StartRotation
2861 //=============================================================================
2863 static Standard_Boolean zRotation = Standard_False;
2865 void V3d_View::StartRotation(const Standard_Integer X,
2866 const Standard_Integer Y,
2867 const Quantity_Ratio zRotationThreshold)
2872 rx = Standard_Real(Convert(x));
2873 ry = Standard_Real(Convert(y));
2875 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2877 zRotation = Standard_False;
2878 if( zRotationThreshold > 0. ) {
2879 Standard_Real dx = Abs(sx - rx/2.);
2880 Standard_Real dy = Abs(sy - ry/2.);
2881 // if( dx > rx/3. || dy > ry/3. ) zRotation = Standard_True;
2882 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2883 if( dx > dd || dy > dd ) zRotation = Standard_True;
2889 //=============================================================================
2890 //function : Rotation
2892 //=============================================================================
2893 void V3d_View::Rotation(const Standard_Integer X,
2894 const Standard_Integer Y)
2897 if( rx == 0. || ry == 0. ) {
2903 Standard_Real dx=0.,dy=0.,dz=0.;
2905 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2906 atan2(sx-rx/2.,ry/2.-sy);
2908 dx = (Standard_Real(X) - sx) * M_PI / rx;
2909 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2911 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2913 Standard_Real dx = (Standard_Real(X - sx)) * M_PI;
2914 Standard_Real dy = (Standard_Real(sy - Y)) * M_PI;
2915 Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2918 if( !myImmediateUpdate ) Update();
2920 myImmediateUpdate = Standard_False;
2921 Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2922 ZFitAll (Zmargin); //Don't do that, perf improvment
2923 myImmediateUpdate = Standard_True;
2928 //=============================================================================
2929 //function : SetComputedMode
2931 //=============================================================================
2932 void V3d_View::SetComputedMode (const Standard_Boolean aMode)
2938 MyView->SetComputedMode (Standard_True);
2944 MyView->SetComputedMode (Standard_False);
2949 //=============================================================================
2950 //function : ComputedMode
2952 //=============================================================================
2953 Standard_Boolean V3d_View::ComputedMode() const
2955 return MyView->ComputedMode();
2958 //=============================================================================
2959 //function : SetBackFacingModel
2961 //=============================================================================
2962 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel aModel)
2964 MyView->SetBackFacingModel (Visual3d_TypeOfBackfacingModel(aModel));
2968 //=============================================================================
2969 //function : BackFacingModel
2971 //=============================================================================
2972 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2974 return V3d_TypeOfBackfacingModel(MyView -> BackFacingModel ());
2977 //=============================================================================
2978 //function : TransientManagerBeginDraw
2980 //=============================================================================
2981 Standard_Boolean V3d_View::TransientManagerBeginDraw(const Standard_Boolean DoubleBuffer,const Standard_Boolean RetainMode) const
2983 return Visual3d_TransientManager::BeginDraw(MyView,DoubleBuffer,RetainMode);
2986 //=============================================================================
2987 //function : TransientManagerClearDraw
2989 //=============================================================================
2990 void V3d_View::TransientManagerClearDraw() const
2992 Visual3d_TransientManager::ClearDraw(MyView);
2995 //=============================================================================
2996 //function : TransientManagerBeginAddDraw
2998 //=============================================================================
2999 Standard_Boolean V3d_View::TransientManagerBeginAddDraw() const
3001 return Visual3d_TransientManager::BeginAddDraw(MyView);
3004 //=============================================================================
3007 //=============================================================================
3008 void V3d_View::Init()
3010 myComputedMode = MyViewer->ComputedMode();
3011 if( !myComputedMode || !MyViewer->DefaultComputedMode() ) {
3012 SetComputedMode(Standard_False);
3016 //=============================================================================
3017 //function : SetPlotter
3019 //=============================================================================
3020 void V3d_View::SetPlotter(const Handle(Graphic3d_Plotter)& aPlotter)
3022 MyPlotter = aPlotter;
3025 //=============================================================================
3028 //=============================================================================
3029 void V3d_View::Plot()
3031 V3d_BadValue_Raise_if( !MyPlotter.IsNull(), "view has no plotter");
3032 MyView->Plot(MyPlotter);
3035 //=============================================================================
3038 //=============================================================================
3039 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
3040 const Graphic3d_BufferType& theBufferType)
3042 Standard_Integer aWinWidth, aWinHeight;
3043 MyWindow->Size (aWinWidth, aWinHeight);
3044 Image_AlienPixMap anImage;
3046 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
3049 //=============================================================================
3050 //function : ToPixMap
3052 //=============================================================================
3053 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
3054 const Standard_Integer theWidth,
3055 const Standard_Integer theHeight,
3056 const Graphic3d_BufferType& theBufferType,
3057 const Standard_Boolean theToKeepAspect,
3058 const V3d_StereoDumpOptions theStereoOptions)
3060 Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
3062 // always prefer hardware accelerated offscreen buffer
3063 Graphic3d_PtrFrameBuffer aFBOPtr = NULL;
3064 Graphic3d_PtrFrameBuffer aPrevFBOPtr = (Graphic3d_PtrFrameBuffer )cView->ptrFBO;
3065 Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
3066 Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
3067 if (aPrevFBOPtr != NULL)
3069 MyView->FBOGetDimensions (aPrevFBOPtr,
3070 aPrevFBOVPSizeX, aPrevFBOVPSizeY,
3071 aPrevFBOSizeXMax, aPrevFBOSizeYMax);
3072 if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
3074 MyView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
3075 aFBOPtr = aPrevFBOPtr;
3079 if (aFBOPtr == NULL)
3081 // Try to create hardware accelerated buffer
3082 aFBOPtr = MyView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
3083 if (aFBOPtr != NULL)
3085 MyView->FBOGetDimensions (aFBOPtr,
3086 aFBOVPSizeX, aFBOVPSizeY,
3087 aFBOSizeXMax, aFBOSizeYMax);
3088 // reduce viewport in case of hardware limits
3089 if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
3090 if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
3091 MyView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
3094 cView->ptrFBO = aFBOPtr;
3096 // If hardware accelerated buffer - try to use onscreen buffer
3097 // Results may be bad!
3098 if (aFBOPtr == NULL)
3100 // retrieve window sizes
3101 Standard_Integer aWinWidth, aWinHeight;
3102 MyWindow->Size (aWinWidth, aWinHeight);
3104 // technically we can reduce existing viewport...
3105 // but currently allow only dumping the window itself
3106 if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
3108 return Standard_False;
3112 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
3114 aStoreMapping->Copy (myCamera);
3116 if (myCamera->IsStereo())
3118 switch (theStereoOptions)
3121 myCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
3124 case V3d_SDO_LEFT_EYE :
3125 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
3128 case V3d_SDO_RIGHT_EYE :
3129 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
3136 if (theToKeepAspect)
3138 myCamera->SetAspect ((Standard_Real) aFBOVPSizeX / aFBOSizeYMax);
3141 //workaround for rendering list of Over and Under Layers
3142 if (!MyLayerMgr.IsNull())
3144 MyLayerMgr->Compute();
3147 // render immediate structures into back buffer rather than front
3148 Handle(Graphic3d_GraphicDriver) aDriver = Handle(Graphic3d_GraphicDriver)::DownCast (MyView->GraphicDriver());
3149 const Standard_Boolean aPrevImmediateMode = aDriver.IsNull() ? Standard_True : aDriver->SetImmediateModeDrawToFront (*cView, Standard_False);
3152 if (!aDriver.IsNull())
3154 aDriver->SetImmediateModeDrawToFront (*cView, aPrevImmediateMode);
3157 myCamera->Copy (aStoreMapping);
3159 Standard_Boolean isSuccess = Standard_True;
3161 // allocate image buffer for dumping
3162 if (theImage.IsEmpty()
3163 || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
3164 || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
3166 bool isBigEndian = Image_PixMap::IsBigEndianHost();
3167 Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
3168 switch (theBufferType)
3170 case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
3171 case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
3172 case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
3175 isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
3177 isSuccess = isSuccess && MyView->BufferDump (theImage, theBufferType);
3179 // FBO now useless, free resources
3180 if (aFBOPtr != aPrevFBOPtr)
3182 MyView->FBORelease (aFBOPtr);
3184 else if (aPrevFBOPtr != NULL)
3186 MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
3188 cView->ptrFBO = aPrevFBOPtr;
3192 void V3d_View::ImmediateUpdate() const
3194 if (myImmediateUpdate) Update();
3197 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
3199 Standard_Boolean aPreviousMode = myImmediateUpdate;
3200 myImmediateUpdate = theImmediateUpdate;
3201 return aPreviousMode;
3204 // =======================================================================
3205 // function : SetCamera
3207 // =======================================================================
3208 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
3210 Standard_ASSERT_RAISE (!theCamera.IsNull(), "Void camera is not allowed");
3212 myCamera = theCamera;
3214 MyView->SetCamera (theCamera);
3217 // =======================================================================
3218 // function : GetCamera
3220 // =======================================================================
3221 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
3226 // =======================================================================
3227 // function : FitMinMax
3228 // purpose : Internal
3229 // =======================================================================
3230 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
3231 const gp_XYZ& theMinCorner,
3232 const gp_XYZ& theMaxCorner,
3233 const Standard_Real theMargin,
3234 const Standard_Real theResolution,
3235 const Standard_Boolean theToEnlargeIfLine) const
3237 // Check bounding box for validness
3238 Standard_Real aLim = (ShortRealLast() - 1.0);
3239 if (Abs (theMinCorner.X()) > aLim || Abs (theMinCorner.Y()) > aLim || Abs (theMinCorner.Z()) > aLim ||
3240 Abs (theMaxCorner.X()) > aLim || Abs (theMaxCorner.Y()) > aLim || Abs (theMaxCorner.Z()) > aLim)
3242 return Standard_False; // bounding box is out of bounds...
3245 // Apply "axial scaling" to the bounding points.
3246 // It is not the best approach to make this scaling as a part of fit all operation,
3247 // but the axial scale is integrated into camera orientation matrix and the other
3248 // option is to perform frustum plane adjustment algorithm in view camera space,
3249 // which will lead to a number of additional world-view space conversions and
3250 // loosing precision as well.
3251 Standard_Real aXmin = theMinCorner.X() * theCamera->AxialScale().X();
3252 Standard_Real aXmax = theMaxCorner.X() * theCamera->AxialScale().X();
3253 Standard_Real aYmin = theMinCorner.Y() * theCamera->AxialScale().Y();
3254 Standard_Real aYmax = theMaxCorner.Y() * theCamera->AxialScale().Y();
3255 Standard_Real aZmin = theMinCorner.Z() * theCamera->AxialScale().Z();
3256 Standard_Real aZmax = theMaxCorner.Z() * theCamera->AxialScale().Z();
3259 aBBox.Update (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3260 if (aBBox.IsThin (RealEpsilon()))
3262 return Standard_False; // nothing to fit all
3265 gp_Pnt aBBCenter ((aXmin + aXmax) * 0.5, (aYmin + aYmax) * 0.5, (aZmin + aZmax) * 0.5);
3267 gp_Pln aFrustumLeft;
3268 gp_Pln aFrustumRight;
3269 gp_Pln aFrustumBottom;
3271 gp_Pln aFrustumNear;
3273 theCamera->Frustum (aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar);
3275 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3276 gp_Dir aCamDir = theCamera->Direction();
3277 gp_Dir aCamSide = aCamDir ^ aCamUp;
3279 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3280 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3281 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3282 // set up perspective-correct camera projection matching the bounding box.
3283 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3284 // The zooming can be done by calculating view plane size matching the bounding box at center of
3285 // the bounding box. The only limitation here is that the scale of camera should define size of
3286 // its view plane passing through the camera center, and the center of camera should be on the
3287 // same line with the center of bounding box.
3289 // The following method is applied:
3290 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3291 // 2) Determine new location of frustum planes, "matching" the bounding box.
3292 // 3) Determine new camera projection vector using the normalized asymmetry.
3293 // 4) Determine new zooming in view space.
3295 // Determine normalized projection asymmetry (if any).
3297 Standard_Real anAssymX = Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction()))
3298 - Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction()));
3299 Standard_Real anAssymY = Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction()))
3300 - Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction()));
3302 // Determine how far should be the frustum planes placed from center
3303 // of bounding box, in order to match the bounding box closely.
3304 gp_Pln aMatchSide[6] = {aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar};
3305 Standard_Real aMatchDistance[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
3306 for (Standard_Integer anIt = 0; anIt < 6; ++anIt)
3308 const gp_Dir& aPlaneN = aMatchSide[anIt].Axis().Direction();
3311 aPlaneTrsf.SetTransformation (gp_Ax3(), gp_Ax3 (aBBCenter, aPlaneN));
3312 Bnd_Box aRelativeBBox = aBBox.Transformed (aPlaneTrsf);
3314 Standard_Real aDummy = 0.0;
3315 Standard_Real aZmin = 0.0;
3316 Standard_Real aZmax = 0.0;
3317 aRelativeBBox.Get (aDummy, aDummy, aZmin, aDummy, aDummy, aZmax);
3318 aMatchDistance[anIt] = -aZmin;
3320 // The center of camera is placed on the same line with center of bounding box.
3321 // The view plane section crosses the bounding box at its center.
3322 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3323 // into view section size between the point and the frustum plane.
3325 // /|\ right half of frame //
3327 // point o<-- distance * coeff -->//---- (view plane section)
3337 aMatchDistance[0] *= Sqrt(1 + Pow (Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction())), 2.0));
3338 aMatchDistance[1] *= Sqrt(1 + Pow (Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction())), 2.0));
3339 aMatchDistance[2] *= Sqrt(1 + Pow (Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction())), 2.0));
3340 aMatchDistance[3] *= Sqrt(1 + Pow (Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction())), 2.0));
3341 aMatchDistance[4] *= Sqrt(1 + Pow (Tan ( aCamDir.Angle (aFrustumNear.Axis().Direction())), 2.0));
3342 aMatchDistance[5] *= Sqrt(1 + Pow (Tan (-aCamDir.Angle (aFrustumFar.Axis().Direction())), 2.0));
3344 Standard_Real aViewSizeXv = aMatchDistance[0] + aMatchDistance[1];
3345 Standard_Real aViewSizeYv = aMatchDistance[2] + aMatchDistance[3];
3346 Standard_Real aViewSizeZv = aMatchDistance[4] + aMatchDistance[5];
3348 // Place center of camera on the same line with center of bounding
3349 // box applying corresponding projection asymmetry (if any).
3350 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3351 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3352 Standard_Real anOffsetXv = (aMatchDistance[1] - aMatchDistance[0]) * 0.5 + anAssymXv;
3353 Standard_Real anOffsetYv = (aMatchDistance[3] - aMatchDistance[2]) * 0.5 + anAssymYv;
3354 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3355 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3356 gp_Pnt aNewCenter = aBBCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3358 gp_Trsf aCenterTrsf;
3359 aCenterTrsf.SetTranslation (theCamera->Center(), aNewCenter);
3360 theCamera->Transform (aCenterTrsf);
3361 theCamera->SetDistance (Max (aMatchDistance[5] + aMatchDistance[4], Precision::Confusion()));
3363 // Bounding box collapses to a point or thin line going in depth of the screen
3364 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3366 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3368 return Standard_True; // This is just one point or line and zooming has no effect.
3371 // Looking along line and "theToEnlargeIfLine" is requested.
3372 // Fit view to see whole scene on rotation.
3373 aViewSizeXv = aViewSizeZv;
3374 aViewSizeYv = aViewSizeZv;
3377 Scale (theCamera, aViewSizeXv * (1.0 + theMargin), aViewSizeYv * (1.0 + theMargin));
3379 return Standard_True;
3382 // =======================================================================
3384 // purpose : Internal
3385 // =======================================================================
3386 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3387 const Standard_Real theSizeXv,
3388 const Standard_Real theSizeYv) const
3390 Standard_Real anAspect = theCamera->Aspect();
3391 Standard_Real aMaxSize = Max (theSizeXv / anAspect, theSizeYv);
3392 theCamera->SetScale (aMaxSize);
3395 // =======================================================================
3396 // function : Translate
3397 // purpose : Internal
3398 // =======================================================================
3399 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3400 const Standard_Real theDXv,
3401 const Standard_Real theDYv) const
3403 const gp_Pnt& aCenter = theCamera->Center();
3404 const gp_Dir& aDir = theCamera->Direction();
3405 const gp_Dir& anUp = theCamera->Up();
3406 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3408 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3409 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3410 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3412 aPanTrsf.SetTranslation (aCameraPan);
3414 theCamera->Transform (aPanTrsf);