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 Size)
1350 V3d_BadValue_Raise_if( Size <= 0.,
1351 "V3d_View::SetSize, Window Size is NULL");
1353 myCamera->SetScale (Size);
1360 //=============================================================================
1361 //function : SetZSize
1363 //=============================================================================
1364 void V3d_View::SetZSize(const Standard_Real Size)
1366 Standard_Real Zmax = Size/2.;
1368 Standard_Real aDistance = myCamera->Distance();
1374 Standard_Real Front = MyViewContext.ZClippingFrontPlane();
1375 Standard_Real Back = MyViewContext.ZClippingBackPlane();
1377 // ShortReal precision factor used to add meaningful tolerance to
1378 // ZNear, ZFar values in order to avoid equality after type conversion
1379 // to ShortReal matrices type.
1380 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1382 Standard_Real aZFar = Zmax + aDistance * 2.0;
1383 Standard_Real aZNear = -Zmax + aDistance;
1384 aZNear -= Abs (aZNear) * aPrecision;
1385 aZFar += Abs (aZFar) * aPrecision;
1387 if (!myCamera->IsOrthographic())
1389 if (aZFar < aPrecision)
1391 // Invalid case when both values are negative
1392 aZNear = aPrecision;
1393 aZFar = aPrecision * 2.0;
1395 else if (aZNear < Abs (aZFar) * aPrecision)
1397 // Z is less than 0.0, try to fix it using any appropriate z-scale
1398 aZNear = Abs (aZFar) * aPrecision;
1402 // If range is too small
1403 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1405 aZFar = aZNear + Abs (aZFar) * aPrecision;
1408 myCamera->SetZRange (aZNear, aZFar);
1410 if (MyViewContext.FrontZClippingIsOn() ||
1411 MyViewContext.BackZClippingIsOn())
1413 MyViewContext.SetZClippingFrontPlane (Front);
1414 MyViewContext.SetZClippingBackPlane (Back);
1415 MyView->SetContext (MyViewContext);
1419 //=============================================================================
1420 //function : SetZoom
1422 //=============================================================================
1423 void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1425 V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
1429 myCamStartOpEye = myCamera->Eye();
1430 myCamStartOpCenter = myCamera->Center();
1433 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
1434 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
1436 // ensure that zoom will not be too small or too big
1437 Standard_Real coef = Coef;
1438 if (aViewWidth < coef * Precision::Confusion())
1440 coef = aViewWidth / Precision::Confusion();
1442 else if (aViewWidth > coef * 1e12)
1444 coef = aViewWidth / 1e12;
1446 if (aViewHeight < coef * Precision::Confusion())
1448 coef = aViewHeight / Precision::Confusion();
1450 else if (aViewHeight > coef * 1e12)
1452 coef = aViewHeight / 1e12;
1455 myCamera->SetEye (myCamStartOpEye);
1456 myCamera->SetCenter (myCamStartOpCenter);
1457 myCamera->SetScale (myCamera->Scale() / Coef);
1463 //=============================================================================
1464 //function : SetScale
1466 //=============================================================================
1467 void V3d_View::SetScale( const Standard_Real Coef )
1469 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1471 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1473 // Strange behavior for the sake of compatibility.
1474 if (!aDefaultCamera.IsNull())
1476 myCamera->SetAspect (aDefaultCamera->Aspect());
1477 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1478 myCamera->SetScale (aDefaultScale / Coef);
1482 myCamera->SetScale (myCamera->Scale() / Coef);
1490 //=============================================================================
1491 //function : SetAxialScale
1493 //=============================================================================
1494 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1496 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1498 myCamera->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1502 //=============================================================================
1505 //=============================================================================
1506 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1508 Standard_ASSERT_RAISE (theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1510 if (MyView->NumberOfDisplayedStructures() == 0)
1515 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
1516 MyView->MinMaxValues (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1517 gp_XYZ aMin (aXmin, aYmin, aZmin);
1518 gp_XYZ aMax (aXmax, aYmax, aZmax);
1520 if (!FitMinMax (myCamera, aMin, aMax, theMargin, 10.0 * Precision::Confusion()))
1527 if (myImmediateUpdate || theToUpdate)
1533 //=============================================================================
1534 //function : AutoZFit
1536 //=============================================================================
1537 void V3d_View::AutoZFit()
1539 if (!AutoZFitMode())
1544 ZFitAll (myAutoZFitScaleFactor);
1547 //=============================================================================
1548 //function : ZFitAll
1550 //=============================================================================
1551 void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
1553 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
1555 // Method changes ZNear and ZFar planes of camera so as to fit the graphical structures
1556 // by their real boundaries (computed ignoring infinite flag) into the viewing volume.
1557 // In addition to the graphical boundaries, the usual min max used for fitting perspective
1558 // camera. To avoid numeric errors for perspective camera the negative ZNear values are
1559 // fixed using tolerance distance, relative to boundaries size. The tolerance distance
1560 // should be computed using information on boundaries of primary application actors,
1561 // (e.g. representing the displayed model) - to ensure that they are not unreasonably clipped.
1563 Standard_Real aMinMax[6]; // applicative min max boundaries
1564 View()->MinMaxValues (aMinMax[0], aMinMax[1], aMinMax[2],
1565 aMinMax[3], aMinMax[4], aMinMax[5],
1568 Standard_Real aGraphicBB[6]; // real graphical boundaries (not accounting infinite flag).
1569 View()->MinMaxValues (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2],
1570 aGraphicBB[3], aGraphicBB[4], aGraphicBB[5],
1573 // Check if anything can be adjusted
1574 Standard_Real aLim = (ShortRealLast() - 1.0);
1575 if (Abs (aGraphicBB[0]) > aLim || Abs (aGraphicBB[1]) > aLim || Abs (aGraphicBB[2]) > aLim ||
1576 Abs (aGraphicBB[3]) > aLim || Abs (aGraphicBB[4]) > aLim || Abs (aGraphicBB[5]) > aLim)
1583 // Measure depth of boundary points from camera eye
1584 gp_Pnt aPntsToMeasure[16] =
1586 gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[2]),
1587 gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[5]),
1588 gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[2]),
1589 gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[5]),
1590 gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[2]),
1591 gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[5]),
1592 gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[2]),
1593 gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[5]),
1595 gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2]),
1596 gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[5]),
1597 gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[2]),
1598 gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[5]),
1599 gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[2]),
1600 gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[5]),
1601 gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[2]),
1602 gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[5])
1606 gp_Dir aCamDir = myCamera->Direction();
1607 gp_Pnt aCamEye = myCamera->Eye();
1608 gp_Pln aCamPln (aCamEye, aCamDir);
1610 Standard_Real aModelMinDist = RealLast();
1611 Standard_Real aModelMaxDist = RealFirst();
1612 Standard_Real aGraphicMinDist = RealLast();
1613 Standard_Real aGraphicMaxDist = RealFirst();
1615 const gp_XYZ& anAxialScale = myCamera->AxialScale();
1617 // Get minimum and maximum distances to the eye plane
1618 for (Standard_Integer aPntIt = 0; aPntIt < 16; ++aPntIt)
1620 gp_Pnt aMeasurePnt = aPntsToMeasure[aPntIt];
1622 if (Abs (aMeasurePnt.X()) > aLim || Abs (aMeasurePnt.Y()) > aLim || Abs (aMeasurePnt.Z()) > aLim)
1627 aMeasurePnt = gp_Pnt (aMeasurePnt.X() * anAxialScale.X(),
1628 aMeasurePnt.Y() * anAxialScale.Y(),
1629 aMeasurePnt.Z() * anAxialScale.Z());
1631 Standard_Real aDistance = aCamPln.Distance (aMeasurePnt);
1633 // Check if the camera is intruded into the scene
1634 if (aCamDir.IsOpposite (gp_Vec (aCamEye, aMeasurePnt), M_PI * 0.5))
1639 Standard_Real& aChangeMinDist = aPntIt >= 8 ? aGraphicMinDist : aModelMinDist;
1640 Standard_Real& aChangeMaxDist = aPntIt >= 8 ? aGraphicMaxDist : aModelMaxDist;
1641 aChangeMinDist = Min (aDistance, aChangeMinDist);
1642 aChangeMaxDist = Max (aDistance, aChangeMaxDist);
1645 // Compute depth of bounding box center
1646 Standard_Real aMidDepth = (aGraphicMinDist + aGraphicMaxDist) * 0.5;
1647 Standard_Real aHalfDepth = (aGraphicMaxDist - aGraphicMinDist) * 0.5;
1649 // ShortReal precision factor used to add meaningful tolerance to
1650 // ZNear, ZFar values in order to avoid equality after type conversion
1651 // to ShortReal matrices type.
1652 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1654 // Compute enlarged or shrank near and far z ranges
1655 Standard_Real aZNear = aMidDepth - aHalfDepth * theScaleFactor;
1656 Standard_Real aZFar = aMidDepth + aHalfDepth * theScaleFactor;
1657 aZNear -= Abs (aZNear) * aPrecision;
1658 aZFar += Abs (aZFar) * aPrecision;
1660 if (!myCamera->IsOrthographic())
1662 if (aZFar >= aPrecision)
1664 // To avoid numeric errors... (See comments in the beginning of the method).
1665 // Choose between model distance and graphical distance, as the model boundaries
1666 // might be infinite if all structures have infinite flag.
1667 const Standard_Real aGraphicDepth = aGraphicMaxDist >= aGraphicMinDist
1668 ? aGraphicMaxDist - aGraphicMinDist : RealLast();
1670 const Standard_Real aModelDepth = aModelMaxDist >= aModelMinDist
1671 ? aModelMaxDist - aModelMinDist : RealLast();
1673 const Standard_Real aMinDepth = Min (aModelDepth, aGraphicDepth);
1674 const Standard_Real aZTolerance =
1675 Max (Abs (aMinDepth) * aPrecision, aPrecision);
1677 if (aZNear < aZTolerance)
1679 aZNear = aZTolerance;
1682 else // aZFar < aPrecision - Invalid case when both ZNear and ZFar are negative
1684 aZNear = aPrecision;
1685 aZFar = aPrecision * 2.0;
1689 // If range is too small
1690 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1692 aZFar = aZNear + Abs (aZFar) * aPrecision;
1695 myCamera->SetZRange (aZNear, aZFar);
1700 //=============================================================================
1701 //function : DepthFitAll
1703 //=============================================================================
1704 void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1705 const Quantity_Coefficient Margin)
1707 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1708 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1709 Standard_Real Dx,Dy,Dz,Size;
1711 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1713 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1718 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
1720 Standard_Real LIM = ShortRealLast() -1.;
1721 if (Abs(Xmin) > LIM || Abs(Ymin) > LIM || Abs(Zmin) > LIM
1722 || Abs(Xmax) > LIM || Abs(Ymax) > LIM || Abs(Zmax) > LIM ) {
1727 if (Xmin == Xmax && Ymin == Ymax && Zmin == Zmax) {
1731 MyView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
1732 MyView->Projects(Xmax,Ymax,Zmax,U1,V1,W1) ;
1733 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1734 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1735 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1736 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
1737 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1738 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1739 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1740 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
1741 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1742 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1743 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1744 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
1745 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1746 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1747 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1748 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
1749 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1750 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1751 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1752 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
1753 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1754 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1755 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1756 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
1757 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1758 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1759 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1762 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1763 Dz = 2.*Wmax + Margin * Wmax;
1765 // Compute depth value
1766 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1767 Dx += Margin * Dx; Dy += Margin * Dy;
1768 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1771 SetDepth( Aspect * Size / 2.);
1777 //=============================================================================
1780 //=============================================================================
1781 void V3d_View::FitAll(const Standard_Real theMinXv,
1782 const Standard_Real theMinYv,
1783 const Standard_Real theMaxXv,
1784 const Standard_Real theMaxYv)
1786 FitAll (MyWindow, theMinXv, theMinYv, theMaxXv, theMaxYv);
1789 //=============================================================================
1790 //function : WindowFitAll
1792 //=============================================================================
1793 void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1794 const Standard_Integer Ymin,
1795 const Standard_Integer Xmax,
1796 const Standard_Integer Ymax)
1798 WindowFit(Xmin,Ymin,Xmax,Ymax);
1801 //=======================================================================
1802 //function : WindowFit
1804 //=======================================================================
1805 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1806 const Standard_Integer theMinYp,
1807 const Standard_Integer theMaxXp,
1808 const Standard_Integer theMaxYp)
1810 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1812 if (!myCamera->IsOrthographic())
1814 // normalize view coordiantes
1815 Standard_Integer aWinWidth, aWinHeight;
1816 MyWindow->Size (aWinWidth, aWinHeight);
1818 // z coordinate of camera center
1819 Standard_Real aDepth = myCamera->Project (myCamera->Center()).Z();
1821 // camera projection coordinate are in NDC which are normalized [-1, 1]
1822 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1823 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1824 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1825 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1827 // compute camera panning
1828 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1829 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1830 gp_Pnt aPanTo = myCamera->ConvertProj2View (aFitCenter);
1831 gp_Pnt aPanFrom = myCamera->ConvertProj2View (aScreenCenter);
1832 gp_Vec aPanVec (aPanFrom, aPanTo);
1834 // compute section size
1835 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1836 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1837 gp_Pnt aViewBotLeft = myCamera->ConvertProj2View (aFitBotLeft);
1838 gp_Pnt aViewTopRight = myCamera->ConvertProj2View (aFitTopRight);
1840 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1841 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1843 Translate (myCamera, aPanVec.X(), -aPanVec.Y());
1844 Scale (myCamera, aUSize, aVSize);
1849 Standard_Real aX1, aY1, aX2, aY2;
1850 Convert (theMinXp, theMinYp, aX1, aY1);
1851 Convert (theMaxXp, theMaxYp, aX2, aY2);
1852 FitAll (aX1, aY1, aX2, aY2);
1855 SetImmediateUpdate (wasUpdateEnabled);
1860 //=======================================================================
1861 //function : SetViewMappingDefault
1863 //=======================================================================
1864 void V3d_View::SetViewMappingDefault()
1866 MyView->SetViewMappingDefault();
1871 //=======================================================================
1872 //function : ResetViewMapping
1874 //=======================================================================
1875 void V3d_View::ResetViewMapping()
1877 MyView->ViewMappingReset();
1882 //=======================================================================
1883 //function : ConvertToGrid
1885 //=======================================================================
1886 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1887 const Standard_Integer Yp,
1890 Standard_Real& Zg) const
1892 Graphic3d_Vertex aVrp;
1893 Standard_Real anX, anY, aZ;
1894 Convert (Xp, Yp, anX, anY, aZ);
1895 aVrp.SetCoord (anX, anY, aZ);
1897 if( MyViewer->Grid()->IsActive() ) {
1898 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1899 aNewVrp.Coord (Xg,Yg,Zg) ;
1901 aVrp.Coord (Xg,Yg,Zg) ;
1904 //=======================================================================
1905 //function : ConvertToGrid
1907 //=======================================================================
1908 void V3d_View::ConvertToGrid(const Standard_Real X,
1909 const Standard_Real Y,
1910 const Standard_Real Z,
1913 Standard_Real& Zg) const
1915 if( MyViewer->Grid()->IsActive() ) {
1916 Graphic3d_Vertex aVrp (X,Y,Z) ;
1917 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1918 aNewVrp.Coord(Xg,Yg,Zg) ;
1920 Xg = X; Yg = Y; Zg = Z;
1924 //=======================================================================
1925 //function : Convert
1927 //=======================================================================
1928 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1930 Standard_Integer aDxw, aDyw ;
1932 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1934 MyWindow->Size (aDxw, aDyw);
1935 Standard_Real aValue;
1937 gp_Pnt aViewDims = myCamera->ViewDimensions();
1938 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1943 //=======================================================================
1944 //function : Convert
1946 //=======================================================================
1947 void V3d_View::Convert(const Standard_Integer Xp,
1948 const Standard_Integer Yp,
1950 Standard_Real& Yv) const
1952 Standard_Integer aDxw, aDyw;
1954 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1956 MyWindow->Size (aDxw, aDyw);
1958 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1959 aPoint = myCamera->ConvertProj2View (aPoint);
1965 //=======================================================================
1966 //function : Convert
1968 //=======================================================================
1969 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1971 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1973 Standard_Integer aDxw, aDyw;
1974 MyWindow->Size (aDxw, aDyw);
1976 gp_Pnt aViewDims = myCamera->ViewDimensions();
1977 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1982 //=======================================================================
1983 //function : Convert
1985 //=======================================================================
1986 void V3d_View::Convert(const Standard_Real Xv,
1987 const Standard_Real Yv,
1988 Standard_Integer& Xp,
1989 Standard_Integer& Yp) const
1991 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1993 Standard_Integer aDxw, aDyw;
1994 MyWindow->Size (aDxw, aDyw);
1996 gp_Pnt aPoint (Xv, Yv, 0.0);
1997 aPoint = myCamera->ConvertView2Proj (aPoint);
1998 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
2000 Xp = RealToInt (aPoint.X());
2001 Yp = RealToInt (aPoint.Y());
2004 //=======================================================================
2005 //function : Convert
2007 //=======================================================================
2008 void V3d_View::Convert(const Standard_Integer Xp,
2009 const Standard_Integer Yp,
2012 Standard_Real& Z) const
2014 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
2015 Standard_Integer aHeight, aWidth;
2016 MyWindow->Size (aWidth, aHeight);
2018 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
2019 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
2020 Standard_Real aZ = 2.0 * 0.0 - 1.0;
2022 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
2028 Graphic3d_Vertex aVrp;
2029 aVrp.SetCoord (X, Y, Z);
2031 if( MyViewer->Grid()->IsActive() ) {
2032 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
2033 aNewVrp.Coord (X, Y, Z) ;
2037 //=======================================================================
2038 //function : ConvertWithProj
2040 //=======================================================================
2041 void V3d_View::ConvertWithProj(const Standard_Integer Xp,
2042 const Standard_Integer Yp,
2048 Standard_Real& Dz) const
2050 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
2051 Standard_Integer aHeight, aWidth;
2052 MyWindow->Size (aWidth, aHeight);
2054 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
2055 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
2056 Standard_Real aZ = 2.0 * 0.0 - 1.0;
2058 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
2064 Graphic3d_Vertex aVrp;
2065 aVrp.SetCoord (X, Y, Z);
2067 aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
2069 Dx = X - aResult.X();
2070 Dy = Y - aResult.Y();
2071 Dz = Z - aResult.Z();
2073 if( MyViewer->Grid()->IsActive() ) {
2074 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
2075 aNewVrp.Coord (X, Y, Z) ;
2079 //=======================================================================
2080 //function : Convert
2082 //=======================================================================
2083 void V3d_View::Convert(const Standard_Real X,
2084 const Standard_Real Y,
2085 const Standard_Real Z,
2086 Standard_Integer& Xp,
2087 Standard_Integer& Yp) const
2089 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
2090 Standard_Integer aHeight, aWidth;
2091 MyWindow->Size (aWidth, aHeight);
2093 gp_Pnt aPoint = myCamera->Project (gp_Pnt (X, Y, Z));
2095 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
2096 Yp = RealToInt ((aPoint.Y() + 1) * 0.5 * aHeight);
2099 //=======================================================================
2100 //function : Project
2102 //=======================================================================
2103 void V3d_View::Project(const Standard_Real X,
2104 const Standard_Real Y,
2105 const Standard_Real Z,
2107 Standard_Real &Yp) const
2110 MyView->Projects (X, Y, Z, Xp, Yp, Zp);
2113 //=======================================================================
2114 //function : BackgroundColor
2116 //=======================================================================
2117 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
2120 Standard_Real& V3) const
2122 Quantity_Color C = BackgroundColor() ;
2123 C.Values(V1,V2,V3,Type) ;
2126 //=======================================================================
2127 //function : BackgroundColor
2129 //=======================================================================
2130 Quantity_Color V3d_View::BackgroundColor() const
2132 return MyBackground.Color() ;
2135 //=======================================================================
2136 //function : GradientBackgroundColors
2138 //=======================================================================
2139 void V3d_View::GradientBackgroundColors(Quantity_Color& Color1,Quantity_Color& Color2) const
2141 MyGradientBackground.Colors(Color1, Color2);
2144 //=======================================================================
2145 //function : GradientBackground
2147 //=======================================================================
2148 Aspect_GradientBackground V3d_View::GradientBackground() const
2150 return MyGradientBackground;
2153 //=======================================================================
2156 //=======================================================================
2157 Standard_Real V3d_View::Scale() const
2159 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
2161 Standard_Real aCameraScale;
2163 // Strange behavior for the sake of compatibility.
2164 if (!aDefaultCamera.IsNull())
2166 Standard_Real aDefaultScale = aDefaultCamera->Scale();
2167 aCameraScale = aDefaultScale / myCamera->Scale();
2171 aCameraScale = myCamera->Scale();
2174 return aCameraScale;
2177 //=======================================================================
2178 //function : AxialScale
2180 //=======================================================================
2181 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
2183 gp_Pnt anAxialScale = myCamera->AxialScale();
2184 Sx = anAxialScale.X();
2185 Sy = anAxialScale.Y();
2186 Sz = anAxialScale.Z();
2189 //=======================================================================
2192 //=======================================================================
2193 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
2195 gp_Pnt aViewDims = myCamera->ViewDimensions();
2197 Width = aViewDims.X();
2198 Height = aViewDims.Y();
2201 //=======================================================================
2204 //=======================================================================
2205 Standard_Real V3d_View::ZSize() const
2207 gp_Pnt aViewDims = myCamera->ViewDimensions();
2209 return aViewDims.Z();
2212 //=======================================================================
2215 //=======================================================================
2216 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
2217 Standard_Real& Vmin,
2218 Standard_Real& Umax,
2219 Standard_Real& Vmax) const
2221 Standard_Real Wmin,Wmax,U,V,W ;
2222 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
2224 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2227 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
2228 MyView->Projects(Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
2229 MyView->Projects(Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
2230 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
2231 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2232 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2233 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2234 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
2235 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2236 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2237 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2238 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
2239 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2240 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2241 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2242 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
2243 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2244 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2245 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2246 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
2247 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2248 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2249 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2250 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
2251 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2252 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2253 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2258 //=======================================================================
2261 //=======================================================================
2262 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
2263 Standard_Real& Ymin,
2264 Standard_Real& Zmin,
2265 Standard_Real& Xmax,
2266 Standard_Real& Ymax,
2267 Standard_Real& Zmax) const
2270 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
2271 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2274 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
2279 //=======================================================================
2280 //function : Gravity
2282 //=======================================================================
2283 Standard_Integer V3d_View::Gravity(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2285 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax;
2286 Standard_Integer Nstruct,Npoint ;
2287 Graphic3d_MapOfStructure MySetOfStructures;
2289 MyView->DisplayedStructures (MySetOfStructures);
2290 Nstruct = MySetOfStructures.Extent() ;
2292 Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ;
2294 Npoint = 0 ; X = Y = Z = 0. ;
2295 for (; MyIterator.More(); MyIterator.Next())
2297 const Handle(Graphic3d_Structure)& aStruct = MyIterator.Key();
2298 if (!aStruct->IsEmpty())
2300 aStruct->MinMaxValues (Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
2302 // Check bounding box for validness
2303 Standard_Real aLim = (ShortRealLast() - 1.0);
2304 if (Abs (Xmin) > aLim || Abs (Ymin) > aLim || Abs (Zmin) > aLim ||
2305 Abs (Xmax) > aLim || Abs (Ymax) > aLim || Abs (Zmax) > aLim)
2310 // use camera projection to find gravity point
2312 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2313 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2314 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2315 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax) };
2317 for (Standard_Integer aPntIt = 0; aPntIt < 8; ++aPntIt)
2319 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2321 gp_Pnt aProjected = myCamera->Project (aBndPnt);
2322 const Standard_Real& U = aProjected.X();
2323 const Standard_Real& V = aProjected.Y();
2324 if (Abs(U) <= 1.0 && Abs(V) <= 1.0)
2335 X /= Npoint ; Y /= Npoint ; Z /= Npoint ;
2341 //=======================================================================
2344 //=======================================================================
2345 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2347 gp_Pnt aCameraEye = myCamera->Eye();
2353 //=============================================================================
2354 //function : FocalReferencePoint
2356 //=============================================================================
2357 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2362 //=============================================================================
2363 //function : ProjReferenceAxe
2365 //=============================================================================
2366 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2367 const Standard_Integer Ypix,
2373 Standard_Real& VZ) const
2375 Standard_Real Xo,Yo,Zo;
2377 Convert (Xpix, Ypix, XP, YP, ZP);
2378 if ( Type() == V3d_PERSPECTIVE )
2380 FocalReferencePoint (Xo,Yo,Zo);
2391 //=============================================================================
2394 //=============================================================================
2395 Standard_Real V3d_View::Depth() const
2397 return myCamera->Distance();
2400 //=============================================================================
2403 //=============================================================================
2404 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2406 gp_Dir aCameraDir = myCamera->Direction().Reversed();
2407 Dx = aCameraDir.X();
2408 Dy = aCameraDir.Y();
2409 Dz = aCameraDir.Z();
2412 //=============================================================================
2415 //=============================================================================
2416 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2418 gp_Pnt aCameraCenter = myCamera->Center();
2419 X = aCameraCenter.X();
2420 Y = aCameraCenter.Y();
2421 Z = aCameraCenter.Z();
2424 //=============================================================================
2427 //=============================================================================
2428 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2430 gp_Dir aCameraUp = myCamera->Up();
2436 //=============================================================================
2439 //=============================================================================
2440 Standard_Real V3d_View::Twist() const
2442 Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2443 Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
2444 Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
2445 Standard_Boolean TheStatus ;
2447 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
2451 anUp = gp_Dir (0.,0.,1.) ;
2452 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2454 anUp = gp_Dir (0.,1.,0.) ;
2455 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2458 anUp = gp_Dir (1.,0.,0.) ;
2459 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2461 Yaxis.Coord(X0,Y0,Z0) ;
2464 /* Compute Cross Vector From Up & Origin */
2465 pvx = Y0*Zup - Z0*Yup ;
2466 pvy = Z0*Xup - X0*Zup ;
2467 pvz = X0*Yup - Y0*Xup ;
2468 pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2469 sca = X0*Xup + Y0*Yup + Z0*Zup ;
2472 if( angle > 1. ) angle = 1. ;
2473 else if( angle < -1. ) angle = -1. ;
2474 angle = asin(angle) ;
2475 if( sca < 0. ) angle = M_PI - angle ;
2476 if( angle > 0. && angle < M_PI ) {
2477 sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2478 if( sca < 0. ) angle = DEUXPI - angle ;
2483 //=============================================================================
2484 //function : ShadingModel
2486 //=============================================================================
2487 V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2489 V3d_TypeOfShadingModel SM = (V3d_TypeOfShadingModel)MyViewContext.Model() ;
2493 //=============================================================================
2494 //function : SurfaceDetail
2496 //=============================================================================
2497 V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
2499 V3d_TypeOfSurfaceDetail SM = (V3d_TypeOfSurfaceDetail)MyViewContext.SurfaceDetail() ;
2503 //=============================================================================
2504 //function : TextureEnv
2506 //=============================================================================
2507 Handle_Graphic3d_TextureEnv V3d_View::TextureEnv() const
2509 Handle(Graphic3d_TextureEnv) SM = MyViewContext.TextureEnv() ;
2513 //=============================================================================
2514 //function : Visualization
2516 //=============================================================================
2517 V3d_TypeOfVisualization V3d_View::Visualization() const
2519 V3d_TypeOfVisualization V =
2520 (V3d_TypeOfVisualization)MyViewContext.Visualization() ;
2524 //=============================================================================
2525 //function : Antialiasing
2527 //=============================================================================
2528 Standard_Boolean V3d_View::Antialiasing() const
2530 Standard_Boolean A = MyViewContext.AliasingIsOn() ;
2534 //=============================================================================
2537 //=============================================================================
2538 Handle(V3d_Viewer) V3d_View::Viewer() const
2543 //=============================================================================
2544 //function : IfWindow
2546 //=============================================================================
2547 Standard_Boolean V3d_View::IfWindow() const
2549 Standard_Boolean TheStatus = MyView->IsDefined() ;
2553 //=============================================================================
2556 //=============================================================================
2557 Handle(Aspect_Window) V3d_View::Window() const
2562 //=============================================================================
2565 //=============================================================================
2566 V3d_TypeOfView V3d_View::Type() const
2568 return myCamera->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2571 //=============================================================================
2572 //function : SetFocale
2574 //=============================================================================
2575 void V3d_View::SetFocale( const Standard_Real focale )
2577 if (myCamera->IsOrthographic())
2582 Standard_Real aFOVyRad = ATan (focale / (myCamera->Distance() * 2.0));
2584 myCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2589 //=============================================================================
2592 //=============================================================================
2593 Standard_Real V3d_View::Focale() const
2595 if (myCamera->IsOrthographic())
2600 return myCamera->Distance() * 2.0 * Tan(myCamera->FOVy() * M_PI / 360.0);
2603 //=============================================================================
2606 //=============================================================================
2607 Handle(Visual3d_View) V3d_View::View() const
2612 //=============================================================================
2613 //function : ScreenAxis
2615 //=============================================================================
2616 Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2618 Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2619 Standard_Real dx1, dy1, dz1, xx, yy, zz;
2621 Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2622 Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2623 xx = Yup*Zpn - Zup*Ypn;
2624 yy = Zup*Xpn - Xup*Zpn;
2625 zz = Xup*Ypn - Yup*Xpn;
2626 Xaxe.SetCoord (xx, yy, zz);
2627 if (Xaxe.LengthZero()) return Standard_False;
2629 Xaxe.Coord(dx1, dy1, dz1);
2630 xx = Ypn*dz1 - Zpn*dy1;
2631 yy = Zpn*dx1 - Xpn*dz1;
2632 zz = Xpn*dy1 - Ypn*dx1;
2633 Yaxe.SetCoord (xx, yy, zz) ;
2634 if (Yaxe.LengthZero()) return Standard_False;
2637 Zaxe.SetCoord (Xpn, Ypn, Zpn);
2639 return Standard_True;
2642 //=============================================================================
2643 //function : TrsPoint
2645 //=============================================================================
2646 Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2648 Graphic3d_Vertex PP ;
2649 Standard_Real X,Y,Z,XX,YY,ZZ ;
2652 Standard_Integer lr, ur, lc, uc;
2653 lr = Matrix.LowerRow ();
2654 ur = Matrix.UpperRow ();
2655 lc = Matrix.LowerCol ();
2656 uc = Matrix.UpperCol ();
2657 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
2659 PP.SetCoord(X,Y,Z) ;
2663 XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2664 Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2666 YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2667 Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2669 ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2670 Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2671 PP.SetCoord(XX,YY,ZZ) ;
2675 //=======================================================================
2678 //=======================================================================
2679 void V3d_View::Pan (const Standard_Integer theDXp,
2680 const Standard_Integer theDYp,
2681 const Quantity_Factor theZoomFactor,
2682 const Standard_Boolean theToStart)
2684 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2687 //=======================================================================
2688 //function : Panning
2690 //=======================================================================
2691 void V3d_View::Panning (const Standard_Real theDXv,
2692 const Standard_Real theDYv,
2693 const Quantity_Factor theZoomFactor,
2694 const Standard_Boolean theToStart)
2696 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2700 myCamStartOpEye = myCamera->Eye();
2701 myCamStartOpCenter = myCamera->Center();
2704 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2706 gp_Pnt aViewDims = myCamera->ViewDimensions();
2708 myCamera->SetEye (myCamStartOpEye);
2709 myCamera->SetCenter (myCamStartOpCenter);
2710 Translate (myCamera, -theDXv, -theDYv);
2711 Scale (myCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2713 SetImmediateUpdate (wasUpdateEnabled);
2718 //=======================================================================
2721 //=======================================================================
2722 void V3d_View::Zoom (const Standard_Integer theXp1,
2723 const Standard_Integer theYp1,
2724 const Standard_Integer theXp2,
2725 const Standard_Integer theYp2)
2727 Standard_Integer aDx = theXp2 - theXp1;
2728 Standard_Integer aDy = theYp2 - theYp1;
2729 if (aDx != 0 || aDy != 0)
2731 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2732 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2733 SetZoom (aCoeff, Standard_True);
2737 //=======================================================================
2738 //function : StartZoomAtPoint
2740 //=======================================================================
2741 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2742 const Standard_Integer theYp)
2744 MyZoomAtPointX = theXp;
2745 MyZoomAtPointY = theYp;
2748 //=======================================================================
2749 //function : ZoomAtPoint
2751 //=======================================================================
2752 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2753 const Standard_Integer theMouseStartY,
2754 const Standard_Integer theMouseEndX,
2755 const Standard_Integer theMouseEndY)
2757 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2760 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2761 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2762 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2764 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2766 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
2767 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
2769 // ensure that zoom will not be too small or too big.
2770 Standard_Real aCoef = aDZoom;
2771 if (aViewWidth < aCoef * Precision::Confusion())
2773 aCoef = aViewWidth / Precision::Confusion();
2775 else if (aViewWidth > aCoef * 1e12)
2777 aCoef = aViewWidth / 1e12;
2779 if (aViewHeight < aCoef * Precision::Confusion())
2781 aCoef = aViewHeight / Precision::Confusion();
2783 else if (aViewHeight > aCoef * 1e12)
2785 aCoef = aViewHeight / 1e12;
2788 Standard_Real aZoomAtPointXv = 0.0;
2789 Standard_Real aZoomAtPointYv = 0.0;
2790 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2792 V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
2793 V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
2795 myCamera->SetScale (myCamera->Scale() / aCoef);
2796 Translate (myCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2800 SetImmediateUpdate (wasUpdateEnabled);
2805 //=============================================================================
2806 //function : AxialScale
2808 //=============================================================================
2809 void V3d_View::AxialScale (const Standard_Integer Dx,
2810 const Standard_Integer Dy,
2811 const V3d_TypeOfAxe Axis)
2813 if( Dx != 0. || Dy != 0. ) {
2814 Standard_Real Sx, Sy, Sz;
2815 AxialScale( Sx, Sy, Sz );
2816 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2817 dscale = (Dx > 0) ? dscale : 1./dscale;
2818 if( Axis == V3d_X ) Sx = dscale;
2819 if( Axis == V3d_Y ) Sy = dscale;
2820 if( Axis == V3d_Z ) Sz = dscale;
2821 SetAxialScale( Sx, Sy, Sz );
2825 //=============================================================================
2828 //=============================================================================
2829 void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
2830 const Standard_Real Xmin,
2831 const Standard_Real Ymin,
2832 const Standard_Real Xmax,
2833 const Standard_Real Ymax)
2835 Standard_Integer aWinWidth, aWinHeight;
2836 aWindow->Size (aWinWidth, aWinHeight);
2838 Standard_Real aWinAspect = (Standard_Real)aWinWidth / aWinHeight;
2839 Standard_Real aFitSizeU = Abs (Xmax - Xmin);
2840 Standard_Real aFitSizeV = Abs (Ymax - Ymin);
2841 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2842 if (aFitAspect >= aWinAspect)
2844 aFitSizeV = aFitSizeU / aWinAspect;
2848 aFitSizeU = aFitSizeV * aWinAspect;
2851 myCamera->SetAspect (aWinAspect);
2852 Translate (myCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
2853 Scale (myCamera, aFitSizeU, aFitSizeV);
2859 //=============================================================================
2860 //function : StartRotation
2862 //=============================================================================
2864 static Standard_Boolean zRotation = Standard_False;
2866 void V3d_View::StartRotation(const Standard_Integer X,
2867 const Standard_Integer Y,
2868 const Quantity_Ratio zRotationThreshold)
2873 rx = Standard_Real(Convert(x));
2874 ry = Standard_Real(Convert(y));
2876 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2878 zRotation = Standard_False;
2879 if( zRotationThreshold > 0. ) {
2880 Standard_Real dx = Abs(sx - rx/2.);
2881 Standard_Real dy = Abs(sy - ry/2.);
2882 // if( dx > rx/3. || dy > ry/3. ) zRotation = Standard_True;
2883 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2884 if( dx > dd || dy > dd ) zRotation = Standard_True;
2890 //=============================================================================
2891 //function : Rotation
2893 //=============================================================================
2894 void V3d_View::Rotation(const Standard_Integer X,
2895 const Standard_Integer Y)
2898 if( rx == 0. || ry == 0. ) {
2904 Standard_Real dx=0.,dy=0.,dz=0.;
2906 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2907 atan2(sx-rx/2.,ry/2.-sy);
2909 dx = (Standard_Real(X) - sx) * M_PI / rx;
2910 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2912 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2914 Standard_Real dx = (Standard_Real(X - sx)) * M_PI;
2915 Standard_Real dy = (Standard_Real(sy - Y)) * M_PI;
2916 Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2919 if( !myImmediateUpdate ) Update();
2921 myImmediateUpdate = Standard_False;
2922 Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2923 ZFitAll (Zmargin); //Don't do that, perf improvment
2924 myImmediateUpdate = Standard_True;
2929 //=============================================================================
2930 //function : SetComputedMode
2932 //=============================================================================
2933 void V3d_View::SetComputedMode (const Standard_Boolean aMode)
2939 MyView->SetComputedMode (Standard_True);
2945 MyView->SetComputedMode (Standard_False);
2950 //=============================================================================
2951 //function : ComputedMode
2953 //=============================================================================
2954 Standard_Boolean V3d_View::ComputedMode() const
2956 return MyView->ComputedMode();
2959 //=============================================================================
2960 //function : SetBackFacingModel
2962 //=============================================================================
2963 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel aModel)
2965 MyView->SetBackFacingModel (Visual3d_TypeOfBackfacingModel(aModel));
2969 //=============================================================================
2970 //function : BackFacingModel
2972 //=============================================================================
2973 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2975 return V3d_TypeOfBackfacingModel(MyView -> BackFacingModel ());
2978 //=============================================================================
2979 //function : TransientManagerBeginDraw
2981 //=============================================================================
2982 Standard_Boolean V3d_View::TransientManagerBeginDraw(const Standard_Boolean DoubleBuffer,const Standard_Boolean RetainMode) const
2984 return Visual3d_TransientManager::BeginDraw(MyView,DoubleBuffer,RetainMode);
2987 //=============================================================================
2988 //function : TransientManagerClearDraw
2990 //=============================================================================
2991 void V3d_View::TransientManagerClearDraw() const
2993 Visual3d_TransientManager::ClearDraw(MyView);
2996 //=============================================================================
2997 //function : TransientManagerBeginAddDraw
2999 //=============================================================================
3000 Standard_Boolean V3d_View::TransientManagerBeginAddDraw() const
3002 return Visual3d_TransientManager::BeginAddDraw(MyView);
3005 //=============================================================================
3008 //=============================================================================
3009 void V3d_View::Init()
3011 myComputedMode = MyViewer->ComputedMode();
3012 if( !myComputedMode || !MyViewer->DefaultComputedMode() ) {
3013 SetComputedMode(Standard_False);
3017 //=============================================================================
3018 //function : SetPlotter
3020 //=============================================================================
3021 void V3d_View::SetPlotter(const Handle(Graphic3d_Plotter)& aPlotter)
3023 MyPlotter = aPlotter;
3026 //=============================================================================
3029 //=============================================================================
3030 void V3d_View::Plot()
3032 V3d_BadValue_Raise_if( !MyPlotter.IsNull(), "view has no plotter");
3033 MyView->Plot(MyPlotter);
3036 //=============================================================================
3039 //=============================================================================
3040 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
3041 const Graphic3d_BufferType& theBufferType)
3043 Standard_Integer aWinWidth, aWinHeight;
3044 MyWindow->Size (aWinWidth, aWinHeight);
3045 Image_AlienPixMap anImage;
3047 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
3050 //=============================================================================
3051 //function : ToPixMap
3053 //=============================================================================
3054 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
3055 const Standard_Integer theWidth,
3056 const Standard_Integer theHeight,
3057 const Graphic3d_BufferType& theBufferType,
3058 const Standard_Boolean theToKeepAspect,
3059 const V3d_StereoDumpOptions theStereoOptions)
3061 Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
3063 // always prefer hardware accelerated offscreen buffer
3064 Graphic3d_PtrFrameBuffer aFBOPtr = NULL;
3065 Graphic3d_PtrFrameBuffer aPrevFBOPtr = (Graphic3d_PtrFrameBuffer )cView->ptrFBO;
3066 Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
3067 Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
3068 if (aPrevFBOPtr != NULL)
3070 MyView->FBOGetDimensions (aPrevFBOPtr,
3071 aPrevFBOVPSizeX, aPrevFBOVPSizeY,
3072 aPrevFBOSizeXMax, aPrevFBOSizeYMax);
3073 if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
3075 MyView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
3076 aFBOPtr = aPrevFBOPtr;
3080 if (aFBOPtr == NULL)
3082 // Try to create hardware accelerated buffer
3083 aFBOPtr = MyView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
3084 if (aFBOPtr != NULL)
3086 MyView->FBOGetDimensions (aFBOPtr,
3087 aFBOVPSizeX, aFBOVPSizeY,
3088 aFBOSizeXMax, aFBOSizeYMax);
3089 // reduce viewport in case of hardware limits
3090 if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
3091 if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
3092 MyView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
3095 cView->ptrFBO = aFBOPtr;
3097 // If hardware accelerated buffer - try to use onscreen buffer
3098 // Results may be bad!
3099 if (aFBOPtr == NULL)
3101 // retrieve window sizes
3102 Standard_Integer aWinWidth, aWinHeight;
3103 MyWindow->Size (aWinWidth, aWinHeight);
3105 // technically we can reduce existing viewport...
3106 // but currently allow only dumping the window itself
3107 if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
3109 return Standard_False;
3113 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
3115 aStoreMapping->Copy (myCamera);
3117 if (myCamera->IsStereo())
3119 switch (theStereoOptions)
3122 myCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
3125 case V3d_SDO_LEFT_EYE :
3126 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
3129 case V3d_SDO_RIGHT_EYE :
3130 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
3137 if (theToKeepAspect)
3139 myCamera->SetAspect ((Standard_Real) aFBOVPSizeX / aFBOSizeYMax);
3142 //workaround for rendering list of Over and Under Layers
3143 if (!MyLayerMgr.IsNull())
3145 MyLayerMgr->Compute();
3148 // render immediate structures into back buffer rather than front
3149 Handle(Graphic3d_GraphicDriver) aDriver = Handle(Graphic3d_GraphicDriver)::DownCast (MyView->GraphicDriver());
3150 const Standard_Boolean aPrevImmediateMode = aDriver.IsNull() ? Standard_True : aDriver->SetImmediateModeDrawToFront (*cView, Standard_False);
3153 if (!aDriver.IsNull())
3155 aDriver->SetImmediateModeDrawToFront (*cView, aPrevImmediateMode);
3158 myCamera->Copy (aStoreMapping);
3160 Standard_Boolean isSuccess = Standard_True;
3162 // allocate image buffer for dumping
3163 if (theImage.IsEmpty()
3164 || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
3165 || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
3167 bool isBigEndian = Image_PixMap::IsBigEndianHost();
3168 Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
3169 switch (theBufferType)
3171 case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
3172 case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
3173 case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
3176 isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
3178 isSuccess = isSuccess && MyView->BufferDump (theImage, theBufferType);
3180 // FBO now useless, free resources
3181 if (aFBOPtr != aPrevFBOPtr)
3183 MyView->FBORelease (aFBOPtr);
3185 else if (aPrevFBOPtr != NULL)
3187 MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
3189 cView->ptrFBO = aPrevFBOPtr;
3193 void V3d_View::ImmediateUpdate() const
3195 if (myImmediateUpdate) Update();
3198 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
3200 Standard_Boolean aPreviousMode = myImmediateUpdate;
3201 myImmediateUpdate = theImmediateUpdate;
3202 return aPreviousMode;
3205 // =======================================================================
3206 // function : SetCamera
3208 // =======================================================================
3209 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
3211 Standard_ASSERT_RAISE (!theCamera.IsNull(), "Void camera is not allowed");
3213 myCamera = theCamera;
3215 MyView->SetCamera (theCamera);
3218 // =======================================================================
3219 // function : GetCamera
3221 // =======================================================================
3222 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
3227 // =======================================================================
3228 // function : FitMinMax
3229 // purpose : Internal
3230 // =======================================================================
3231 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
3232 const gp_XYZ& theMinCorner,
3233 const gp_XYZ& theMaxCorner,
3234 const Standard_Real theMargin,
3235 const Standard_Real theResolution,
3236 const Standard_Boolean theToEnlargeIfLine) const
3238 // Check bounding box for validness
3239 Standard_Real aLim = (ShortRealLast() - 1.0);
3240 if (Abs (theMinCorner.X()) > aLim || Abs (theMinCorner.Y()) > aLim || Abs (theMinCorner.Z()) > aLim ||
3241 Abs (theMaxCorner.X()) > aLim || Abs (theMaxCorner.Y()) > aLim || Abs (theMaxCorner.Z()) > aLim)
3243 return Standard_False; // bounding box is out of bounds...
3246 // Apply "axial scaling" to the bounding points.
3247 // It is not the best approach to make this scaling as a part of fit all operation,
3248 // but the axial scale is integrated into camera orientation matrix and the other
3249 // option is to perform frustum plane adjustment algorithm in view camera space,
3250 // which will lead to a number of additional world-view space conversions and
3251 // loosing precision as well.
3252 Standard_Real aXmin = theMinCorner.X() * theCamera->AxialScale().X();
3253 Standard_Real aXmax = theMaxCorner.X() * theCamera->AxialScale().X();
3254 Standard_Real aYmin = theMinCorner.Y() * theCamera->AxialScale().Y();
3255 Standard_Real aYmax = theMaxCorner.Y() * theCamera->AxialScale().Y();
3256 Standard_Real aZmin = theMinCorner.Z() * theCamera->AxialScale().Z();
3257 Standard_Real aZmax = theMaxCorner.Z() * theCamera->AxialScale().Z();
3260 aBBox.Update (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3261 if (aBBox.IsThin (RealEpsilon()))
3263 return Standard_False; // nothing to fit all
3266 gp_Pnt aBBCenter ((aXmin + aXmax) * 0.5, (aYmin + aYmax) * 0.5, (aZmin + aZmax) * 0.5);
3268 gp_Pln aFrustumLeft;
3269 gp_Pln aFrustumRight;
3270 gp_Pln aFrustumBottom;
3272 gp_Pln aFrustumNear;
3274 theCamera->Frustum (aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar);
3276 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3277 gp_Dir aCamDir = theCamera->Direction();
3278 gp_Dir aCamSide = aCamDir ^ aCamUp;
3280 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3281 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3282 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3283 // set up perspective-correct camera projection matching the bounding box.
3284 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3285 // The zooming can be done by calculating view plane size matching the bounding box at center of
3286 // the bounding box. The only limitation here is that the scale of camera should define size of
3287 // its view plane passing through the camera center, and the center of camera should be on the
3288 // same line with the center of bounding box.
3290 // The following method is applied:
3291 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3292 // 2) Determine new location of frustum planes, "matching" the bounding box.
3293 // 3) Determine new camera projection vector using the normalized asymmetry.
3294 // 4) Determine new zooming in view space.
3296 // Determine normalized projection asymmetry (if any).
3298 Standard_Real anAssymX = Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction()))
3299 - Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction()));
3300 Standard_Real anAssymY = Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction()))
3301 - Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction()));
3303 // Determine how far should be the frustum planes placed from center
3304 // of bounding box, in order to match the bounding box closely.
3305 gp_Pln aMatchSide[6] = {aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar};
3306 Standard_Real aMatchDistance[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
3307 for (Standard_Integer anIt = 0; anIt < 6; ++anIt)
3309 const gp_Dir& aPlaneN = aMatchSide[anIt].Axis().Direction();
3312 aPlaneTrsf.SetTransformation (gp_Ax3(), gp_Ax3 (aBBCenter, aPlaneN));
3313 Bnd_Box aRelativeBBox = aBBox.Transformed (aPlaneTrsf);
3315 Standard_Real aDummy = 0.0;
3316 Standard_Real aZmin = 0.0;
3317 Standard_Real aZmax = 0.0;
3318 aRelativeBBox.Get (aDummy, aDummy, aZmin, aDummy, aDummy, aZmax);
3319 aMatchDistance[anIt] = -aZmin;
3321 // The center of camera is placed on the same line with center of bounding box.
3322 // The view plane section crosses the bounding box at its center.
3323 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3324 // into view section size between the point and the frustum plane.
3326 // /|\ right half of frame //
3328 // point o<-- distance * coeff -->//---- (view plane section)
3338 aMatchDistance[0] *= Sqrt(1 + Pow (Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction())), 2.0));
3339 aMatchDistance[1] *= Sqrt(1 + Pow (Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction())), 2.0));
3340 aMatchDistance[2] *= Sqrt(1 + Pow (Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction())), 2.0));
3341 aMatchDistance[3] *= Sqrt(1 + Pow (Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction())), 2.0));
3342 aMatchDistance[4] *= Sqrt(1 + Pow (Tan ( aCamDir.Angle (aFrustumNear.Axis().Direction())), 2.0));
3343 aMatchDistance[5] *= Sqrt(1 + Pow (Tan (-aCamDir.Angle (aFrustumFar.Axis().Direction())), 2.0));
3345 Standard_Real aViewSizeXv = aMatchDistance[0] + aMatchDistance[1];
3346 Standard_Real aViewSizeYv = aMatchDistance[2] + aMatchDistance[3];
3347 Standard_Real aViewSizeZv = aMatchDistance[4] + aMatchDistance[5];
3349 // Place center of camera on the same line with center of bounding
3350 // box applying corresponding projection asymmetry (if any).
3351 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3352 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3353 Standard_Real anOffsetXv = (aMatchDistance[1] - aMatchDistance[0]) * 0.5 + anAssymXv;
3354 Standard_Real anOffsetYv = (aMatchDistance[3] - aMatchDistance[2]) * 0.5 + anAssymYv;
3355 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3356 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3357 gp_Pnt aNewCenter = aBBCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3359 gp_Trsf aCenterTrsf;
3360 aCenterTrsf.SetTranslation (theCamera->Center(), aNewCenter);
3361 theCamera->Transform (aCenterTrsf);
3362 theCamera->SetDistance (Max (aMatchDistance[5] + aMatchDistance[4], Precision::Confusion()));
3364 // Bounding box collapses to a point or thin line going in depth of the screen
3365 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3367 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3369 return Standard_True; // This is just one point or line and zooming has no effect.
3372 // Looking along line and "theToEnlargeIfLine" is requested.
3373 // Fit view to see whole scene on rotation.
3374 aViewSizeXv = aViewSizeZv;
3375 aViewSizeYv = aViewSizeZv;
3378 Scale (theCamera, aViewSizeXv * (1.0 + theMargin), aViewSizeYv * (1.0 + theMargin));
3380 return Standard_True;
3383 // =======================================================================
3385 // purpose : Internal
3386 // =======================================================================
3387 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3388 const Standard_Real theSizeXv,
3389 const Standard_Real theSizeYv) const
3391 Standard_Real anAspect = theCamera->Aspect();
3392 Standard_Real aMaxSize = Max (theSizeXv / anAspect, theSizeYv);
3393 theCamera->SetScale (aMaxSize);
3396 // =======================================================================
3397 // function : Translate
3398 // purpose : Internal
3399 // =======================================================================
3400 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3401 const Standard_Real theDXv,
3402 const Standard_Real theDYv) const
3404 const gp_Pnt& aCenter = theCamera->Center();
3405 const gp_Dir& aDir = theCamera->Direction();
3406 const gp_Dir& anUp = theCamera->Up();
3407 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3409 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3410 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3411 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3413 aPanTrsf.SetTranslation (aCameraPan);
3415 theCamera->Transform (aPanTrsf);