1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 /***********************************************************************
20 HISTORIQUE DES MODIFICATIONS :
21 --------------------------------
22 00-09-92 : GG ; Creation.
23 02-10-96 : FMN ; Suppression appel Redraw sans MustBeResized()
24 05-06-97 : FMN ; Correction FitAll()
25 30-06-97 : GG ; Correction + Optimisation de Panning(...)
26 On fait la translation + le zoom en une seule
27 operation au lieu de 2 precedemment qui etait buggee.
28 09-07-97 : FMN ; Correction FitAll() sur le Ratio
29 16-07-97 : FMN ; Correction FitAll() sur le calcul de la Box
30 22-07-97 : FMN ; Ajout mode RetainMode pour le Transient
31 15-12-97 : FMN ; Ajout texture mapping
32 17-12-97 : FMN ; CTS19129 Correction FitAll() multiple
33 18-12-97 : FMN ; Ajout mode Ajout
34 24-12-97 : FMN ; Remplacement de math par MathGra
35 24-12-97 : CQO ; BUC50037 Xw_Window -> Aspect_Window
36 31-12-97 : CAL ; Remplacement de MathGra par Array2OfReal
37 07-01-98 : CAL ; Ajout de la methode DoMapping.
38 07-01-98 : CAL ; Retrait de tous les "this->" inutiles
39 21-01-98 : CAL ; Remplacement des Window->Position () par Window->Size ()
40 27-01-98 : FMN ; PERF: OPTIMISATION LOADER (LOPTIM)
41 12-02-98 : GG ; Reactivation du Redraw dans MustBeResized()
42 23-02-98 : FMN ; Remplacement PI par Standard_PI
43 25-02-98 : FMN ; PERF.27: Optimisation of view creation from existing view
44 11-03-98 : STT ; S3558
45 19-03-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
47 08-04-98 : STT ; suppr. S3558
48 10-04-98 : CAL ; Ajout des methodes RefToPix et PixToRef
49 13-06-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
50 ne marche pas. Contournement en appelant WNT_Window::Size(Int,Int).
51 16-08-98 : CAL ; S3892. Ajout grilles 3d.
52 09-09-98 : CAL ; S3892. Generalisation de TrsPoint.
53 06-10-98 : CAL ; Ajout d'un TIMER si CSF_GraphicTimer est definie.
54 16-10-98 : CAL ; Retrait d'un TIMER si CSF_GraphicTimer est definie.
55 06-11-98 : CAL ; PRO ?????. Probleme dans ZFitAll si un point dans la vue.
56 13-06-98 : FMN ; PRO14896: Correction sur la gestion de la perspective (cf Programming Guinde)
57 29-OCT-98 : DCB : Adding ScreenCopy () method.
58 10-11-99 : GG ; PRO19603 Add Redraw( area ) method
60 -> Don't increase too much the ZSize.
61 -> Initialize correctly the Z clipping and D cueing
63 IMP100701 : SZV ; Add ToPixMap() method
67 About FitAll() multiple. This probleme is caused by missing
68 precision of transformation matrices. If it is supposed that
69 projection is made in the plane (U,V), there is a difference
70 after several Zoom - compared to the exact value (cf ZoomX).
71 Don't forget that the matrices work in float and not in double.
72 To solve the problem (for lack of a better solution) I make 2 passes.
74 ************************************************************************/
76 //GER61351 //GG_15/12/99 Add SetBackgroundColor() and BackgroundColor() methods
79 #define IMP020300 //GG Don't use ZFitAll in during Rotation
80 // for perf improvment
82 #define IMP210600 //GG Avoid to have infinite loop when call Rotation() method
83 // without call before StartRotation().
84 // This problem occurs when CTRL MB3 is maintain press betwwen 2 views.
86 #define IMP250900 //GG Enable rotation around screen Z axis when
87 // rotation begin far the center of the screen.
88 // Thanks to Patrick REGINSTER (SAMTECH)
89 // GG 21/12/00 Due to a regression on the previous specifications
90 // this new functionnality is right now deactivated
91 // by default (see StartRotation(...,zRotationThreshold)
94 #define BUC60952 //GG Enable to rotate around the view axis
95 // and the required view point
97 #define RIC120302 //GG Add a NEW SetWindow method which enable
98 // to connect a graphic widget and context to OGL.
100 #define IMP260302 //GG To avoid conflicting in Window destructor
101 // nullify this handle in Remove method
103 #define OCC280 //SAV fix for FitAll problem in the perspective view.
105 #define OCC1188 //SAV Added methods to set background image
107 /*----------------------------------------------------------------------*/
112 #include <Standard_TypeMismatch.hxx>
113 #include <Standard_ShortReal.hxx>
114 #include <Standard_Assert.hxx>
115 #include <Standard_ErrorHandler.hxx>
116 #include <Standard_DivideByZero.hxx>
118 #include <Visual3d_ViewManager.hxx>
119 #include <Visual3d_Light.hxx>
120 #include <Visual3d_Layer.hxx>
123 #include <V3d_View.ixx>
124 #include <V3d_BadValue.hxx>
125 #include <V3d_StereoDumpOptions.hxx>
127 #include <Image_AlienPixMap.hxx>
129 #include <gp_Dir.hxx>
130 #include <gp_Pln.hxx>
131 #include <TColStd_Array2OfReal.hxx>
132 #include <TColStd_HSequenceOfInteger.hxx>
134 #include <Bnd_Box.hxx>
136 #include <Precision.hxx>
138 #include <Graphic3d_Structure.hxx>
139 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
140 #include <Graphic3d_MapOfStructure.hxx>
141 #include <Graphic3d_TextureEnv.hxx>
142 #include <Graphic3d_AspectMarker3d.hxx>
143 #include <Graphic3d_GraphicDriver.hxx>
146 #include <Aspect_GenericColorMap.hxx>
147 #include <Aspect_TypeMap.hxx>
148 #include <Aspect_WidthMap.hxx>
149 #include <Aspect_MarkMap.hxx>
150 #include <Aspect_FontMap.hxx>
151 #include <Aspect.hxx>
153 #define V3d_FLAG_COMPUTATION 0x00000004
156 #include <OSD_Environment.hxx>
158 /*----------------------------------------------------------------------*/
163 #define DEUXPI (2. * M_PI)
165 //=============================================================================
166 //function : Constructor
168 //=============================================================================
169 V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) :
170 MyProjModel(V3d_TPM_SCREEN),
171 MyViewer(VM.operator->()),
174 myActiveLightsIterator(),
175 SwitchSetFront(Standard_False),
177 myAutoZFitIsOn (Standard_True),
178 myAutoZFitScaleFactor (1.0)
180 myImmediateUpdate = Standard_False;
181 MyView = new Visual3d_View(MyViewer->Viewer());
183 // { Begin to retrieve the definition from ViewContext.
184 // Step MyViewContext = MyView->Context() ;
185 // to permit MyView->SetContext to compare
186 // the old and the new context.
187 // No problem for MyViewMapping, MyViewOrientation
188 // as MyView->SetViewMapping and MyView->SetViewOrientation
189 // don't try to optimize the modifications introduced to
190 // viewmapping and vieworientation.
193 if ((MyView->Context ()).AliasingIsOn ())
194 MyViewContext.SetAliasingOn ();
196 MyViewContext.SetAliasingOff ();
199 MyViewContext.SetDepthCueingBackPlane
200 ((MyView->Context ()).DepthCueingBackPlane ());
201 MyViewContext.SetDepthCueingFrontPlane
202 ((MyView->Context ()).DepthCueingFrontPlane ());
204 if ((MyView->Context ()).DepthCueingIsOn ())
205 MyViewContext.SetDepthCueingOn ();
207 MyViewContext.SetDepthCueingOff ();
210 MyViewContext.SetZClippingBackPlane
211 ((MyView->Context ()).ZClippingBackPlane ());
212 MyViewContext.SetZClippingFrontPlane
213 ((MyView->Context ()).ZClippingFrontPlane ());
215 if ((MyView->Context ()).FrontZClippingIsOn ())
216 MyViewContext.SetFrontZClippingOn ();
218 MyViewContext.SetFrontZClippingOff ();
220 if ((MyView->Context ()).BackZClippingIsOn ())
221 MyViewContext.SetBackZClippingOn ();
223 MyViewContext.SetBackZClippingOff ();
225 // Visualization and Shading Model
226 MyViewContext.SetModel ((MyView->Context ()).Model ());
227 MyViewContext.SetVisualization ((MyView->Context ()).Visualization ());
230 MyViewContext.SetSurfaceDetail (MyView->Context ().SurfaceDetail ());
231 MyViewContext.SetTextureEnv (MyView->Context ().TextureEnv ());
232 // } End of retrieval of the definition of ViewContext.
234 MyBackground = VM->GetBackgroundColor() ;
235 MyGradientBackground = VM->GetGradientBackground() ;
238 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
239 aCamera->SetFOVy (45.0);
240 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
241 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
244 SetAxis (0.,0.,0.,1.,1.,1.);
245 SetVisualization (VM->DefaultVisualization());
246 SetShadingModel (VM->DefaultShadingModel());
247 SetSurfaceDetail (VM->DefaultSurfaceDetail());
250 SetProj (VM->DefaultViewProj());
251 SetSize (VM->DefaultViewSize());
252 Standard_Real zsize = VM->DefaultViewSize();
254 SetZClippingDepth (0.);
255 SetZClippingWidth (zsize);
256 SetZCueingDepth (0.);
257 SetZCueingWidth (zsize);
258 SetDepth (VM->DefaultViewSize()/2.0);
259 SetViewMappingDefault();
260 SetViewOrientationDefault();
263 myImmediateUpdate = Standard_True;
265 aCamera->SetProjectionType ((Type == V3d_ORTHOGRAPHIC)
266 ? Graphic3d_Camera::Projection_Orthographic
267 : Graphic3d_Camera::Projection_Perspective);
269 MyTransparencyFlag = Standard_False;
272 //=============================================================================
273 //function : Constructor
275 //=============================================================================
276 V3d_View::V3d_View(const Handle(V3d_Viewer)& theVM,const Handle(V3d_View)& theView) :
277 MyProjModel(V3d_TPM_SCREEN),
278 MyViewer(theVM.operator->()),
281 myActiveLightsIterator(),
282 SwitchSetFront(Standard_False),
285 Handle(Visual3d_View) aFromView = theView->View();
287 myImmediateUpdate = Standard_False;
288 MyView = new Visual3d_View (MyViewer->Viewer());
290 for (theView->InitActiveLights(); theView->MoreActiveLights(); theView->NextActiveLights())
292 MyActiveLights.Append (theView->ActiveLight());
295 MyViewContext = aFromView->Context() ;
297 SetCamera (new Graphic3d_Camera (theView->Camera()));
298 myAutoZFitIsOn = theView->AutoZFitMode();
299 myAutoZFitScaleFactor = theView->AutoZFitScaleFactor();
301 MyBackground = aFromView->Background() ;
302 MyGradientBackground = aFromView->GradientBackground();
304 MyView->SetContext (MyViewContext) ;
306 SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
308 SetViewMappingDefault();
309 SetViewOrientationDefault();
310 theVM->AddView (this);
314 myImmediateUpdate = Standard_True;
317 //=============================================================================
318 //function : SetMagnify
320 //=============================================================================
321 void V3d_View::SetMagnify(const Handle(Aspect_Window)& TheWindow,
322 const Handle(V3d_View)& aPreviousView,
323 const Standard_Integer x1,
324 const Standard_Integer y1,
325 const Standard_Integer x2,
326 const Standard_Integer y2)
328 if( !MyView->IsDefined() ) {
329 Standard_Real a,b,c,d;
330 aPreviousView->Convert(x1,y1,a,b);
331 aPreviousView->Convert(x2,y2,c,d);
332 MyView->SetWindow(TheWindow) ;
333 FitAll(TheWindow,a,b,c,d);
334 MyView->SetContext(MyViewContext) ;
335 MyView->SetBackground(MyBackground) ;
336 MyViewer->SetViewOn(this) ;
337 MyWindow = TheWindow;
339 SetViewMappingDefault();
343 //=============================================================================
344 //function : SetWindow
346 //=============================================================================
347 void V3d_View::SetWindow(const Handle(Aspect_Window)& TheWindow)
349 Standard_MultiplyDefined_Raise_if( MyView->IsDefined(),
350 "V3d_View::SetWindow, window of view already defined");
352 MyView->SetWindow(TheWindow) ;
353 // AGV: Method V3d_View::SetWindow() should assign the field MyWindow before
354 // calling Redraw(). Otherwise it is impossible to call certain methods of
355 // V3d_View like Convert() inside the context of Redraw(),
356 // particularly in class NIS_View.
357 MyWindow = TheWindow;
358 // SetWindow carries out SetRatio and modifies
359 MyView->SetContext(MyViewContext) ;
360 MyView->SetBackground(MyBackground) ;
361 MyViewer->SetViewOn(this) ;
365 //=============================================================================
366 //function : SetWindow
368 //=============================================================================
369 void V3d_View::SetWindow(const Handle(Aspect_Window)& aWindow,
370 const Aspect_RenderingContext aContext,
371 const Aspect_GraphicCallbackProc& aDisplayCB,
372 const Standard_Address aClientData)
374 Standard_MultiplyDefined_Raise_if( MyView->IsDefined(),
375 "V3d_View::SetWindow, "
376 "window of view already defined");
377 // AGV: Method V3d_View::SetWindow() should assign the field MyWindow before
378 // calling Redraw(). Otherwise it is impossible to call certain methods of
379 // V3d_View like Convert() inside the context of Redraw(),
380 // particularly in class NIS_View.
382 MyView->SetWindow(aWindow, aContext, aDisplayCB, aClientData) ;
383 MyView->SetContext(MyViewContext) ;
384 MyView->SetBackground(MyBackground) ;
385 MyViewer->SetViewOn(this) ;
389 //=============================================================================
392 //=============================================================================
393 void V3d_View::Remove() const
395 MyViewer->DelView (this);
397 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
401 //=============================================================================
404 //=============================================================================
405 void V3d_View::Update() const
407 if( MyView->IsDefined() ) MyView->Update() ;
410 //=============================================================================
413 //=============================================================================
414 void V3d_View::Redraw() const
416 if( MyView->IsDefined() ) MyView->Redraw() ;
419 //=============================================================================
420 //function : RedrawImmediate
422 //=============================================================================
423 void V3d_View::RedrawImmediate() const
425 if (MyView->IsDefined())
427 MyView->RedrawImmediate();
431 //=============================================================================
432 //function : Invalidate
434 //=============================================================================
435 void V3d_View::Invalidate() const
437 if (MyView->IsDefined())
439 MyView->Invalidate();
443 //=============================================================================
446 //=============================================================================
447 void V3d_View::Redraw(const Standard_Integer xc,const Standard_Integer yc,
448 const Standard_Integer width,const Standard_Integer height) const
450 if( MyView->IsDefined() ) MyView->Redraw(xc,yc,width,height) ;
453 //=============================================================================
456 //=============================================================================
457 Standard_Boolean V3d_View::IsEmpty() const
459 Standard_Boolean TheStatus = Standard_True ;
460 if( MyView->IsDefined() ) {
461 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
462 if( Nstruct > 0 ) TheStatus = Standard_False ;
467 //=============================================================================
468 //function : UpdateLights
470 //=============================================================================
471 void V3d_View::UpdateLights() const
473 MyView->SetContext(MyViewContext);
477 //=============================================================================
478 //function : DoMapping
480 //=============================================================================
481 void V3d_View::DoMapping()
483 if( MyView->IsDefined() ) {
484 (MyView->Window())->DoMapping() ;
488 //=============================================================================
489 //function : MustBeResized
491 //=============================================================================
492 void V3d_View::MustBeResized()
494 if ( !MyLayerMgr.IsNull() )
495 MyLayerMgr->Resized();
497 if( MyView->IsDefined() ) {
503 //=============================================================================
504 //function : SetBackgroundColor
506 //=============================================================================
507 void V3d_View::SetBackgroundColor(const Quantity_TypeOfColor Type, const Standard_Real v1, const Standard_Real v2, const Standard_Real v3)
509 Standard_Real V1 = Max( Min( v1, 1.0 ), 0.0 );
510 Standard_Real V2 = Max( Min( v2, 1.0 ), 0.0 );
511 Standard_Real V3 = Max( Min( v3, 1.0 ), 0.0 );
513 Quantity_Color C( V1, V2, V3, Type );
514 SetBackgroundColor( C );
517 //=============================================================================
518 //function : SetBackgroundColor
520 //=============================================================================
521 void V3d_View::SetBackgroundColor(const Quantity_Color &Color)
523 MyBackground.SetColor( Color );
524 if ( MyView->IsDefined() )
525 MyView->SetBackground( MyBackground );
527 if ( !MyLayerMgr.IsNull() )
528 MyLayerMgr->Resized();
531 //=============================================================================
532 //function : SetBackgroundColor
534 //=============================================================================
535 void V3d_View::SetBackgroundColor(const Quantity_NameOfColor Name)
537 Quantity_Color C( Name );
538 SetBackgroundColor( C );
541 //=============================================================================
542 //function : SetBgGradientColors
544 //=============================================================================
545 void V3d_View::SetBgGradientColors( const Quantity_Color& Color1,
546 const Quantity_Color& Color2,
547 const Aspect_GradientFillMethod FillStyle,
548 const Standard_Boolean status)
550 MyGradientBackground.SetColors(Color1, Color2, FillStyle);
551 if ( MyView->IsDefined() )
552 MyView->SetGradientBackground( MyGradientBackground, status );
555 //=============================================================================
556 //function : SetBgGradientColors
558 //=============================================================================
559 void V3d_View::SetBgGradientColors( const Quantity_NameOfColor Color1,
560 const Quantity_NameOfColor Color2,
561 const Aspect_GradientFillMethod FillStyle,
562 const Standard_Boolean status )
564 Quantity_Color C1( Color1 );
565 Quantity_Color C2( Color2 );
566 MyGradientBackground.SetColors( C1, C2, FillStyle );
567 if ( MyView->IsDefined() )
568 MyView->SetGradientBackground( MyGradientBackground, status );
571 //=============================================================================
572 //function : SetBgGradientStyle
574 //=============================================================================
575 void V3d_View::SetBgGradientStyle( const Aspect_GradientFillMethod FillStyle,
576 const Standard_Boolean update)
578 Quantity_Color Color1, Color2;
579 MyGradientBackground.Colors( Color1, Color2 );
580 MyGradientBackground.SetColors( Color1, Color2, FillStyle );
581 if( MyView->IsDefined() )
582 MyView->SetBgGradientStyle( FillStyle, update ) ;
585 //=============================================================================
586 //function : SetBackgroundImage
588 //=============================================================================
589 void V3d_View::SetBackgroundImage( const Standard_CString FileName,
590 const Aspect_FillMethod FillStyle,
591 const Standard_Boolean update )
594 if( MyView->IsDefined() )
595 MyView->SetBackgroundImage( FileName, FillStyle, update ) ;
599 //=============================================================================
600 //function : SetBgImageStyle
602 //=============================================================================
603 void V3d_View::SetBgImageStyle( const Aspect_FillMethod FillStyle,
604 const Standard_Boolean update )
607 if( MyView->IsDefined() )
608 MyView->SetBgImageStyle( FillStyle, update ) ;
612 //=============================================================================
615 //=============================================================================
616 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)
618 Standard_Real D,Nx = Vx,Ny = Vy,Nz = Vz ;
620 D = Sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) ;
621 V3d_BadValue_Raise_if ( D <= 0. , "V3d_View::SetAxis, bad axis");
622 Nx /= D ; Ny /= D ; Nz /= D ;
623 MyDefaultViewPoint.SetCoord(X,Y,Z) ;
624 MyDefaultViewAxis.SetCoord(Nx,Ny,Nz) ;
627 //=============================================================================
628 //function : SetShadingModel
630 //=============================================================================
631 void V3d_View::SetShadingModel(const V3d_TypeOfShadingModel Model)
633 MyViewContext.SetModel((Visual3d_TypeOfModel) Model) ;
634 MyView->SetContext(MyViewContext) ;
637 //=============================================================================
638 //function : SetSurfaceDetail
640 //=============================================================================
641 void V3d_View::SetSurfaceDetail(const V3d_TypeOfSurfaceDetail Model)
643 MyViewContext.SetSurfaceDetail((Visual3d_TypeOfSurfaceDetail) Model) ;
644 MyView->SetContext(MyViewContext) ;
647 //=============================================================================
648 //function : SetTextureEnv
650 //=============================================================================
651 void V3d_View::SetTextureEnv(const Handle(Graphic3d_TextureEnv)& ATexture)
653 MyViewContext.SetTextureEnv(ATexture) ;
654 MyView->SetContext(MyViewContext) ;
657 //=============================================================================
658 //function : SetVisualization
660 //=============================================================================
661 void V3d_View::SetVisualization(const V3d_TypeOfVisualization Mode)
663 MyViewContext.SetVisualization((Visual3d_TypeOfVisualization) Mode);
664 MyView->SetContext(MyViewContext) ;
667 //=============================================================================
668 //function : SetFront
670 //=============================================================================
671 void V3d_View::SetFront()
673 gp_Ax3 a = MyViewer->PrivilegedPlane();
674 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
676 a.Direction().Coord(vx,vy,vz);
677 a.YDirection().Coord(xu,yu,zu);
678 a.Location().Coord(xo,yo,zo);
680 myCamera->SetCenter (gp_Pnt (xo, yo, zo));
682 myCamera->SetDirection (gp_Dir (vx, vy, vz));
684 myCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
685 myCamera->SetUp (gp_Dir (xu, yu, zu));
689 SwitchSetFront = !SwitchSetFront;
694 //=============================================================================
697 //=============================================================================
698 void V3d_View::Rotate (const Standard_Real ax,
699 const Standard_Real ay,
700 const Standard_Real az,
701 const Standard_Boolean Start)
703 Standard_Real Ax = ax;
704 Standard_Real Ay = ay;
705 Standard_Real Az = az;
707 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
708 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
709 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
710 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
711 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
712 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
716 myCamStartOpUp = myCamera->Up();
717 myCamStartOpEye = myCamera->Eye();
718 myCamStartOpCenter = myCamera->Center();
721 myCamera->SetUp (myCamStartOpUp);
722 myCamera->SetEye (myCamStartOpEye);
723 myCamera->SetCenter (myCamStartOpCenter);
725 // rotate camera around 3 initial axes
726 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
727 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
728 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
729 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
731 gp_Trsf aRot[3], aTrsf;
732 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
733 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
734 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
735 aTrsf.Multiply (aRot[0]);
736 aTrsf.Multiply (aRot[1]);
737 aTrsf.Multiply (aRot[2]);
739 myCamera->Transform (aTrsf);
746 //=============================================================================
749 //=============================================================================
750 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
751 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
754 Standard_Real Ax = ax ;
755 Standard_Real Ay = ay ;
756 Standard_Real Az = az ;
758 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
759 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
760 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
761 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
762 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
763 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
767 myGravityReferencePoint.SetCoord (X, Y, Z);
768 myCamStartOpUp = myCamera->Up();
769 myCamStartOpEye = myCamera->Eye();
770 myCamStartOpCenter = myCamera->Center();
773 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
775 myCamera->SetUp (myCamStartOpUp);
776 myCamera->SetEye (myCamStartOpEye);
777 myCamera->SetCenter (myCamStartOpCenter);
779 // rotate camera around 3 initial axes
780 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
782 gp_Dir aZAxis (myCamera->Direction().Reversed());
783 gp_Dir aYAxis (myCamera->Up());
784 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
786 gp_Trsf aRot[3], aTrsf;
787 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
788 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
789 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
790 aTrsf.Multiply (aRot[0]);
791 aTrsf.Multiply (aRot[1]);
792 aTrsf.Multiply (aRot[2]);
794 myCamera->Transform (aTrsf);
801 //=============================================================================
804 //=============================================================================
805 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
809 Rotate(angle,0.,0.,Start);
812 Rotate(0.,angle,0.,Start);
815 Rotate(0.,0.,angle,Start);
820 //=============================================================================
823 //=============================================================================
824 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
825 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
827 Standard_Real Angle = angle ;
829 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
830 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
834 myGravityReferencePoint.SetCoord (X, Y, Z);
835 myCamStartOpUp = myCamera->Up();
836 myCamStartOpEye = myCamera->Eye();
837 myCamStartOpCenter = myCamera->Center();
841 myViewAxis.SetCoord(1.,0.,0.) ;
844 myViewAxis.SetCoord(0.,1.,0.) ;
847 myViewAxis.SetCoord(0.,0.,1.) ;
851 myCamStartOpUp = myCamera->Up();
852 myCamStartOpEye = myCamera->Eye();
853 myCamStartOpCenter = myCamera->Center();
856 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
858 myCamera->SetUp (myCamStartOpUp);
859 myCamera->SetEye (myCamStartOpEye);
860 myCamera->SetCenter (myCamStartOpCenter);
862 // rotate camera around passed axis
864 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
865 gp_Dir aRAxis ((Axe == V3d_X) ? 1.0 : 0.0,
866 (Axe == V3d_Y) ? 1.0 : 0.0,
867 (Axe == V3d_Z) ? 1.0 : 0.0);
869 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
870 myCamera->Transform (aRotation);
877 //=============================================================================
880 //=============================================================================
881 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
883 Standard_Real Angle = angle;
885 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
886 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
889 myCamStartOpUp = myCamera->Up();
890 myCamStartOpEye = myCamera->Eye();
891 myCamStartOpCenter = myCamera->Center();
894 const Graphic3d_Vertex& aPnt = MyDefaultViewPoint;
895 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
897 myCamera->SetUp (myCamStartOpUp);
898 myCamera->SetEye (myCamStartOpEye);
899 myCamera->SetCenter (myCamStartOpCenter);
902 gp_Pnt aRCenter (aPnt.X(), aPnt.Y(), aPnt.Z());
903 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
904 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
905 myCamera->Transform (aRotation);
912 //=============================================================================
915 //=============================================================================
916 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
918 Standard_Real Ax = ax;
919 Standard_Real Ay = ay;
920 Standard_Real Az = az;
922 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
923 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
924 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
925 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
926 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
927 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
930 myCamStartOpUp = myCamera->Up();
931 myCamStartOpEye = myCamera->Eye();
932 myCamStartOpCenter = myCamera->Center();
935 myCamera->SetUp (myCamStartOpUp);
936 myCamera->SetEye (myCamStartOpEye);
937 myCamera->SetCenter (myCamStartOpCenter);
939 // rotate camera around 3 initial axes
940 gp_Pnt aRCenter = myCamera->Eye();
941 gp_Dir aZAxis (myCamera->Direction().Reversed());
942 gp_Dir aYAxis (myCamera->Up());
943 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
945 gp_Trsf aRot[3], aTrsf;
946 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
947 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
948 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
949 aTrsf.Multiply (aRot[0]);
950 aTrsf.Multiply (aRot[1]);
951 aTrsf.Multiply (aRot[2]);
953 myCamera->Transform (aTrsf);
960 //=============================================================================
963 //=============================================================================
964 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
968 Turn(angle,0.,0.,Start);
971 Turn(0.,angle,0.,Start);
974 Turn(0.,0.,angle,Start);
979 //=============================================================================
982 //=============================================================================
983 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
985 Standard_Real Angle = angle ;
987 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
988 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
991 myCamStartOpUp = myCamera->Up();
992 myCamStartOpEye = myCamera->Eye();
993 myCamStartOpCenter = myCamera->Center();
996 myCamera->SetUp (myCamStartOpUp);
997 myCamera->SetEye (myCamStartOpEye);
998 myCamera->SetCenter (myCamStartOpCenter);
1000 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
1003 gp_Pnt aRCenter = myCamera->Eye();
1004 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
1005 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
1006 myCamera->Transform (aRotation);
1013 //=============================================================================
1014 //function : SetTwist
1016 //=============================================================================
1017 void V3d_View::SetTwist(const Standard_Real angle)
1019 Standard_Real Angle = angle ;
1020 Standard_Boolean TheStatus;
1022 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
1023 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
1025 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1028 anUp = gp_Dir (0.0, 0.0, 1.0);
1030 TheStatus = ScreenAxis(aReferencePlane, anUp,
1031 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1033 anUp = gp_Dir (0.0, 1.0, 0.0);
1034 TheStatus = ScreenAxis(aReferencePlane, anUp,
1035 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1038 anUp = gp_Dir (1.0, 0.0, 0.0);
1039 TheStatus = ScreenAxis(aReferencePlane, anUp,
1040 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1043 V3d_BadValue_Raise_if( !TheStatus,"V3d_ViewSetTwist, alignment of Eye,At,Up,");
1045 gp_Pnt aRCenter = myCamera->Center();
1046 gp_Dir aZAxis (myCamera->Direction().Reversed());
1049 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
1051 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1052 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1054 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1055 myCamera->Transform (aTrsf);
1062 //=============================================================================
1063 //function : SetAutoZFitMode
1065 //=============================================================================
1066 void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn, const Standard_Real theScaleFactor)
1068 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
1069 myAutoZFitScaleFactor = theScaleFactor;
1070 myAutoZFitIsOn = theIsOn;
1073 //=============================================================================
1074 //function : AutoZFitMode
1076 //=============================================================================
1077 Standard_Boolean V3d_View::AutoZFitMode() const
1079 return myAutoZFitIsOn;
1082 //=============================================================================
1083 //function : AutoZFitScaleFactor
1085 //=============================================================================
1086 Standard_Real V3d_View::AutoZFitScaleFactor () const
1088 return myAutoZFitScaleFactor;
1091 //=============================================================================
1094 //=============================================================================
1095 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1097 Standard_Real aTwistBefore = Twist();
1099 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1101 myCamera->SetEye (gp_Pnt (X, Y, Z));
1102 SetTwist (aTwistBefore);
1106 SetImmediateUpdate (wasUpdateEnabled);
1111 //=============================================================================
1112 //function : SetDepth
1114 //=============================================================================
1115 void V3d_View::SetDepth(const Standard_Real Depth)
1117 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1121 // Move eye using center (target) as anchor.
1122 myCamera->SetDistance (Depth);
1126 // Move the view ref point instead of the eye.
1127 gp_Vec aDir (myCamera->Direction());
1128 gp_Pnt aCameraEye = myCamera->Eye();
1129 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1131 myCamera->SetCenter (aCameraCenter);
1139 //=============================================================================
1140 //function : SetProj
1142 //=============================================================================
1143 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1145 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1146 "V3d_View::SetProj, null projection vector");
1148 Standard_Real aTwistBefore = Twist();
1150 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1152 myCamera->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1154 if (MyProjModel == V3d_TPM_SCREEN)
1156 SetTwist(aTwistBefore);
1161 SetImmediateUpdate (wasUpdateEnabled);
1166 //=============================================================================
1167 //function : SetProj
1169 //=============================================================================
1170 void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1172 Standard_Real Xpn=0;
1173 Standard_Real Ypn=0;
1174 Standard_Real Zpn=0;
1176 switch (Orientation) {
1187 const Graphic3d_Vector& aBck = V3d::GetProjAxis (Orientation);
1189 // retain camera panning from origin when switching projection
1190 gp_Pnt anOriginVCS = myCamera->ConvertWorld2View (gp::Origin());
1191 Standard_Real aPanX = anOriginVCS.X();
1192 Standard_Real aPanY = anOriginVCS.Y();
1194 myCamera->SetCenter (gp_Pnt (0, 0, 0));
1195 myCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1196 myCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
1197 myCamera->OrthogonalizeUp();
1199 Panning (aPanX, aPanY);
1206 //=============================================================================
1209 //=============================================================================
1210 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1212 Standard_Real aTwistBefore = Twist();
1214 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1216 myCamera->SetCenter (gp_Pnt (X, Y, Z));
1218 SetTwist (aTwistBefore);
1222 SetImmediateUpdate (wasUpdateEnabled);
1227 //=============================================================================
1230 //=============================================================================
1231 void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standard_Real Vz)
1233 Standard_Boolean TheStatus ;
1234 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0. ,
1235 "V3d_View::SetUp, nullUp vector");
1237 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1238 gp_Dir anUp (Vx, Vy, Vz);
1240 TheStatus = ScreenAxis(aReferencePlane,anUp,
1241 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1243 anUp = gp_Dir (0.0, 0.0, 1.0);
1244 TheStatus = ScreenAxis(aReferencePlane,anUp,
1245 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1248 anUp = gp_Dir (0.0, 1.0, 0.0);
1249 TheStatus = ScreenAxis(aReferencePlane,anUp,
1250 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1253 anUp = gp_Dir (1.0, 0.0, 0.0);
1254 TheStatus = ScreenAxis(aReferencePlane,anUp,
1255 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1257 V3d_BadValue_Raise_if( !TheStatus,"V3d_View::Setup, alignment of Eye,At,Up");
1259 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1260 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1262 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1269 //=============================================================================
1272 //=============================================================================
1273 void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
1275 Standard_Boolean TheStatus ;
1277 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1280 const Graphic3d_Vector& aViewReferenceUp = V3d::GetProjAxis(Orientation) ;
1281 anUp = gp_Dir (aViewReferenceUp.X(), aViewReferenceUp.Y(), aViewReferenceUp.Z());
1283 TheStatus = ScreenAxis(aReferencePlane,anUp,
1284 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1286 anUp = gp_Dir (0.,0.,1.);
1287 TheStatus = ScreenAxis(aReferencePlane,anUp,
1288 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1291 anUp = gp_Dir (0.,1.,0.);
1292 TheStatus = ScreenAxis(aReferencePlane,anUp,
1293 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1296 anUp = gp_Dir (1.,0.,0.);
1297 TheStatus = ScreenAxis(aReferencePlane,anUp,
1298 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1300 V3d_BadValue_Raise_if( !TheStatus, "V3d_View::SetUp, alignment of Eye,At,Up");
1302 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1303 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1305 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1312 //=============================================================================
1313 //function : SetViewOrientationDefault
1315 //=============================================================================
1316 void V3d_View::SetViewOrientationDefault()
1318 MyView->SetViewOrientationDefault() ;
1323 //=============================================================================
1324 //function : ResetViewOrientation
1326 //=============================================================================
1327 void V3d_View::ResetViewOrientation()
1329 MyView->ViewOrientationReset() ;
1334 //=============================================================================
1337 //=============================================================================
1338 void V3d_View::Reset( const Standard_Boolean update )
1340 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1342 if (!aDefaultCamera.IsNull())
1344 myCamera->CopyMappingData (aDefaultCamera);
1345 myCamera->CopyOrientationData (aDefaultCamera);
1350 SwitchSetFront = Standard_False;
1352 if( !myImmediateUpdate && update ) Update();
1355 //=======================================================================
1356 //function : SetCenter
1358 //=======================================================================
1359 void V3d_View::SetCenter (const Standard_Integer theXp,
1360 const Standard_Integer theYp)
1362 Standard_Real aXv, aYv;
1363 Convert (theXp, theYp, aXv, aYv);
1364 Translate (myCamera, aXv, aYv);
1369 //=============================================================================
1370 //function : SetSize
1372 //=============================================================================
1373 void V3d_View::SetSize (const Standard_Real theSize)
1375 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1377 myCamera->SetScale (myCamera->Aspect() >= 1.0 ? theSize / myCamera->Aspect() : theSize);
1384 //=============================================================================
1385 //function : SetZSize
1387 //=============================================================================
1388 void V3d_View::SetZSize(const Standard_Real Size)
1390 Standard_Real Zmax = Size/2.;
1392 Standard_Real aDistance = myCamera->Distance();
1398 Standard_Real Front = MyViewContext.ZClippingFrontPlane();
1399 Standard_Real Back = MyViewContext.ZClippingBackPlane();
1401 // ShortReal precision factor used to add meaningful tolerance to
1402 // ZNear, ZFar values in order to avoid equality after type conversion
1403 // to ShortReal matrices type.
1404 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1406 Standard_Real aZFar = Zmax + aDistance * 2.0;
1407 Standard_Real aZNear = -Zmax + aDistance;
1408 aZNear -= Abs (aZNear) * aPrecision;
1409 aZFar += Abs (aZFar) * aPrecision;
1411 if (!myCamera->IsOrthographic())
1413 if (aZFar < aPrecision)
1415 // Invalid case when both values are negative
1416 aZNear = aPrecision;
1417 aZFar = aPrecision * 2.0;
1419 else if (aZNear < Abs (aZFar) * aPrecision)
1421 // Z is less than 0.0, try to fix it using any appropriate z-scale
1422 aZNear = Abs (aZFar) * aPrecision;
1426 // If range is too small
1427 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1429 aZFar = aZNear + Abs (aZFar) * aPrecision;
1432 myCamera->SetZRange (aZNear, aZFar);
1434 if (MyViewContext.FrontZClippingIsOn() ||
1435 MyViewContext.BackZClippingIsOn())
1437 MyViewContext.SetZClippingFrontPlane (Front);
1438 MyViewContext.SetZClippingBackPlane (Back);
1439 MyView->SetContext (MyViewContext);
1443 //=============================================================================
1444 //function : SetZoom
1446 //=============================================================================
1447 void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1449 V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
1453 myCamStartOpEye = myCamera->Eye();
1454 myCamStartOpCenter = myCamera->Center();
1457 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
1458 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
1460 // ensure that zoom will not be too small or too big
1461 Standard_Real coef = Coef;
1462 if (aViewWidth < coef * Precision::Confusion())
1464 coef = aViewWidth / Precision::Confusion();
1466 else if (aViewWidth > coef * 1e12)
1468 coef = aViewWidth / 1e12;
1470 if (aViewHeight < coef * Precision::Confusion())
1472 coef = aViewHeight / Precision::Confusion();
1474 else if (aViewHeight > coef * 1e12)
1476 coef = aViewHeight / 1e12;
1479 myCamera->SetEye (myCamStartOpEye);
1480 myCamera->SetCenter (myCamStartOpCenter);
1481 myCamera->SetScale (myCamera->Scale() / Coef);
1487 //=============================================================================
1488 //function : SetScale
1490 //=============================================================================
1491 void V3d_View::SetScale( const Standard_Real Coef )
1493 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1495 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1497 // Strange behavior for the sake of compatibility.
1498 if (!aDefaultCamera.IsNull())
1500 myCamera->SetAspect (aDefaultCamera->Aspect());
1501 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1502 myCamera->SetScale (aDefaultScale / Coef);
1506 myCamera->SetScale (myCamera->Scale() / Coef);
1514 //=============================================================================
1515 //function : SetAxialScale
1517 //=============================================================================
1518 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1520 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1522 myCamera->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1526 //=============================================================================
1529 //=============================================================================
1530 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1532 Standard_ASSERT_RAISE (theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1534 if (MyView->NumberOfDisplayedStructures() == 0)
1539 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
1540 MyView->MinMaxValues (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1541 gp_XYZ aMin (aXmin, aYmin, aZmin);
1542 gp_XYZ aMax (aXmax, aYmax, aZmax);
1544 if (!FitMinMax (myCamera, aMin, aMax, theMargin, 10.0 * Precision::Confusion()))
1551 if (myImmediateUpdate || theToUpdate)
1557 //=============================================================================
1558 //function : AutoZFit
1560 //=============================================================================
1561 void V3d_View::AutoZFit()
1563 if (!AutoZFitMode())
1568 ZFitAll (myAutoZFitScaleFactor);
1571 //=============================================================================
1572 //function : ZFitAll
1574 //=============================================================================
1575 void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
1577 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
1579 // Method changes ZNear and ZFar planes of camera so as to fit the graphical structures
1580 // by their real boundaries (computed ignoring infinite flag) into the viewing volume.
1581 // In addition to the graphical boundaries, the usual min max used for fitting perspective
1582 // camera. To avoid numeric errors for perspective camera the negative ZNear values are
1583 // fixed using tolerance distance, relative to boundaries size. The tolerance distance
1584 // should be computed using information on boundaries of primary application actors,
1585 // (e.g. representing the displayed model) - to ensure that they are not unreasonably clipped.
1587 Standard_Real aMinMax[6]; // applicative min max boundaries
1588 View()->MinMaxValues (aMinMax[0], aMinMax[1], aMinMax[2],
1589 aMinMax[3], aMinMax[4], aMinMax[5],
1592 Standard_Real aGraphicBB[6]; // real graphical boundaries (not accounting infinite flag).
1593 View()->MinMaxValues (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2],
1594 aGraphicBB[3], aGraphicBB[4], aGraphicBB[5],
1597 // Check if anything can be adjusted
1598 Standard_Real aLim = (ShortRealLast() - 1.0);
1599 if (Abs (aGraphicBB[0]) > aLim || Abs (aGraphicBB[1]) > aLim || Abs (aGraphicBB[2]) > aLim ||
1600 Abs (aGraphicBB[3]) > aLim || Abs (aGraphicBB[4]) > aLim || Abs (aGraphicBB[5]) > aLim)
1607 // Measure depth of boundary points from camera eye
1608 gp_Pnt aPntsToMeasure[16] =
1610 gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[2]),
1611 gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[5]),
1612 gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[2]),
1613 gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[5]),
1614 gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[2]),
1615 gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[5]),
1616 gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[2]),
1617 gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[5]),
1619 gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2]),
1620 gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[5]),
1621 gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[2]),
1622 gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[5]),
1623 gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[2]),
1624 gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[5]),
1625 gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[2]),
1626 gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[5])
1630 gp_Dir aCamDir = myCamera->Direction();
1631 gp_Pnt aCamEye = myCamera->Eye();
1632 gp_Pln aCamPln (aCamEye, aCamDir);
1634 Standard_Real aModelMinDist = RealLast();
1635 Standard_Real aModelMaxDist = RealFirst();
1636 Standard_Real aGraphicMinDist = RealLast();
1637 Standard_Real aGraphicMaxDist = RealFirst();
1639 const gp_XYZ& anAxialScale = myCamera->AxialScale();
1641 // Get minimum and maximum distances to the eye plane
1642 for (Standard_Integer aPntIt = 0; aPntIt < 16; ++aPntIt)
1644 gp_Pnt aMeasurePnt = aPntsToMeasure[aPntIt];
1646 if (Abs (aMeasurePnt.X()) > aLim || Abs (aMeasurePnt.Y()) > aLim || Abs (aMeasurePnt.Z()) > aLim)
1651 aMeasurePnt = gp_Pnt (aMeasurePnt.X() * anAxialScale.X(),
1652 aMeasurePnt.Y() * anAxialScale.Y(),
1653 aMeasurePnt.Z() * anAxialScale.Z());
1655 Standard_Real aDistance = aCamPln.Distance (aMeasurePnt);
1657 // Check if the camera is intruded into the scene
1658 if (aCamDir.IsOpposite (gp_Vec (aCamEye, aMeasurePnt), M_PI * 0.5))
1663 Standard_Real& aChangeMinDist = aPntIt >= 8 ? aGraphicMinDist : aModelMinDist;
1664 Standard_Real& aChangeMaxDist = aPntIt >= 8 ? aGraphicMaxDist : aModelMaxDist;
1665 aChangeMinDist = Min (aDistance, aChangeMinDist);
1666 aChangeMaxDist = Max (aDistance, aChangeMaxDist);
1669 // Compute depth of bounding box center
1670 Standard_Real aMidDepth = (aGraphicMinDist + aGraphicMaxDist) * 0.5;
1671 Standard_Real aHalfDepth = (aGraphicMaxDist - aGraphicMinDist) * 0.5;
1673 // ShortReal precision factor used to add meaningful tolerance to
1674 // ZNear, ZFar values in order to avoid equality after type conversion
1675 // to ShortReal matrices type.
1676 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1678 // Compute enlarged or shrank near and far z ranges
1679 Standard_Real aZNear = aMidDepth - aHalfDepth * theScaleFactor;
1680 Standard_Real aZFar = aMidDepth + aHalfDepth * theScaleFactor;
1681 aZNear -= Abs (aZNear) * aPrecision;
1682 aZFar += Abs (aZFar) * aPrecision;
1684 if (!myCamera->IsOrthographic())
1686 if (aZFar >= aPrecision)
1688 // To avoid numeric errors... (See comments in the beginning of the method).
1689 // Choose between model distance and graphical distance, as the model boundaries
1690 // might be infinite if all structures have infinite flag.
1691 const Standard_Real aGraphicDepth = aGraphicMaxDist >= aGraphicMinDist
1692 ? aGraphicMaxDist - aGraphicMinDist : RealLast();
1694 const Standard_Real aModelDepth = aModelMaxDist >= aModelMinDist
1695 ? aModelMaxDist - aModelMinDist : RealLast();
1697 const Standard_Real aMinDepth = Min (aModelDepth, aGraphicDepth);
1698 const Standard_Real aZTolerance =
1699 Max (Abs (aMinDepth) * aPrecision, aPrecision);
1701 if (aZNear < aZTolerance)
1703 aZNear = aZTolerance;
1706 else // aZFar < aPrecision - Invalid case when both ZNear and ZFar are negative
1708 aZNear = aPrecision;
1709 aZFar = aPrecision * 2.0;
1713 // If range is too small
1714 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1716 aZFar = aZNear + Abs (aZFar) * aPrecision;
1719 myCamera->SetZRange (aZNear, aZFar);
1724 //=============================================================================
1725 //function : DepthFitAll
1727 //=============================================================================
1728 void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1729 const Quantity_Coefficient Margin)
1731 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1732 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1733 Standard_Real Dx,Dy,Dz,Size;
1735 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1737 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1742 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
1744 Standard_Real LIM = ShortRealLast() -1.;
1745 if (Abs(Xmin) > LIM || Abs(Ymin) > LIM || Abs(Zmin) > LIM
1746 || Abs(Xmax) > LIM || Abs(Ymax) > LIM || Abs(Zmax) > LIM ) {
1751 if (Xmin == Xmax && Ymin == Ymax && Zmin == Zmax) {
1755 MyView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
1756 MyView->Projects(Xmax,Ymax,Zmax,U1,V1,W1) ;
1757 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1758 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1759 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1760 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
1761 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1762 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1763 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1764 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
1765 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1766 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1767 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1768 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
1769 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1770 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1771 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1772 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
1773 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1774 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1775 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1776 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
1777 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1778 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1779 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1780 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
1781 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1782 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1783 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1786 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1787 Dz = 2.*Wmax + Margin * Wmax;
1789 // Compute depth value
1790 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1791 Dx += Margin * Dx; Dy += Margin * Dy;
1792 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1795 SetDepth( Aspect * Size / 2.);
1801 //=============================================================================
1804 //=============================================================================
1805 void V3d_View::FitAll(const Standard_Real theMinXv,
1806 const Standard_Real theMinYv,
1807 const Standard_Real theMaxXv,
1808 const Standard_Real theMaxYv)
1810 FitAll (MyWindow, theMinXv, theMinYv, theMaxXv, theMaxYv);
1813 //=============================================================================
1814 //function : WindowFitAll
1816 //=============================================================================
1817 void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1818 const Standard_Integer Ymin,
1819 const Standard_Integer Xmax,
1820 const Standard_Integer Ymax)
1822 WindowFit(Xmin,Ymin,Xmax,Ymax);
1825 //=======================================================================
1826 //function : WindowFit
1828 //=======================================================================
1829 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1830 const Standard_Integer theMinYp,
1831 const Standard_Integer theMaxXp,
1832 const Standard_Integer theMaxYp)
1834 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1836 if (!myCamera->IsOrthographic())
1838 // normalize view coordiantes
1839 Standard_Integer aWinWidth, aWinHeight;
1840 MyWindow->Size (aWinWidth, aWinHeight);
1842 // z coordinate of camera center
1843 Standard_Real aDepth = myCamera->Project (myCamera->Center()).Z();
1845 // camera projection coordinate are in NDC which are normalized [-1, 1]
1846 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1847 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1848 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1849 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1851 // compute camera panning
1852 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1853 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1854 gp_Pnt aPanTo = myCamera->ConvertProj2View (aFitCenter);
1855 gp_Pnt aPanFrom = myCamera->ConvertProj2View (aScreenCenter);
1856 gp_Vec aPanVec (aPanFrom, aPanTo);
1858 // compute section size
1859 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1860 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1861 gp_Pnt aViewBotLeft = myCamera->ConvertProj2View (aFitBotLeft);
1862 gp_Pnt aViewTopRight = myCamera->ConvertProj2View (aFitTopRight);
1864 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1865 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1867 Translate (myCamera, aPanVec.X(), -aPanVec.Y());
1868 Scale (myCamera, aUSize, aVSize);
1873 Standard_Real aX1, aY1, aX2, aY2;
1874 Convert (theMinXp, theMinYp, aX1, aY1);
1875 Convert (theMaxXp, theMaxYp, aX2, aY2);
1876 FitAll (aX1, aY1, aX2, aY2);
1879 SetImmediateUpdate (wasUpdateEnabled);
1884 //=======================================================================
1885 //function : SetViewMappingDefault
1887 //=======================================================================
1888 void V3d_View::SetViewMappingDefault()
1890 MyView->SetViewMappingDefault();
1895 //=======================================================================
1896 //function : ResetViewMapping
1898 //=======================================================================
1899 void V3d_View::ResetViewMapping()
1901 MyView->ViewMappingReset();
1906 //=======================================================================
1907 //function : ConvertToGrid
1909 //=======================================================================
1910 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1911 const Standard_Integer Yp,
1914 Standard_Real& Zg) const
1916 Graphic3d_Vertex aVrp;
1917 Standard_Real anX, anY, aZ;
1918 Convert (Xp, Yp, anX, anY, aZ);
1919 aVrp.SetCoord (anX, anY, aZ);
1921 if( MyViewer->Grid()->IsActive() ) {
1922 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1923 aNewVrp.Coord (Xg,Yg,Zg) ;
1925 aVrp.Coord (Xg,Yg,Zg) ;
1928 //=======================================================================
1929 //function : ConvertToGrid
1931 //=======================================================================
1932 void V3d_View::ConvertToGrid(const Standard_Real X,
1933 const Standard_Real Y,
1934 const Standard_Real Z,
1937 Standard_Real& Zg) const
1939 if( MyViewer->Grid()->IsActive() ) {
1940 Graphic3d_Vertex aVrp (X,Y,Z) ;
1941 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1942 aNewVrp.Coord(Xg,Yg,Zg) ;
1944 Xg = X; Yg = Y; Zg = Z;
1948 //=======================================================================
1949 //function : Convert
1951 //=======================================================================
1952 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1954 Standard_Integer aDxw, aDyw ;
1956 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1958 MyWindow->Size (aDxw, aDyw);
1959 Standard_Real aValue;
1961 gp_Pnt aViewDims = myCamera->ViewDimensions();
1962 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1967 //=======================================================================
1968 //function : Convert
1970 //=======================================================================
1971 void V3d_View::Convert(const Standard_Integer Xp,
1972 const Standard_Integer Yp,
1974 Standard_Real& Yv) const
1976 Standard_Integer aDxw, aDyw;
1978 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1980 MyWindow->Size (aDxw, aDyw);
1982 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1983 aPoint = myCamera->ConvertProj2View (aPoint);
1989 //=======================================================================
1990 //function : Convert
1992 //=======================================================================
1993 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1995 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1997 Standard_Integer aDxw, aDyw;
1998 MyWindow->Size (aDxw, aDyw);
2000 gp_Pnt aViewDims = myCamera->ViewDimensions();
2001 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
2006 //=======================================================================
2007 //function : Convert
2009 //=======================================================================
2010 void V3d_View::Convert(const Standard_Real Xv,
2011 const Standard_Real Yv,
2012 Standard_Integer& Xp,
2013 Standard_Integer& Yp) const
2015 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
2017 Standard_Integer aDxw, aDyw;
2018 MyWindow->Size (aDxw, aDyw);
2020 gp_Pnt aPoint (Xv, Yv, 0.0);
2021 aPoint = myCamera->ConvertView2Proj (aPoint);
2022 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
2024 Xp = RealToInt (aPoint.X());
2025 Yp = RealToInt (aPoint.Y());
2028 //=======================================================================
2029 //function : Convert
2031 //=======================================================================
2032 void V3d_View::Convert(const Standard_Integer Xp,
2033 const Standard_Integer Yp,
2036 Standard_Real& Z) const
2038 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
2039 Standard_Integer aHeight, aWidth;
2040 MyWindow->Size (aWidth, aHeight);
2042 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
2043 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
2044 Standard_Real aZ = 2.0 * 0.0 - 1.0;
2046 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
2052 Graphic3d_Vertex aVrp;
2053 aVrp.SetCoord (X, Y, Z);
2055 if( MyViewer->Grid()->IsActive() ) {
2056 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
2057 aNewVrp.Coord (X, Y, Z) ;
2061 //=======================================================================
2062 //function : ConvertWithProj
2064 //=======================================================================
2065 void V3d_View::ConvertWithProj(const Standard_Integer Xp,
2066 const Standard_Integer Yp,
2072 Standard_Real& Dz) const
2074 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
2075 Standard_Integer aHeight, aWidth;
2076 MyWindow->Size (aWidth, aHeight);
2078 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
2079 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
2080 Standard_Real aZ = 2.0 * 0.0 - 1.0;
2082 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
2088 Graphic3d_Vertex aVrp;
2089 aVrp.SetCoord (X, Y, Z);
2091 aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
2093 Dx = X - aResult.X();
2094 Dy = Y - aResult.Y();
2095 Dz = Z - aResult.Z();
2097 if( MyViewer->Grid()->IsActive() ) {
2098 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
2099 aNewVrp.Coord (X, Y, Z) ;
2103 //=======================================================================
2104 //function : Convert
2106 //=======================================================================
2107 void V3d_View::Convert(const Standard_Real X,
2108 const Standard_Real Y,
2109 const Standard_Real Z,
2110 Standard_Integer& Xp,
2111 Standard_Integer& Yp) const
2113 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
2114 Standard_Integer aHeight, aWidth;
2115 MyWindow->Size (aWidth, aHeight);
2117 gp_Pnt aPoint = myCamera->Project (gp_Pnt (X, Y, Z));
2119 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
2120 Yp = RealToInt ((aPoint.Y() + 1) * 0.5 * aHeight);
2123 //=======================================================================
2124 //function : Project
2126 //=======================================================================
2127 void V3d_View::Project(const Standard_Real X,
2128 const Standard_Real Y,
2129 const Standard_Real Z,
2131 Standard_Real &Yp) const
2134 MyView->Projects (X, Y, Z, Xp, Yp, Zp);
2137 //=======================================================================
2138 //function : BackgroundColor
2140 //=======================================================================
2141 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
2144 Standard_Real& V3) const
2146 Quantity_Color C = BackgroundColor() ;
2147 C.Values(V1,V2,V3,Type) ;
2150 //=======================================================================
2151 //function : BackgroundColor
2153 //=======================================================================
2154 Quantity_Color V3d_View::BackgroundColor() const
2156 return MyBackground.Color() ;
2159 //=======================================================================
2160 //function : GradientBackgroundColors
2162 //=======================================================================
2163 void V3d_View::GradientBackgroundColors(Quantity_Color& Color1,Quantity_Color& Color2) const
2165 MyGradientBackground.Colors(Color1, Color2);
2168 //=======================================================================
2169 //function : GradientBackground
2171 //=======================================================================
2172 Aspect_GradientBackground V3d_View::GradientBackground() const
2174 return MyGradientBackground;
2177 //=======================================================================
2180 //=======================================================================
2181 Standard_Real V3d_View::Scale() const
2183 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
2185 Standard_Real aCameraScale;
2187 // Strange behavior for the sake of compatibility.
2188 if (!aDefaultCamera.IsNull())
2190 Standard_Real aDefaultScale = aDefaultCamera->Scale();
2191 aCameraScale = aDefaultScale / myCamera->Scale();
2195 aCameraScale = myCamera->Scale();
2198 return aCameraScale;
2201 //=======================================================================
2202 //function : AxialScale
2204 //=======================================================================
2205 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
2207 gp_Pnt anAxialScale = myCamera->AxialScale();
2208 Sx = anAxialScale.X();
2209 Sy = anAxialScale.Y();
2210 Sz = anAxialScale.Z();
2213 //=======================================================================
2216 //=======================================================================
2217 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
2219 gp_Pnt aViewDims = myCamera->ViewDimensions();
2221 Width = aViewDims.X();
2222 Height = aViewDims.Y();
2225 //=======================================================================
2228 //=======================================================================
2229 Standard_Real V3d_View::ZSize() const
2231 gp_Pnt aViewDims = myCamera->ViewDimensions();
2233 return aViewDims.Z();
2236 //=======================================================================
2239 //=======================================================================
2240 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
2241 Standard_Real& Vmin,
2242 Standard_Real& Umax,
2243 Standard_Real& Vmax) const
2245 Standard_Real Wmin,Wmax,U,V,W ;
2246 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
2248 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2251 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
2252 MyView->Projects(Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
2253 MyView->Projects(Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
2254 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
2255 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2256 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2257 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2258 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
2259 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2260 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2261 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2262 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
2263 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2264 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2265 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2266 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
2267 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2268 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2269 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2270 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
2271 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2272 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2273 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2274 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
2275 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2276 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2277 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2282 //=======================================================================
2285 //=======================================================================
2286 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
2287 Standard_Real& Ymin,
2288 Standard_Real& Zmin,
2289 Standard_Real& Xmax,
2290 Standard_Real& Ymax,
2291 Standard_Real& Zmax) const
2294 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
2295 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2298 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
2303 //=======================================================================
2304 //function : Gravity
2306 //=======================================================================
2307 Standard_Integer V3d_View::Gravity(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2309 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax;
2310 Standard_Integer Nstruct,Npoint ;
2311 Graphic3d_MapOfStructure MySetOfStructures;
2313 MyView->DisplayedStructures (MySetOfStructures);
2314 Nstruct = MySetOfStructures.Extent() ;
2316 Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ;
2318 Npoint = 0 ; X = Y = Z = 0. ;
2319 for (; MyIterator.More(); MyIterator.Next())
2321 const Handle(Graphic3d_Structure)& aStruct = MyIterator.Key();
2322 if (!aStruct->IsEmpty())
2324 aStruct->MinMaxValues (Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
2326 // Check bounding box for validness
2327 Standard_Real aLim = (ShortRealLast() - 1.0);
2328 if (Abs (Xmin) > aLim || Abs (Ymin) > aLim || Abs (Zmin) > aLim ||
2329 Abs (Xmax) > aLim || Abs (Ymax) > aLim || Abs (Zmax) > aLim)
2334 // use camera projection to find gravity point
2336 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2337 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2338 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2339 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax) };
2341 for (Standard_Integer aPntIt = 0; aPntIt < 8; ++aPntIt)
2343 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2345 gp_Pnt aProjected = myCamera->Project (aBndPnt);
2346 const Standard_Real& U = aProjected.X();
2347 const Standard_Real& V = aProjected.Y();
2348 if (Abs(U) <= 1.0 && Abs(V) <= 1.0)
2359 X /= Npoint ; Y /= Npoint ; Z /= Npoint ;
2365 //=======================================================================
2368 //=======================================================================
2369 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2371 gp_Pnt aCameraEye = myCamera->Eye();
2377 //=============================================================================
2378 //function : FocalReferencePoint
2380 //=============================================================================
2381 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2386 //=============================================================================
2387 //function : ProjReferenceAxe
2389 //=============================================================================
2390 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2391 const Standard_Integer Ypix,
2397 Standard_Real& VZ) const
2399 Standard_Real Xo,Yo,Zo;
2401 Convert (Xpix, Ypix, XP, YP, ZP);
2402 if ( Type() == V3d_PERSPECTIVE )
2404 FocalReferencePoint (Xo,Yo,Zo);
2415 //=============================================================================
2418 //=============================================================================
2419 Standard_Real V3d_View::Depth() const
2421 return myCamera->Distance();
2424 //=============================================================================
2427 //=============================================================================
2428 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2430 gp_Dir aCameraDir = myCamera->Direction().Reversed();
2431 Dx = aCameraDir.X();
2432 Dy = aCameraDir.Y();
2433 Dz = aCameraDir.Z();
2436 //=============================================================================
2439 //=============================================================================
2440 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2442 gp_Pnt aCameraCenter = myCamera->Center();
2443 X = aCameraCenter.X();
2444 Y = aCameraCenter.Y();
2445 Z = aCameraCenter.Z();
2448 //=============================================================================
2451 //=============================================================================
2452 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2454 gp_Dir aCameraUp = myCamera->Up();
2460 //=============================================================================
2463 //=============================================================================
2464 Standard_Real V3d_View::Twist() const
2466 Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2467 Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
2468 Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
2469 Standard_Boolean TheStatus ;
2471 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
2475 anUp = gp_Dir (0.,0.,1.) ;
2476 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2478 anUp = gp_Dir (0.,1.,0.) ;
2479 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2482 anUp = gp_Dir (1.,0.,0.) ;
2483 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2485 Yaxis.Coord(X0,Y0,Z0) ;
2488 /* Compute Cross Vector From Up & Origin */
2489 pvx = Y0*Zup - Z0*Yup ;
2490 pvy = Z0*Xup - X0*Zup ;
2491 pvz = X0*Yup - Y0*Xup ;
2492 pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2493 sca = X0*Xup + Y0*Yup + Z0*Zup ;
2496 if( angle > 1. ) angle = 1. ;
2497 else if( angle < -1. ) angle = -1. ;
2498 angle = asin(angle) ;
2499 if( sca < 0. ) angle = M_PI - angle ;
2500 if( angle > 0. && angle < M_PI ) {
2501 sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2502 if( sca < 0. ) angle = DEUXPI - angle ;
2507 //=============================================================================
2508 //function : ShadingModel
2510 //=============================================================================
2511 V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2513 V3d_TypeOfShadingModel SM = (V3d_TypeOfShadingModel)MyViewContext.Model() ;
2517 //=============================================================================
2518 //function : SurfaceDetail
2520 //=============================================================================
2521 V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
2523 V3d_TypeOfSurfaceDetail SM = (V3d_TypeOfSurfaceDetail)MyViewContext.SurfaceDetail() ;
2527 //=============================================================================
2528 //function : TextureEnv
2530 //=============================================================================
2531 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2533 Handle(Graphic3d_TextureEnv) SM = MyViewContext.TextureEnv() ;
2537 //=============================================================================
2538 //function : Visualization
2540 //=============================================================================
2541 V3d_TypeOfVisualization V3d_View::Visualization() const
2543 V3d_TypeOfVisualization V =
2544 (V3d_TypeOfVisualization)MyViewContext.Visualization() ;
2548 //=============================================================================
2549 //function : Antialiasing
2551 //=============================================================================
2552 Standard_Boolean V3d_View::Antialiasing() const
2554 Standard_Boolean A = MyViewContext.AliasingIsOn() ;
2558 //=============================================================================
2561 //=============================================================================
2562 Handle(V3d_Viewer) V3d_View::Viewer() const
2567 //=============================================================================
2568 //function : IfWindow
2570 //=============================================================================
2571 Standard_Boolean V3d_View::IfWindow() const
2573 Standard_Boolean TheStatus = MyView->IsDefined() ;
2577 //=============================================================================
2580 //=============================================================================
2581 Handle(Aspect_Window) V3d_View::Window() const
2586 //=============================================================================
2589 //=============================================================================
2590 V3d_TypeOfView V3d_View::Type() const
2592 return myCamera->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2595 //=============================================================================
2596 //function : SetFocale
2598 //=============================================================================
2599 void V3d_View::SetFocale( const Standard_Real focale )
2601 if (myCamera->IsOrthographic())
2606 Standard_Real aFOVyRad = ATan (focale / (myCamera->Distance() * 2.0));
2608 myCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2613 //=============================================================================
2616 //=============================================================================
2617 Standard_Real V3d_View::Focale() const
2619 if (myCamera->IsOrthographic())
2624 return myCamera->Distance() * 2.0 * Tan(myCamera->FOVy() * M_PI / 360.0);
2627 //=============================================================================
2630 //=============================================================================
2631 Handle(Visual3d_View) V3d_View::View() const
2636 //=============================================================================
2637 //function : ScreenAxis
2639 //=============================================================================
2640 Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2642 Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2643 Standard_Real dx1, dy1, dz1, xx, yy, zz;
2645 Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2646 Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2647 xx = Yup*Zpn - Zup*Ypn;
2648 yy = Zup*Xpn - Xup*Zpn;
2649 zz = Xup*Ypn - Yup*Xpn;
2650 Xaxe.SetCoord (xx, yy, zz);
2651 if (Xaxe.LengthZero()) return Standard_False;
2653 Xaxe.Coord(dx1, dy1, dz1);
2654 xx = Ypn*dz1 - Zpn*dy1;
2655 yy = Zpn*dx1 - Xpn*dz1;
2656 zz = Xpn*dy1 - Ypn*dx1;
2657 Yaxe.SetCoord (xx, yy, zz) ;
2658 if (Yaxe.LengthZero()) return Standard_False;
2661 Zaxe.SetCoord (Xpn, Ypn, Zpn);
2663 return Standard_True;
2666 //=============================================================================
2667 //function : TrsPoint
2669 //=============================================================================
2670 Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2672 Graphic3d_Vertex PP ;
2673 Standard_Real X,Y,Z,XX,YY,ZZ ;
2676 Standard_Integer lr, ur, lc, uc;
2677 lr = Matrix.LowerRow ();
2678 ur = Matrix.UpperRow ();
2679 lc = Matrix.LowerCol ();
2680 uc = Matrix.UpperCol ();
2681 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
2683 PP.SetCoord(X,Y,Z) ;
2687 XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2688 Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2690 YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2691 Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2693 ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2694 Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2695 PP.SetCoord(XX,YY,ZZ) ;
2699 //=======================================================================
2702 //=======================================================================
2703 void V3d_View::Pan (const Standard_Integer theDXp,
2704 const Standard_Integer theDYp,
2705 const Quantity_Factor theZoomFactor,
2706 const Standard_Boolean theToStart)
2708 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2711 //=======================================================================
2712 //function : Panning
2714 //=======================================================================
2715 void V3d_View::Panning (const Standard_Real theDXv,
2716 const Standard_Real theDYv,
2717 const Quantity_Factor theZoomFactor,
2718 const Standard_Boolean theToStart)
2720 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2724 myCamStartOpEye = myCamera->Eye();
2725 myCamStartOpCenter = myCamera->Center();
2728 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2730 gp_Pnt aViewDims = myCamera->ViewDimensions();
2732 myCamera->SetEye (myCamStartOpEye);
2733 myCamera->SetCenter (myCamStartOpCenter);
2734 Translate (myCamera, -theDXv, -theDYv);
2735 Scale (myCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2737 SetImmediateUpdate (wasUpdateEnabled);
2742 //=======================================================================
2745 //=======================================================================
2746 void V3d_View::Zoom (const Standard_Integer theXp1,
2747 const Standard_Integer theYp1,
2748 const Standard_Integer theXp2,
2749 const Standard_Integer theYp2)
2751 Standard_Integer aDx = theXp2 - theXp1;
2752 Standard_Integer aDy = theYp2 - theYp1;
2753 if (aDx != 0 || aDy != 0)
2755 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2756 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2757 SetZoom (aCoeff, Standard_True);
2761 //=======================================================================
2762 //function : StartZoomAtPoint
2764 //=======================================================================
2765 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2766 const Standard_Integer theYp)
2768 MyZoomAtPointX = theXp;
2769 MyZoomAtPointY = theYp;
2772 //=======================================================================
2773 //function : ZoomAtPoint
2775 //=======================================================================
2776 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2777 const Standard_Integer theMouseStartY,
2778 const Standard_Integer theMouseEndX,
2779 const Standard_Integer theMouseEndY)
2781 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2784 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2785 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2786 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2788 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2790 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
2791 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
2793 // ensure that zoom will not be too small or too big.
2794 Standard_Real aCoef = aDZoom;
2795 if (aViewWidth < aCoef * Precision::Confusion())
2797 aCoef = aViewWidth / Precision::Confusion();
2799 else if (aViewWidth > aCoef * 1e12)
2801 aCoef = aViewWidth / 1e12;
2803 if (aViewHeight < aCoef * Precision::Confusion())
2805 aCoef = aViewHeight / Precision::Confusion();
2807 else if (aViewHeight > aCoef * 1e12)
2809 aCoef = aViewHeight / 1e12;
2812 Standard_Real aZoomAtPointXv = 0.0;
2813 Standard_Real aZoomAtPointYv = 0.0;
2814 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2816 V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
2817 V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
2819 myCamera->SetScale (myCamera->Scale() / aCoef);
2820 Translate (myCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2824 SetImmediateUpdate (wasUpdateEnabled);
2829 //=============================================================================
2830 //function : AxialScale
2832 //=============================================================================
2833 void V3d_View::AxialScale (const Standard_Integer Dx,
2834 const Standard_Integer Dy,
2835 const V3d_TypeOfAxe Axis)
2837 if( Dx != 0. || Dy != 0. ) {
2838 Standard_Real Sx, Sy, Sz;
2839 AxialScale( Sx, Sy, Sz );
2840 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2841 dscale = (Dx > 0) ? dscale : 1./dscale;
2842 if( Axis == V3d_X ) Sx = dscale;
2843 if( Axis == V3d_Y ) Sy = dscale;
2844 if( Axis == V3d_Z ) Sz = dscale;
2845 SetAxialScale( Sx, Sy, Sz );
2849 //=============================================================================
2852 //=============================================================================
2853 void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
2854 const Standard_Real Xmin,
2855 const Standard_Real Ymin,
2856 const Standard_Real Xmax,
2857 const Standard_Real Ymax)
2859 Standard_Integer aWinWidth, aWinHeight;
2860 aWindow->Size (aWinWidth, aWinHeight);
2862 Standard_Real aWinAspect = (Standard_Real)aWinWidth / aWinHeight;
2863 Standard_Real aFitSizeU = Abs (Xmax - Xmin);
2864 Standard_Real aFitSizeV = Abs (Ymax - Ymin);
2865 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2866 if (aFitAspect >= aWinAspect)
2868 aFitSizeV = aFitSizeU / aWinAspect;
2872 aFitSizeU = aFitSizeV * aWinAspect;
2875 myCamera->SetAspect (aWinAspect);
2876 Translate (myCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
2877 Scale (myCamera, aFitSizeU, aFitSizeV);
2883 //=============================================================================
2884 //function : StartRotation
2886 //=============================================================================
2888 static Standard_Boolean zRotation = Standard_False;
2890 void V3d_View::StartRotation(const Standard_Integer X,
2891 const Standard_Integer Y,
2892 const Quantity_Ratio zRotationThreshold)
2897 rx = Standard_Real(Convert(x));
2898 ry = Standard_Real(Convert(y));
2900 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2902 zRotation = Standard_False;
2903 if( zRotationThreshold > 0. ) {
2904 Standard_Real dx = Abs(sx - rx/2.);
2905 Standard_Real dy = Abs(sy - ry/2.);
2906 // if( dx > rx/3. || dy > ry/3. ) zRotation = Standard_True;
2907 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2908 if( dx > dd || dy > dd ) zRotation = Standard_True;
2914 //=============================================================================
2915 //function : Rotation
2917 //=============================================================================
2918 void V3d_View::Rotation(const Standard_Integer X,
2919 const Standard_Integer Y)
2922 if( rx == 0. || ry == 0. ) {
2928 Standard_Real dx=0.,dy=0.,dz=0.;
2930 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2931 atan2(sx-rx/2.,ry/2.-sy);
2933 dx = (Standard_Real(X) - sx) * M_PI / rx;
2934 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2936 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2938 Standard_Real dx = (Standard_Real(X - sx)) * M_PI;
2939 Standard_Real dy = (Standard_Real(sy - Y)) * M_PI;
2940 Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2943 if( !myImmediateUpdate ) Update();
2945 myImmediateUpdate = Standard_False;
2946 Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2947 ZFitAll (Zmargin); //Don't do that, perf improvment
2948 myImmediateUpdate = Standard_True;
2953 //=============================================================================
2954 //function : SetComputedMode
2956 //=============================================================================
2957 void V3d_View::SetComputedMode (const Standard_Boolean aMode)
2963 MyView->SetComputedMode (Standard_True);
2969 MyView->SetComputedMode (Standard_False);
2974 //=============================================================================
2975 //function : ComputedMode
2977 //=============================================================================
2978 Standard_Boolean V3d_View::ComputedMode() const
2980 return MyView->ComputedMode();
2983 //=============================================================================
2984 //function : SetBackFacingModel
2986 //=============================================================================
2987 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel aModel)
2989 MyView->SetBackFacingModel (Visual3d_TypeOfBackfacingModel(aModel));
2993 //=============================================================================
2994 //function : BackFacingModel
2996 //=============================================================================
2997 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2999 return V3d_TypeOfBackfacingModel(MyView -> BackFacingModel ());
3002 void V3d_View::Init()
3004 myComputedMode = MyViewer->ComputedMode();
3005 if( !myComputedMode || !MyViewer->DefaultComputedMode() ) {
3006 SetComputedMode(Standard_False);
3010 //=============================================================================
3013 //=============================================================================
3014 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
3015 const Graphic3d_BufferType& theBufferType)
3017 Standard_Integer aWinWidth, aWinHeight;
3018 MyWindow->Size (aWinWidth, aWinHeight);
3019 Image_AlienPixMap anImage;
3021 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
3024 //=============================================================================
3025 //function : ToPixMap
3027 //=============================================================================
3028 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
3029 const Standard_Integer theWidth,
3030 const Standard_Integer theHeight,
3031 const Graphic3d_BufferType& theBufferType,
3032 const Standard_Boolean theToKeepAspect,
3033 const V3d_StereoDumpOptions theStereoOptions)
3035 Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
3037 // always prefer hardware accelerated offscreen buffer
3038 Graphic3d_PtrFrameBuffer aFBOPtr = NULL;
3039 Graphic3d_PtrFrameBuffer aPrevFBOPtr = (Graphic3d_PtrFrameBuffer )cView->ptrFBO;
3040 Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
3041 Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
3042 if (aPrevFBOPtr != NULL)
3044 MyView->FBOGetDimensions (aPrevFBOPtr,
3045 aPrevFBOVPSizeX, aPrevFBOVPSizeY,
3046 aPrevFBOSizeXMax, aPrevFBOSizeYMax);
3047 if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
3049 MyView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
3050 aFBOPtr = aPrevFBOPtr;
3054 if (aFBOPtr == NULL)
3056 // Try to create hardware accelerated buffer
3057 aFBOPtr = MyView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
3058 if (aFBOPtr != NULL)
3060 MyView->FBOGetDimensions (aFBOPtr,
3061 aFBOVPSizeX, aFBOVPSizeY,
3062 aFBOSizeXMax, aFBOSizeYMax);
3063 // reduce viewport in case of hardware limits
3064 if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
3065 if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
3066 MyView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
3069 cView->ptrFBO = aFBOPtr;
3071 // If hardware accelerated buffer - try to use onscreen buffer
3072 // Results may be bad!
3073 if (aFBOPtr == NULL)
3075 // retrieve window sizes
3076 Standard_Integer aWinWidth, aWinHeight;
3077 MyWindow->Size (aWinWidth, aWinHeight);
3079 // technically we can reduce existing viewport...
3080 // but currently allow only dumping the window itself
3081 if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
3083 return Standard_False;
3087 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
3089 aStoreMapping->Copy (myCamera);
3091 if (myCamera->IsStereo())
3093 switch (theStereoOptions)
3096 myCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
3099 case V3d_SDO_LEFT_EYE :
3100 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
3103 case V3d_SDO_RIGHT_EYE :
3104 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
3109 // render immediate structures into back buffer rather than front
3110 Handle(Graphic3d_GraphicDriver) aDriver = Handle(Graphic3d_GraphicDriver)::DownCast (MyView->GraphicDriver());
3111 const Standard_Boolean aPrevImmediateMode = aDriver.IsNull() ? Standard_True : aDriver->SetImmediateModeDrawToFront (*cView, Standard_False);
3113 const Standard_Boolean toAutoUpdate = myImmediateUpdate;
3114 myImmediateUpdate = Standard_False;
3116 myImmediateUpdate = toAutoUpdate;
3118 if (theToKeepAspect)
3120 myCamera->SetAspect ((Standard_Real) aFBOVPSizeX / aFBOVPSizeY);
3123 //workaround for rendering list of Over and Under Layers
3124 if (!MyLayerMgr.IsNull())
3126 MyLayerMgr->Compute();
3131 if (!aDriver.IsNull())
3133 aDriver->SetImmediateModeDrawToFront (*cView, aPrevImmediateMode);
3136 myCamera->Copy (aStoreMapping);
3138 Standard_Boolean isSuccess = Standard_True;
3140 // allocate image buffer for dumping
3141 if (theImage.IsEmpty()
3142 || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
3143 || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
3145 bool isBigEndian = Image_PixMap::IsBigEndianHost();
3146 Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
3147 switch (theBufferType)
3149 case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
3150 case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
3151 case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
3154 isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
3156 isSuccess = isSuccess && MyView->BufferDump (theImage, theBufferType);
3158 // FBO now useless, free resources
3159 if (aFBOPtr != aPrevFBOPtr)
3161 MyView->FBORelease (aFBOPtr);
3163 else if (aPrevFBOPtr != NULL)
3165 MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
3167 cView->ptrFBO = aPrevFBOPtr;
3171 void V3d_View::ImmediateUpdate() const
3173 if (myImmediateUpdate) Update();
3176 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
3178 Standard_Boolean aPreviousMode = myImmediateUpdate;
3179 myImmediateUpdate = theImmediateUpdate;
3180 return aPreviousMode;
3183 // =======================================================================
3184 // function : SetCamera
3186 // =======================================================================
3187 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
3189 Standard_ASSERT_RAISE (!theCamera.IsNull(), "Void camera is not allowed");
3191 myCamera = theCamera;
3193 MyView->SetCamera (theCamera);
3196 // =======================================================================
3197 // function : GetCamera
3199 // =======================================================================
3200 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
3205 // =======================================================================
3206 // function : FitMinMax
3207 // purpose : Internal
3208 // =======================================================================
3209 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
3210 const gp_XYZ& theMinCorner,
3211 const gp_XYZ& theMaxCorner,
3212 const Standard_Real theMargin,
3213 const Standard_Real theResolution,
3214 const Standard_Boolean theToEnlargeIfLine) const
3216 // Check bounding box for validness
3217 Standard_Real aLim = (ShortRealLast() - 1.0);
3218 if (Abs (theMinCorner.X()) > aLim || Abs (theMinCorner.Y()) > aLim || Abs (theMinCorner.Z()) > aLim ||
3219 Abs (theMaxCorner.X()) > aLim || Abs (theMaxCorner.Y()) > aLim || Abs (theMaxCorner.Z()) > aLim)
3221 return Standard_False; // bounding box is out of bounds...
3224 // Apply "axial scaling" to the bounding points.
3225 // It is not the best approach to make this scaling as a part of fit all operation,
3226 // but the axial scale is integrated into camera orientation matrix and the other
3227 // option is to perform frustum plane adjustment algorithm in view camera space,
3228 // which will lead to a number of additional world-view space conversions and
3229 // loosing precision as well.
3230 Standard_Real aXmin = theMinCorner.X() * theCamera->AxialScale().X();
3231 Standard_Real aXmax = theMaxCorner.X() * theCamera->AxialScale().X();
3232 Standard_Real aYmin = theMinCorner.Y() * theCamera->AxialScale().Y();
3233 Standard_Real aYmax = theMaxCorner.Y() * theCamera->AxialScale().Y();
3234 Standard_Real aZmin = theMinCorner.Z() * theCamera->AxialScale().Z();
3235 Standard_Real aZmax = theMaxCorner.Z() * theCamera->AxialScale().Z();
3238 aBBox.Update (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3239 if (aBBox.IsThin (RealEpsilon()))
3241 return Standard_False; // nothing to fit all
3244 gp_Pnt aBBCenter ((aXmin + aXmax) * 0.5, (aYmin + aYmax) * 0.5, (aZmin + aZmax) * 0.5);
3246 gp_Pln aFrustumLeft;
3247 gp_Pln aFrustumRight;
3248 gp_Pln aFrustumBottom;
3250 gp_Pln aFrustumNear;
3252 theCamera->Frustum (aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar);
3254 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3255 gp_Dir aCamDir = theCamera->Direction();
3256 gp_Dir aCamSide = aCamDir ^ aCamUp;
3258 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3259 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3260 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3261 // set up perspective-correct camera projection matching the bounding box.
3262 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3263 // The zooming can be done by calculating view plane size matching the bounding box at center of
3264 // the bounding box. The only limitation here is that the scale of camera should define size of
3265 // its view plane passing through the camera center, and the center of camera should be on the
3266 // same line with the center of bounding box.
3268 // The following method is applied:
3269 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3270 // 2) Determine new location of frustum planes, "matching" the bounding box.
3271 // 3) Determine new camera projection vector using the normalized asymmetry.
3272 // 4) Determine new zooming in view space.
3274 // Determine normalized projection asymmetry (if any).
3276 Standard_Real anAssymX = Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction()))
3277 - Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction()));
3278 Standard_Real anAssymY = Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction()))
3279 - Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction()));
3281 // Determine how far should be the frustum planes placed from center
3282 // of bounding box, in order to match the bounding box closely.
3283 gp_Pln aMatchSide[6] = {aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar};
3284 Standard_Real aMatchDistance[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
3285 for (Standard_Integer anIt = 0; anIt < 6; ++anIt)
3287 const gp_Dir& aPlaneN = aMatchSide[anIt].Axis().Direction();
3290 aPlaneTrsf.SetTransformation (gp_Ax3(), gp_Ax3 (aBBCenter, aPlaneN));
3291 Bnd_Box aRelativeBBox = aBBox.Transformed (aPlaneTrsf);
3293 Standard_Real aDummy = 0.0;
3294 Standard_Real aZmin = 0.0;
3295 Standard_Real aZmax = 0.0;
3296 aRelativeBBox.Get (aDummy, aDummy, aZmin, aDummy, aDummy, aZmax);
3297 aMatchDistance[anIt] = -aZmin;
3299 // The center of camera is placed on the same line with center of bounding box.
3300 // The view plane section crosses the bounding box at its center.
3301 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3302 // into view section size between the point and the frustum plane.
3304 // /|\ right half of frame //
3306 // point o<-- distance * coeff -->//---- (view plane section)
3316 aMatchDistance[0] *= Sqrt(1 + Pow (Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction())), 2.0));
3317 aMatchDistance[1] *= Sqrt(1 + Pow (Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction())), 2.0));
3318 aMatchDistance[2] *= Sqrt(1 + Pow (Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction())), 2.0));
3319 aMatchDistance[3] *= Sqrt(1 + Pow (Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction())), 2.0));
3320 aMatchDistance[4] *= Sqrt(1 + Pow (Tan ( aCamDir.Angle (aFrustumNear.Axis().Direction())), 2.0));
3321 aMatchDistance[5] *= Sqrt(1 + Pow (Tan (-aCamDir.Angle (aFrustumFar.Axis().Direction())), 2.0));
3323 Standard_Real aViewSizeXv = aMatchDistance[0] + aMatchDistance[1];
3324 Standard_Real aViewSizeYv = aMatchDistance[2] + aMatchDistance[3];
3325 Standard_Real aViewSizeZv = aMatchDistance[4] + aMatchDistance[5];
3327 // Place center of camera on the same line with center of bounding
3328 // box applying corresponding projection asymmetry (if any).
3329 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3330 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3331 Standard_Real anOffsetXv = (aMatchDistance[1] - aMatchDistance[0]) * 0.5 + anAssymXv;
3332 Standard_Real anOffsetYv = (aMatchDistance[3] - aMatchDistance[2]) * 0.5 + anAssymYv;
3333 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3334 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3335 gp_Pnt aNewCenter = aBBCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3337 gp_Trsf aCenterTrsf;
3338 aCenterTrsf.SetTranslation (theCamera->Center(), aNewCenter);
3339 theCamera->Transform (aCenterTrsf);
3340 theCamera->SetDistance (Max (aMatchDistance[5] + aMatchDistance[4], Precision::Confusion()));
3342 // Bounding box collapses to a point or thin line going in depth of the screen
3343 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3345 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3347 return Standard_True; // This is just one point or line and zooming has no effect.
3350 // Looking along line and "theToEnlargeIfLine" is requested.
3351 // Fit view to see whole scene on rotation.
3352 aViewSizeXv = aViewSizeZv;
3353 aViewSizeYv = aViewSizeZv;
3356 Scale (theCamera, aViewSizeXv * (1.0 + theMargin), aViewSizeYv * (1.0 + theMargin));
3358 return Standard_True;
3361 // =======================================================================
3363 // purpose : Internal
3364 // =======================================================================
3365 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3366 const Standard_Real theSizeXv,
3367 const Standard_Real theSizeYv) const
3369 Standard_Real anAspect = theCamera->Aspect();
3370 Standard_Real aMaxSize = Max (theSizeXv / anAspect, theSizeYv);
3371 theCamera->SetScale (aMaxSize);
3374 // =======================================================================
3375 // function : Translate
3376 // purpose : Internal
3377 // =======================================================================
3378 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3379 const Standard_Real theDXv,
3380 const Standard_Real theDYv) const
3382 const gp_Pnt& aCenter = theCamera->Center();
3383 const gp_Dir& aDir = theCamera->Direction();
3384 const gp_Dir& anUp = theCamera->Up();
3385 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3387 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3388 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3389 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3391 aPanTrsf.SetTranslation (aCameraPan);
3393 theCamera->Transform (aPanTrsf);