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 29-OCT-98 : DCB : Adding ScreenCopy () method.
60 About FitAll() multiple. This probleme is caused by missing
61 precision of transformation matrices. If it is supposed that
62 projection is made in the plane (U,V), there is a difference
63 after several Zoom - compared to the exact value (cf ZoomX).
64 Don't forget that the matrices work in float and not in double.
65 To solve the problem (for lack of a better solution) I make 2 passes.
67 ************************************************************************/
69 /*----------------------------------------------------------------------*/
74 #include <Standard_TypeMismatch.hxx>
75 #include <Standard_ShortReal.hxx>
76 #include <Standard_Assert.hxx>
77 #include <Standard_ErrorHandler.hxx>
78 #include <Standard_DivideByZero.hxx>
80 #include <Visual3d_ViewManager.hxx>
81 #include <Visual3d_Light.hxx>
82 #include <Visual3d_Layer.hxx>
85 #include <V3d_View.ixx>
86 #include <V3d_BadValue.hxx>
87 #include <V3d_StereoDumpOptions.hxx>
89 #include <Image_AlienPixMap.hxx>
93 #include <TColStd_Array2OfReal.hxx>
94 #include <TColStd_HSequenceOfInteger.hxx>
96 #include <Bnd_Box.hxx>
98 #include <Precision.hxx>
100 #include <Graphic3d_Structure.hxx>
101 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
102 #include <Graphic3d_MapOfStructure.hxx>
103 #include <Graphic3d_TextureEnv.hxx>
104 #include <Graphic3d_AspectMarker3d.hxx>
105 #include <Graphic3d_GraphicDriver.hxx>
107 #define V3d_FLAG_COMPUTATION 0x00000004
110 #include <OSD_Environment.hxx>
112 /*----------------------------------------------------------------------*/
117 #define DEUXPI (2. * M_PI)
121 static const Standard_Integer THE_NB_BOUND_POINTS = 8;
124 //=============================================================================
125 //function : Constructor
127 //=============================================================================
128 V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) :
129 MyViewer(VM.operator->()),
132 myActiveLightsIterator(),
133 SwitchSetFront(Standard_False),
136 myImmediateUpdate = Standard_False;
137 MyView = new Visual3d_View(MyViewer->Viewer());
139 // { Begin to retrieve the definition from ViewContext.
140 // Step MyViewContext = MyView->Context() ;
141 // to permit MyView->SetContext to compare
142 // the old and the new context.
143 // No problem for MyViewMapping, MyViewOrientation
144 // as MyView->SetViewMapping and MyView->SetViewOrientation
145 // don't try to optimize the modifications introduced to
146 // viewmapping and vieworientation.
149 if ((MyView->Context ()).AliasingIsOn ())
150 MyViewContext.SetAliasingOn ();
152 MyViewContext.SetAliasingOff ();
155 MyViewContext.SetDepthCueingBackPlane
156 ((MyView->Context ()).DepthCueingBackPlane ());
157 MyViewContext.SetDepthCueingFrontPlane
158 ((MyView->Context ()).DepthCueingFrontPlane ());
160 if ((MyView->Context ()).DepthCueingIsOn ())
161 MyViewContext.SetDepthCueingOn ();
163 MyViewContext.SetDepthCueingOff ();
166 MyViewContext.SetZClippingBackPlane
167 ((MyView->Context ()).ZClippingBackPlane ());
168 MyViewContext.SetZClippingFrontPlane
169 ((MyView->Context ()).ZClippingFrontPlane ());
171 if ((MyView->Context ()).FrontZClippingIsOn ())
172 MyViewContext.SetFrontZClippingOn ();
174 MyViewContext.SetFrontZClippingOff ();
176 if ((MyView->Context ()).BackZClippingIsOn ())
177 MyViewContext.SetBackZClippingOn ();
179 MyViewContext.SetBackZClippingOff ();
181 // Visualization and Shading Model
182 MyViewContext.SetModel ((MyView->Context ()).Model ());
183 MyViewContext.SetVisualization ((MyView->Context ()).Visualization ());
186 MyViewContext.SetSurfaceDetail (MyView->Context ().SurfaceDetail ());
187 MyViewContext.SetTextureEnv (MyView->Context ().TextureEnv ());
188 // } End of retrieval of the definition of ViewContext.
190 MyBackground = VM->GetBackgroundColor() ;
191 MyGradientBackground = VM->GetGradientBackground() ;
194 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
195 aCamera->SetFOVy (45.0);
196 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
197 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
200 SetAxis (0.,0.,0.,1.,1.,1.);
201 SetVisualization (VM->DefaultVisualization());
202 SetShadingModel (VM->DefaultShadingModel());
203 SetSurfaceDetail (VM->DefaultSurfaceDetail());
206 SetProj (VM->DefaultViewProj());
207 SetSize (VM->DefaultViewSize());
208 Standard_Real zsize = VM->DefaultViewSize();
210 SetZClippingDepth (0.);
211 SetZClippingWidth (zsize);
212 SetZCueingDepth (0.);
213 SetZCueingWidth (zsize);
214 SetDepth (VM->DefaultViewSize()/2.0);
215 SetViewMappingDefault();
216 SetViewOrientationDefault();
219 myImmediateUpdate = Standard_True;
221 aCamera->SetProjectionType ((Type == V3d_ORTHOGRAPHIC)
222 ? Graphic3d_Camera::Projection_Orthographic
223 : Graphic3d_Camera::Projection_Perspective);
226 //=============================================================================
227 //function : Constructor
229 //=============================================================================
230 V3d_View::V3d_View(const Handle(V3d_Viewer)& theVM,const Handle(V3d_View)& theView) :
231 MyViewer(theVM.operator->()),
234 myActiveLightsIterator(),
235 SwitchSetFront(Standard_False),
238 Handle(Visual3d_View) aFromView = theView->View();
240 myImmediateUpdate = Standard_False;
241 MyView = new Visual3d_View (MyViewer->Viewer());
243 for (theView->InitActiveLights(); theView->MoreActiveLights(); theView->NextActiveLights())
245 MyActiveLights.Append (theView->ActiveLight());
248 MyViewContext = aFromView->Context() ;
250 SetCamera (new Graphic3d_Camera (theView->Camera()));
251 View()->SetAutoZFitMode (theView->View()->AutoZFitMode(), theView->View()->AutoZFitScaleFactor());
253 MyBackground = aFromView->Background() ;
254 MyGradientBackground = aFromView->GradientBackground();
256 MyView->SetContext (MyViewContext) ;
258 SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
260 SetViewMappingDefault();
261 SetViewOrientationDefault();
262 theVM->AddView (this);
266 myImmediateUpdate = Standard_True;
269 //=============================================================================
270 //function : SetMagnify
272 //=============================================================================
273 void V3d_View::SetMagnify(const Handle(Aspect_Window)& TheWindow,
274 const Handle(V3d_View)& aPreviousView,
275 const Standard_Integer x1,
276 const Standard_Integer y1,
277 const Standard_Integer x2,
278 const Standard_Integer y2)
280 if( !MyView->IsDefined() ) {
281 Standard_Real a,b,c,d;
282 aPreviousView->Convert(x1,y1,a,b);
283 aPreviousView->Convert(x2,y2,c,d);
284 MyView->SetWindow(TheWindow) ;
285 FitAll(TheWindow,a,b,c,d);
286 MyView->SetContext(MyViewContext) ;
287 MyView->SetBackground(MyBackground) ;
288 MyViewer->SetViewOn(this) ;
289 MyWindow = TheWindow;
291 SetViewMappingDefault();
295 //=============================================================================
296 //function : SetWindow
298 //=============================================================================
299 void V3d_View::SetWindow(const Handle(Aspect_Window)& TheWindow)
301 MyView->SetWindow(TheWindow) ;
302 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
303 MyWindow = TheWindow;
304 // SetWindow carries out SetRatio and modifies
305 MyView->SetContext(MyViewContext) ;
306 MyView->SetBackground(MyBackground) ;
307 MyViewer->SetViewOn(this) ;
311 //=============================================================================
312 //function : SetWindow
314 //=============================================================================
315 void V3d_View::SetWindow(const Handle(Aspect_Window)& aWindow,
316 const Aspect_RenderingContext aContext,
317 const Aspect_GraphicCallbackProc& aDisplayCB,
318 const Standard_Address aClientData)
320 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
322 MyView->SetWindow(aWindow, aContext, aDisplayCB, aClientData) ;
323 MyView->SetContext(MyViewContext) ;
324 MyView->SetBackground(MyBackground) ;
325 MyViewer->SetViewOn(this) ;
329 //=============================================================================
332 //=============================================================================
333 void V3d_View::Remove() const
335 MyViewer->DelView (this);
337 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
341 //=============================================================================
344 //=============================================================================
345 void V3d_View::Update() const
347 if( MyView->IsDefined() ) MyView->Update (Aspect_TOU_ASAP) ;
350 //=============================================================================
353 //=============================================================================
354 void V3d_View::Redraw() const
356 if( MyView->IsDefined() ) MyView->Redraw() ;
359 //=============================================================================
360 //function : RedrawImmediate
362 //=============================================================================
363 void V3d_View::RedrawImmediate() const
365 if (MyView->IsDefined())
367 MyView->RedrawImmediate();
371 //=============================================================================
372 //function : Invalidate
374 //=============================================================================
375 void V3d_View::Invalidate() const
377 if (MyView->IsDefined())
379 MyView->Invalidate();
383 //=============================================================================
384 //function : AutoZFit
386 //=============================================================================
387 void V3d_View::AutoZFit()
392 //=============================================================================
395 //=============================================================================
396 void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
398 View()->ZFitAll (theScaleFactor);
401 //=============================================================================
404 //=============================================================================
405 void V3d_View::Redraw(const Standard_Integer xc,const Standard_Integer yc,
406 const Standard_Integer width,const Standard_Integer height) const
408 if( MyView->IsDefined() ) MyView->Redraw(xc,yc,width,height) ;
411 //=============================================================================
414 //=============================================================================
415 Standard_Boolean V3d_View::IsEmpty() const
417 Standard_Boolean TheStatus = Standard_True ;
418 if( MyView->IsDefined() ) {
419 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
420 if( Nstruct > 0 ) TheStatus = Standard_False ;
425 //=============================================================================
426 //function : UpdateLights
428 //=============================================================================
429 void V3d_View::UpdateLights() const
431 MyView->SetContext(MyViewContext);
435 //=============================================================================
436 //function : DoMapping
438 //=============================================================================
439 void V3d_View::DoMapping()
441 if( MyView->IsDefined() ) {
442 (MyView->Window())->DoMapping() ;
446 //=============================================================================
447 //function : MustBeResized
449 //=============================================================================
450 void V3d_View::MustBeResized()
452 if ( !MyLayerMgr.IsNull() )
453 MyLayerMgr->Resized();
455 if( MyView->IsDefined() ) {
461 //=============================================================================
462 //function : SetBackgroundColor
464 //=============================================================================
465 void V3d_View::SetBackgroundColor(const Quantity_TypeOfColor Type, const Standard_Real v1, const Standard_Real v2, const Standard_Real v3)
467 Standard_Real V1 = Max( Min( v1, 1.0 ), 0.0 );
468 Standard_Real V2 = Max( Min( v2, 1.0 ), 0.0 );
469 Standard_Real V3 = Max( Min( v3, 1.0 ), 0.0 );
471 Quantity_Color C( V1, V2, V3, Type );
472 SetBackgroundColor( C );
475 //=============================================================================
476 //function : SetBackgroundColor
478 //=============================================================================
479 void V3d_View::SetBackgroundColor(const Quantity_Color &Color)
481 MyBackground.SetColor( Color );
482 if ( MyView->IsDefined() )
483 MyView->SetBackground( MyBackground );
485 if ( !MyLayerMgr.IsNull() )
486 MyLayerMgr->Resized();
489 //=============================================================================
490 //function : SetBackgroundColor
492 //=============================================================================
493 void V3d_View::SetBackgroundColor(const Quantity_NameOfColor Name)
495 Quantity_Color C( Name );
496 SetBackgroundColor( C );
499 //=============================================================================
500 //function : SetBgGradientColors
502 //=============================================================================
503 void V3d_View::SetBgGradientColors( const Quantity_Color& Color1,
504 const Quantity_Color& Color2,
505 const Aspect_GradientFillMethod FillStyle,
506 const Standard_Boolean status)
508 MyGradientBackground.SetColors(Color1, Color2, FillStyle);
509 if ( MyView->IsDefined() )
510 MyView->SetGradientBackground( MyGradientBackground, status );
513 //=============================================================================
514 //function : SetBgGradientColors
516 //=============================================================================
517 void V3d_View::SetBgGradientColors( const Quantity_NameOfColor Color1,
518 const Quantity_NameOfColor Color2,
519 const Aspect_GradientFillMethod FillStyle,
520 const Standard_Boolean status )
522 Quantity_Color C1( Color1 );
523 Quantity_Color C2( Color2 );
524 MyGradientBackground.SetColors( C1, C2, FillStyle );
525 if ( MyView->IsDefined() )
526 MyView->SetGradientBackground( MyGradientBackground, status );
529 //=============================================================================
530 //function : SetBgGradientStyle
532 //=============================================================================
533 void V3d_View::SetBgGradientStyle( const Aspect_GradientFillMethod FillStyle,
534 const Standard_Boolean update)
536 Quantity_Color Color1, Color2;
537 MyGradientBackground.Colors( Color1, Color2 );
538 MyGradientBackground.SetColors( Color1, Color2, FillStyle );
539 if( MyView->IsDefined() )
540 MyView->SetBgGradientStyle( FillStyle, update ) ;
543 //=============================================================================
544 //function : SetBackgroundImage
546 //=============================================================================
547 void V3d_View::SetBackgroundImage( const Standard_CString FileName,
548 const Aspect_FillMethod FillStyle,
549 const Standard_Boolean update )
551 if( MyView->IsDefined() )
552 MyView->SetBackgroundImage( FileName, FillStyle, update ) ;
555 //=============================================================================
556 //function : SetBgImageStyle
558 //=============================================================================
559 void V3d_View::SetBgImageStyle( const Aspect_FillMethod FillStyle,
560 const Standard_Boolean update )
562 if( MyView->IsDefined() )
563 MyView->SetBgImageStyle( FillStyle, update ) ;
566 //=============================================================================
569 //=============================================================================
570 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)
572 Standard_Real D,Nx = Vx,Ny = Vy,Nz = Vz ;
574 D = Sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) ;
575 V3d_BadValue_Raise_if ( D <= 0. , "V3d_View::SetAxis, bad axis");
576 Nx /= D ; Ny /= D ; Nz /= D ;
577 MyDefaultViewPoint.SetCoord(X,Y,Z) ;
578 MyDefaultViewAxis.SetCoord(Nx,Ny,Nz) ;
581 //=============================================================================
582 //function : SetShadingModel
584 //=============================================================================
585 void V3d_View::SetShadingModel(const V3d_TypeOfShadingModel Model)
587 MyViewContext.SetModel((Visual3d_TypeOfModel) Model) ;
588 MyView->SetContext(MyViewContext) ;
591 //=============================================================================
592 //function : SetSurfaceDetail
594 //=============================================================================
595 void V3d_View::SetSurfaceDetail(const V3d_TypeOfSurfaceDetail Model)
597 MyViewContext.SetSurfaceDetail((Visual3d_TypeOfSurfaceDetail) Model) ;
598 MyView->SetContext(MyViewContext) ;
601 //=============================================================================
602 //function : SetTextureEnv
604 //=============================================================================
605 void V3d_View::SetTextureEnv(const Handle(Graphic3d_TextureEnv)& ATexture)
607 MyViewContext.SetTextureEnv(ATexture) ;
608 MyView->SetContext(MyViewContext) ;
611 //=============================================================================
612 //function : SetVisualization
614 //=============================================================================
615 void V3d_View::SetVisualization(const V3d_TypeOfVisualization Mode)
617 MyViewContext.SetVisualization((Visual3d_TypeOfVisualization) Mode);
618 MyView->SetContext(MyViewContext) ;
621 //=============================================================================
622 //function : SetFront
624 //=============================================================================
625 void V3d_View::SetFront()
627 gp_Ax3 a = MyViewer->PrivilegedPlane();
628 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
630 a.Direction().Coord(vx,vy,vz);
631 a.YDirection().Coord(xu,yu,zu);
632 a.Location().Coord(xo,yo,zo);
634 myCamera->SetCenter (gp_Pnt (xo, yo, zo));
636 myCamera->SetDirection (gp_Dir (vx, vy, vz));
638 myCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
639 myCamera->SetUp (gp_Dir (xu, yu, zu));
643 SwitchSetFront = !SwitchSetFront;
648 //=============================================================================
651 //=============================================================================
652 void V3d_View::Rotate (const Standard_Real ax,
653 const Standard_Real ay,
654 const Standard_Real az,
655 const Standard_Boolean Start)
657 Standard_Real Ax = ax;
658 Standard_Real Ay = ay;
659 Standard_Real Az = az;
661 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
662 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
663 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
664 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
665 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
666 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
670 myCamStartOpUp = myCamera->Up();
671 myCamStartOpEye = myCamera->Eye();
672 myCamStartOpCenter = myCamera->Center();
675 myCamera->SetUp (myCamStartOpUp);
676 myCamera->SetEye (myCamStartOpEye);
677 myCamera->SetCenter (myCamStartOpCenter);
679 // rotate camera around 3 initial axes
680 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
681 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
682 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
683 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
685 gp_Trsf aRot[3], aTrsf;
686 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
687 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
688 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
689 aTrsf.Multiply (aRot[0]);
690 aTrsf.Multiply (aRot[1]);
691 aTrsf.Multiply (aRot[2]);
693 myCamera->Transform (aTrsf);
700 //=============================================================================
703 //=============================================================================
704 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
705 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
708 Standard_Real Ax = ax ;
709 Standard_Real Ay = ay ;
710 Standard_Real Az = az ;
712 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
713 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
714 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
715 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
716 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
717 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
721 myGravityReferencePoint.SetCoord (X, Y, Z);
722 myCamStartOpUp = myCamera->Up();
723 myCamStartOpEye = myCamera->Eye();
724 myCamStartOpCenter = myCamera->Center();
727 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
729 myCamera->SetUp (myCamStartOpUp);
730 myCamera->SetEye (myCamStartOpEye);
731 myCamera->SetCenter (myCamStartOpCenter);
733 // rotate camera around 3 initial axes
734 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
736 gp_Dir aZAxis (myCamera->Direction().Reversed());
737 gp_Dir aYAxis (myCamera->Up());
738 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
740 gp_Trsf aRot[3], aTrsf;
741 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
742 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
743 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
744 aTrsf.Multiply (aRot[0]);
745 aTrsf.Multiply (aRot[1]);
746 aTrsf.Multiply (aRot[2]);
748 myCamera->Transform (aTrsf);
755 //=============================================================================
758 //=============================================================================
759 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
763 Rotate(angle,0.,0.,Start);
766 Rotate(0.,angle,0.,Start);
769 Rotate(0.,0.,angle,Start);
774 //=============================================================================
777 //=============================================================================
778 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
779 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
781 Standard_Real Angle = angle ;
783 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
784 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
788 myGravityReferencePoint.SetCoord (X, Y, Z);
789 myCamStartOpUp = myCamera->Up();
790 myCamStartOpEye = myCamera->Eye();
791 myCamStartOpCenter = myCamera->Center();
795 myViewAxis.SetCoord(1.,0.,0.) ;
798 myViewAxis.SetCoord(0.,1.,0.) ;
801 myViewAxis.SetCoord(0.,0.,1.) ;
805 myCamStartOpUp = myCamera->Up();
806 myCamStartOpEye = myCamera->Eye();
807 myCamStartOpCenter = myCamera->Center();
810 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
812 myCamera->SetUp (myCamStartOpUp);
813 myCamera->SetEye (myCamStartOpEye);
814 myCamera->SetCenter (myCamStartOpCenter);
816 // rotate camera around passed axis
818 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
819 gp_Dir aRAxis ((Axe == V3d_X) ? 1.0 : 0.0,
820 (Axe == V3d_Y) ? 1.0 : 0.0,
821 (Axe == V3d_Z) ? 1.0 : 0.0);
823 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
824 myCamera->Transform (aRotation);
831 //=============================================================================
834 //=============================================================================
835 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
837 Standard_Real Angle = angle;
839 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
840 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
843 myCamStartOpUp = myCamera->Up();
844 myCamStartOpEye = myCamera->Eye();
845 myCamStartOpCenter = myCamera->Center();
848 const Graphic3d_Vertex& aPnt = MyDefaultViewPoint;
849 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
851 myCamera->SetUp (myCamStartOpUp);
852 myCamera->SetEye (myCamStartOpEye);
853 myCamera->SetCenter (myCamStartOpCenter);
856 gp_Pnt aRCenter (aPnt.X(), aPnt.Y(), aPnt.Z());
857 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
858 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
859 myCamera->Transform (aRotation);
866 //=============================================================================
869 //=============================================================================
870 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
872 Standard_Real Ax = ax;
873 Standard_Real Ay = ay;
874 Standard_Real Az = az;
876 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
877 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
878 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
879 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
880 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
881 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
884 myCamStartOpUp = myCamera->Up();
885 myCamStartOpEye = myCamera->Eye();
886 myCamStartOpCenter = myCamera->Center();
889 myCamera->SetUp (myCamStartOpUp);
890 myCamera->SetEye (myCamStartOpEye);
891 myCamera->SetCenter (myCamStartOpCenter);
893 // rotate camera around 3 initial axes
894 gp_Pnt aRCenter = myCamera->Eye();
895 gp_Dir aZAxis (myCamera->Direction().Reversed());
896 gp_Dir aYAxis (myCamera->Up());
897 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
899 gp_Trsf aRot[3], aTrsf;
900 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
901 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
902 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
903 aTrsf.Multiply (aRot[0]);
904 aTrsf.Multiply (aRot[1]);
905 aTrsf.Multiply (aRot[2]);
907 myCamera->Transform (aTrsf);
914 //=============================================================================
917 //=============================================================================
918 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
922 Turn(angle,0.,0.,Start);
925 Turn(0.,angle,0.,Start);
928 Turn(0.,0.,angle,Start);
933 //=============================================================================
936 //=============================================================================
937 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
939 Standard_Real Angle = angle ;
941 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
942 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
945 myCamStartOpUp = myCamera->Up();
946 myCamStartOpEye = myCamera->Eye();
947 myCamStartOpCenter = myCamera->Center();
950 myCamera->SetUp (myCamStartOpUp);
951 myCamera->SetEye (myCamStartOpEye);
952 myCamera->SetCenter (myCamStartOpCenter);
954 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
957 gp_Pnt aRCenter = myCamera->Eye();
958 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
959 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
960 myCamera->Transform (aRotation);
967 //=============================================================================
968 //function : SetTwist
970 //=============================================================================
971 void V3d_View::SetTwist(const Standard_Real angle)
973 Standard_Real Angle = angle ;
974 Standard_Boolean TheStatus;
976 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
977 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
979 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
982 anUp = gp_Dir (0.0, 0.0, 1.0);
984 TheStatus = ScreenAxis(aReferencePlane, anUp,
985 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
987 anUp = gp_Dir (0.0, 1.0, 0.0);
988 TheStatus = ScreenAxis(aReferencePlane, anUp,
989 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
992 anUp = gp_Dir (1.0, 0.0, 0.0);
993 TheStatus = ScreenAxis(aReferencePlane, anUp,
994 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
997 V3d_BadValue_Raise_if( !TheStatus,"V3d_ViewSetTwist, alignment of Eye,At,Up,");
999 gp_Pnt aRCenter = myCamera->Center();
1000 gp_Dir aZAxis (myCamera->Direction().Reversed());
1003 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
1005 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1006 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1008 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1009 myCamera->Transform (aTrsf);
1016 //=============================================================================
1019 //=============================================================================
1020 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1022 Standard_Real aTwistBefore = Twist();
1024 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1026 myCamera->SetEye (gp_Pnt (X, Y, Z));
1027 SetTwist (aTwistBefore);
1031 SetImmediateUpdate (wasUpdateEnabled);
1036 //=============================================================================
1037 //function : SetDepth
1039 //=============================================================================
1040 void V3d_View::SetDepth(const Standard_Real Depth)
1042 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1046 // Move eye using center (target) as anchor.
1047 myCamera->SetDistance (Depth);
1051 // Move the view ref point instead of the eye.
1052 gp_Vec aDir (myCamera->Direction());
1053 gp_Pnt aCameraEye = myCamera->Eye();
1054 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1056 myCamera->SetCenter (aCameraCenter);
1064 //=============================================================================
1065 //function : SetProj
1067 //=============================================================================
1068 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1070 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1071 "V3d_View::SetProj, null projection vector");
1073 Standard_Real aTwistBefore = Twist();
1075 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1077 myCamera->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1079 SetTwist(aTwistBefore);
1083 SetImmediateUpdate (wasUpdateEnabled);
1088 //=============================================================================
1089 //function : SetProj
1091 //=============================================================================
1092 void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1094 Standard_Real Xpn=0;
1095 Standard_Real Ypn=0;
1096 Standard_Real Zpn=0;
1098 switch (Orientation) {
1109 const Graphic3d_Vector& aBck = V3d::GetProjAxis (Orientation);
1111 // retain camera panning from origin when switching projection
1112 gp_Pnt anOriginVCS = myCamera->ConvertWorld2View (gp::Origin());
1113 Standard_Real aPanX = anOriginVCS.X();
1114 Standard_Real aPanY = anOriginVCS.Y();
1116 myCamera->SetCenter (gp_Pnt (0, 0, 0));
1117 myCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1118 myCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
1119 myCamera->OrthogonalizeUp();
1121 Panning (aPanX, aPanY);
1128 //=============================================================================
1131 //=============================================================================
1132 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1134 Standard_Real aTwistBefore = Twist();
1136 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1138 myCamera->SetCenter (gp_Pnt (X, Y, Z));
1140 SetTwist (aTwistBefore);
1144 SetImmediateUpdate (wasUpdateEnabled);
1149 //=============================================================================
1152 //=============================================================================
1153 void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standard_Real Vz)
1155 Standard_Boolean TheStatus ;
1156 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0. ,
1157 "V3d_View::SetUp, nullUp vector");
1159 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1160 gp_Dir anUp (Vx, Vy, Vz);
1162 TheStatus = ScreenAxis(aReferencePlane,anUp,
1163 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1165 anUp = gp_Dir (0.0, 0.0, 1.0);
1166 TheStatus = ScreenAxis(aReferencePlane,anUp,
1167 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1170 anUp = gp_Dir (0.0, 1.0, 0.0);
1171 TheStatus = ScreenAxis(aReferencePlane,anUp,
1172 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1175 anUp = gp_Dir (1.0, 0.0, 0.0);
1176 TheStatus = ScreenAxis(aReferencePlane,anUp,
1177 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1179 V3d_BadValue_Raise_if( !TheStatus,"V3d_View::Setup, alignment of Eye,At,Up");
1181 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1182 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1184 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1191 //=============================================================================
1194 //=============================================================================
1195 void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
1197 Standard_Boolean TheStatus ;
1199 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1202 const Graphic3d_Vector& aViewReferenceUp = V3d::GetProjAxis(Orientation) ;
1203 anUp = gp_Dir (aViewReferenceUp.X(), aViewReferenceUp.Y(), aViewReferenceUp.Z());
1205 TheStatus = ScreenAxis(aReferencePlane,anUp,
1206 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1208 anUp = gp_Dir (0.,0.,1.);
1209 TheStatus = ScreenAxis(aReferencePlane,anUp,
1210 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1213 anUp = gp_Dir (0.,1.,0.);
1214 TheStatus = ScreenAxis(aReferencePlane,anUp,
1215 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1218 anUp = gp_Dir (1.,0.,0.);
1219 TheStatus = ScreenAxis(aReferencePlane,anUp,
1220 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1222 V3d_BadValue_Raise_if( !TheStatus, "V3d_View::SetUp, alignment of Eye,At,Up");
1224 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1225 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1227 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1234 //=============================================================================
1235 //function : SetViewOrientationDefault
1237 //=============================================================================
1238 void V3d_View::SetViewOrientationDefault()
1240 MyView->SetViewOrientationDefault() ;
1245 //=============================================================================
1246 //function : ResetViewOrientation
1248 //=============================================================================
1249 void V3d_View::ResetViewOrientation()
1251 MyView->ViewOrientationReset() ;
1256 //=============================================================================
1259 //=============================================================================
1260 void V3d_View::Reset( const Standard_Boolean update )
1262 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1264 if (!aDefaultCamera.IsNull())
1266 myCamera->CopyMappingData (aDefaultCamera);
1267 myCamera->CopyOrientationData (aDefaultCamera);
1272 SwitchSetFront = Standard_False;
1274 if( myImmediateUpdate || update ) Update();
1277 //=======================================================================
1278 //function : SetCenter
1280 //=======================================================================
1281 void V3d_View::SetCenter (const Standard_Integer theXp,
1282 const Standard_Integer theYp)
1284 Standard_Real aXv, aYv;
1285 Convert (theXp, theYp, aXv, aYv);
1286 Translate (myCamera, aXv, aYv);
1291 //=============================================================================
1292 //function : SetSize
1294 //=============================================================================
1295 void V3d_View::SetSize (const Standard_Real theSize)
1297 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1299 myCamera->SetScale (myCamera->Aspect() >= 1.0 ? theSize / myCamera->Aspect() : theSize);
1306 //=============================================================================
1307 //function : SetZSize
1309 //=============================================================================
1310 void V3d_View::SetZSize(const Standard_Real Size)
1312 Standard_Real Zmax = Size/2.;
1314 Standard_Real aDistance = myCamera->Distance();
1320 Standard_Real Front = MyViewContext.ZClippingFrontPlane();
1321 Standard_Real Back = MyViewContext.ZClippingBackPlane();
1323 // ShortReal precision factor used to add meaningful tolerance to
1324 // ZNear, ZFar values in order to avoid equality after type conversion
1325 // to ShortReal matrices type.
1326 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1328 Standard_Real aZFar = Zmax + aDistance * 2.0;
1329 Standard_Real aZNear = -Zmax + aDistance;
1330 aZNear -= Abs (aZNear) * aPrecision;
1331 aZFar += Abs (aZFar) * aPrecision;
1333 if (!myCamera->IsOrthographic())
1335 if (aZFar < aPrecision)
1337 // Invalid case when both values are negative
1338 aZNear = aPrecision;
1339 aZFar = aPrecision * 2.0;
1341 else if (aZNear < Abs (aZFar) * aPrecision)
1343 // Z is less than 0.0, try to fix it using any appropriate z-scale
1344 aZNear = Abs (aZFar) * aPrecision;
1348 // If range is too small
1349 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1351 aZFar = aZNear + Abs (aZFar) * aPrecision;
1354 myCamera->SetZRange (aZNear, aZFar);
1356 if (MyViewContext.FrontZClippingIsOn() ||
1357 MyViewContext.BackZClippingIsOn())
1359 MyViewContext.SetZClippingFrontPlane (Front);
1360 MyViewContext.SetZClippingBackPlane (Back);
1361 MyView->SetContext (MyViewContext);
1365 //=============================================================================
1366 //function : SetZoom
1368 //=============================================================================
1369 void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1371 V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
1375 myCamStartOpEye = myCamera->Eye();
1376 myCamStartOpCenter = myCamera->Center();
1379 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
1380 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
1382 // ensure that zoom will not be too small or too big
1383 Standard_Real coef = Coef;
1384 if (aViewWidth < coef * Precision::Confusion())
1386 coef = aViewWidth / Precision::Confusion();
1388 else if (aViewWidth > coef * 1e12)
1390 coef = aViewWidth / 1e12;
1392 if (aViewHeight < coef * Precision::Confusion())
1394 coef = aViewHeight / Precision::Confusion();
1396 else if (aViewHeight > coef * 1e12)
1398 coef = aViewHeight / 1e12;
1401 myCamera->SetEye (myCamStartOpEye);
1402 myCamera->SetCenter (myCamStartOpCenter);
1403 myCamera->SetScale (myCamera->Scale() / Coef);
1409 //=============================================================================
1410 //function : SetScale
1412 //=============================================================================
1413 void V3d_View::SetScale( const Standard_Real Coef )
1415 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1417 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1419 // Strange behavior for the sake of compatibility.
1420 if (!aDefaultCamera.IsNull())
1422 myCamera->SetAspect (aDefaultCamera->Aspect());
1423 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1424 myCamera->SetScale (aDefaultScale / Coef);
1428 myCamera->SetScale (myCamera->Scale() / Coef);
1436 //=============================================================================
1437 //function : SetAxialScale
1439 //=============================================================================
1440 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1442 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1444 myCamera->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1448 //=============================================================================
1451 //=============================================================================
1452 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1454 Standard_ASSERT_RAISE (theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1456 if (MyView->NumberOfDisplayedStructures() == 0)
1461 if (!FitMinMax (myCamera, MyView->MinMaxValues(), theMargin, 10.0 * Precision::Confusion()))
1468 if (myImmediateUpdate || theToUpdate)
1474 //=============================================================================
1475 //function : DepthFitAll
1477 //=============================================================================
1478 void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1479 const Quantity_Coefficient Margin)
1481 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1482 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1483 Standard_Real Dx,Dy,Dz,Size;
1485 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1487 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1492 Bnd_Box aBox = MyView->MinMaxValues();
1498 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1499 MyView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
1500 MyView->Projects(Xmax,Ymax,Zmax,U1,V1,W1) ;
1501 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1502 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1503 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1504 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
1505 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1506 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1507 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1508 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
1509 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1510 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1511 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1512 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
1513 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1514 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1515 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1516 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
1517 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1518 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1519 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1520 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
1521 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1522 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1523 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1524 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
1525 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1526 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1527 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1530 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1531 Dz = 2.*Wmax + Margin * Wmax;
1533 // Compute depth value
1534 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1535 Dx += Margin * Dx; Dy += Margin * Dy;
1536 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1539 SetDepth( Aspect * Size / 2.);
1545 //=============================================================================
1548 //=============================================================================
1549 void V3d_View::FitAll(const Standard_Real theMinXv,
1550 const Standard_Real theMinYv,
1551 const Standard_Real theMaxXv,
1552 const Standard_Real theMaxYv)
1554 FitAll (MyWindow, theMinXv, theMinYv, theMaxXv, theMaxYv);
1557 //=============================================================================
1558 //function : WindowFitAll
1560 //=============================================================================
1561 void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1562 const Standard_Integer Ymin,
1563 const Standard_Integer Xmax,
1564 const Standard_Integer Ymax)
1566 WindowFit(Xmin,Ymin,Xmax,Ymax);
1569 //=======================================================================
1570 //function : WindowFit
1572 //=======================================================================
1573 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1574 const Standard_Integer theMinYp,
1575 const Standard_Integer theMaxXp,
1576 const Standard_Integer theMaxYp)
1578 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1580 if (!myCamera->IsOrthographic())
1582 // normalize view coordiantes
1583 Standard_Integer aWinWidth, aWinHeight;
1584 MyWindow->Size (aWinWidth, aWinHeight);
1586 // z coordinate of camera center
1587 Standard_Real aDepth = myCamera->Project (myCamera->Center()).Z();
1589 // camera projection coordinate are in NDC which are normalized [-1, 1]
1590 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1591 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1592 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1593 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1595 // compute camera panning
1596 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1597 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1598 gp_Pnt aPanTo = myCamera->ConvertProj2View (aFitCenter);
1599 gp_Pnt aPanFrom = myCamera->ConvertProj2View (aScreenCenter);
1600 gp_Vec aPanVec (aPanFrom, aPanTo);
1602 // compute section size
1603 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1604 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1605 gp_Pnt aViewBotLeft = myCamera->ConvertProj2View (aFitBotLeft);
1606 gp_Pnt aViewTopRight = myCamera->ConvertProj2View (aFitTopRight);
1608 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1609 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1611 Translate (myCamera, aPanVec.X(), -aPanVec.Y());
1612 Scale (myCamera, aUSize, aVSize);
1617 Standard_Real aX1, aY1, aX2, aY2;
1618 Convert (theMinXp, theMinYp, aX1, aY1);
1619 Convert (theMaxXp, theMaxYp, aX2, aY2);
1620 FitAll (aX1, aY1, aX2, aY2);
1623 SetImmediateUpdate (wasUpdateEnabled);
1628 //=======================================================================
1629 //function : SetViewMappingDefault
1631 //=======================================================================
1632 void V3d_View::SetViewMappingDefault()
1634 MyView->SetViewMappingDefault();
1639 //=======================================================================
1640 //function : ResetViewMapping
1642 //=======================================================================
1643 void V3d_View::ResetViewMapping()
1645 MyView->ViewMappingReset();
1650 //=======================================================================
1651 //function : ConvertToGrid
1653 //=======================================================================
1654 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1655 const Standard_Integer Yp,
1658 Standard_Real& Zg) const
1660 Graphic3d_Vertex aVrp;
1661 Standard_Real anX, anY, aZ;
1662 Convert (Xp, Yp, anX, anY, aZ);
1663 aVrp.SetCoord (anX, anY, aZ);
1665 if( MyViewer->Grid()->IsActive() ) {
1666 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1667 aNewVrp.Coord (Xg,Yg,Zg) ;
1669 aVrp.Coord (Xg,Yg,Zg) ;
1672 //=======================================================================
1673 //function : ConvertToGrid
1675 //=======================================================================
1676 void V3d_View::ConvertToGrid(const Standard_Real X,
1677 const Standard_Real Y,
1678 const Standard_Real Z,
1681 Standard_Real& Zg) const
1683 if( MyViewer->Grid()->IsActive() ) {
1684 Graphic3d_Vertex aVrp (X,Y,Z) ;
1685 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1686 aNewVrp.Coord(Xg,Yg,Zg) ;
1688 Xg = X; Yg = Y; Zg = Z;
1692 //=======================================================================
1693 //function : Convert
1695 //=======================================================================
1696 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1698 Standard_Integer aDxw, aDyw ;
1700 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1702 MyWindow->Size (aDxw, aDyw);
1703 Standard_Real aValue;
1705 gp_Pnt aViewDims = myCamera->ViewDimensions();
1706 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1711 //=======================================================================
1712 //function : Convert
1714 //=======================================================================
1715 void V3d_View::Convert(const Standard_Integer Xp,
1716 const Standard_Integer Yp,
1718 Standard_Real& Yv) const
1720 Standard_Integer aDxw, aDyw;
1722 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1724 MyWindow->Size (aDxw, aDyw);
1726 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1727 aPoint = myCamera->ConvertProj2View (aPoint);
1733 //=======================================================================
1734 //function : Convert
1736 //=======================================================================
1737 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1739 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1741 Standard_Integer aDxw, aDyw;
1742 MyWindow->Size (aDxw, aDyw);
1744 gp_Pnt aViewDims = myCamera->ViewDimensions();
1745 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1750 //=======================================================================
1751 //function : Convert
1753 //=======================================================================
1754 void V3d_View::Convert(const Standard_Real Xv,
1755 const Standard_Real Yv,
1756 Standard_Integer& Xp,
1757 Standard_Integer& Yp) const
1759 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1761 Standard_Integer aDxw, aDyw;
1762 MyWindow->Size (aDxw, aDyw);
1764 gp_Pnt aPoint (Xv, Yv, 0.0);
1765 aPoint = myCamera->ConvertView2Proj (aPoint);
1766 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1768 Xp = RealToInt (aPoint.X());
1769 Yp = RealToInt (aPoint.Y());
1772 //=======================================================================
1773 //function : Convert
1775 //=======================================================================
1776 void V3d_View::Convert(const Standard_Integer Xp,
1777 const Standard_Integer Yp,
1780 Standard_Real& Z) const
1782 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1783 Standard_Integer aHeight, aWidth;
1784 MyWindow->Size (aWidth, aHeight);
1786 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1787 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1788 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1790 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
1796 Graphic3d_Vertex aVrp;
1797 aVrp.SetCoord (X, Y, Z);
1799 if( MyViewer->Grid()->IsActive() ) {
1800 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1801 aNewVrp.Coord (X, Y, Z) ;
1805 //=======================================================================
1806 //function : ConvertWithProj
1808 //=======================================================================
1809 void V3d_View::ConvertWithProj(const Standard_Integer Xp,
1810 const Standard_Integer Yp,
1816 Standard_Real& Dz) const
1818 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
1819 Standard_Integer aHeight, aWidth;
1820 MyWindow->Size (aWidth, aHeight);
1822 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1823 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1824 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1826 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
1832 Graphic3d_Vertex aVrp;
1833 aVrp.SetCoord (X, Y, Z);
1835 aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1837 Graphic3d_Vec3d aNormDir;
1838 aNormDir.x() = X - aResult.X();
1839 aNormDir.y() = Y - aResult.Y();
1840 aNormDir.z() = Z - aResult.Z();
1841 aNormDir.Normalize();
1847 if( MyViewer->Grid()->IsActive() ) {
1848 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1849 aNewVrp.Coord (X, Y, Z) ;
1853 //=======================================================================
1854 //function : Convert
1856 //=======================================================================
1857 void V3d_View::Convert(const Standard_Real X,
1858 const Standard_Real Y,
1859 const Standard_Real Z,
1860 Standard_Integer& Xp,
1861 Standard_Integer& Yp) const
1863 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
1864 Standard_Integer aHeight, aWidth;
1865 MyWindow->Size (aWidth, aHeight);
1867 gp_Pnt aPoint = myCamera->Project (gp_Pnt (X, Y, Z));
1869 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1870 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1873 //=======================================================================
1874 //function : Project
1876 //=======================================================================
1877 void V3d_View::Project(const Standard_Real X,
1878 const Standard_Real Y,
1879 const Standard_Real Z,
1881 Standard_Real &Yp) const
1884 MyView->Projects (X, Y, Z, Xp, Yp, Zp);
1887 //=======================================================================
1888 //function : BackgroundColor
1890 //=======================================================================
1891 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1894 Standard_Real& V3) const
1896 Quantity_Color C = BackgroundColor() ;
1897 C.Values(V1,V2,V3,Type) ;
1900 //=======================================================================
1901 //function : BackgroundColor
1903 //=======================================================================
1904 Quantity_Color V3d_View::BackgroundColor() const
1906 return MyBackground.Color() ;
1909 //=======================================================================
1910 //function : GradientBackgroundColors
1912 //=======================================================================
1913 void V3d_View::GradientBackgroundColors(Quantity_Color& Color1,Quantity_Color& Color2) const
1915 MyGradientBackground.Colors(Color1, Color2);
1918 //=======================================================================
1919 //function : GradientBackground
1921 //=======================================================================
1922 Aspect_GradientBackground V3d_View::GradientBackground() const
1924 return MyGradientBackground;
1927 //=======================================================================
1930 //=======================================================================
1931 Standard_Real V3d_View::Scale() const
1933 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1935 Standard_Real aCameraScale;
1937 // Strange behavior for the sake of compatibility.
1938 if (!aDefaultCamera.IsNull())
1940 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1941 aCameraScale = aDefaultScale / myCamera->Scale();
1945 aCameraScale = myCamera->Scale();
1948 return aCameraScale;
1951 //=======================================================================
1952 //function : AxialScale
1954 //=======================================================================
1955 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1957 gp_Pnt anAxialScale = myCamera->AxialScale();
1958 Sx = anAxialScale.X();
1959 Sy = anAxialScale.Y();
1960 Sz = anAxialScale.Z();
1963 //=======================================================================
1966 //=======================================================================
1967 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1969 gp_Pnt aViewDims = myCamera->ViewDimensions();
1971 Width = aViewDims.X();
1972 Height = aViewDims.Y();
1975 //=======================================================================
1978 //=======================================================================
1979 Standard_Real V3d_View::ZSize() const
1981 gp_Pnt aViewDims = myCamera->ViewDimensions();
1983 return aViewDims.Z();
1986 //=======================================================================
1989 //=======================================================================
1990 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
1991 Standard_Real& Vmin,
1992 Standard_Real& Umax,
1993 Standard_Real& Vmax) const
1995 Standard_Real Wmin,Wmax,U,V,W ;
1996 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
1998 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2001 Bnd_Box aBox = MyView->MinMaxValues();
2002 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2003 MyView->Projects(Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
2004 MyView->Projects(Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
2005 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
2006 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2007 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2008 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2009 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
2010 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2011 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2012 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2013 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
2014 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2015 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2016 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2017 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
2018 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2019 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2020 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2021 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
2022 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2023 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2024 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2025 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
2026 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2027 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2028 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2033 //=======================================================================
2036 //=======================================================================
2037 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
2038 Standard_Real& Ymin,
2039 Standard_Real& Zmin,
2040 Standard_Real& Xmax,
2041 Standard_Real& Ymax,
2042 Standard_Real& Zmax) const
2045 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
2046 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2049 Bnd_Box aBox = MyView->MinMaxValues();
2050 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2055 //=======================================================================
2056 //function : Gravity
2058 //=======================================================================
2059 void V3d_View::Gravity (Standard_Real& theX,
2060 Standard_Real& theY,
2061 Standard_Real& theZ) const
2063 Graphic3d_MapOfStructure aSetOfStructures;
2064 MyView->DisplayedStructures (aSetOfStructures);
2066 Standard_Boolean hasSelection = Standard_False;
2067 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2068 aStructIter.More(); aStructIter.Next())
2070 if (aStructIter.Key()->IsHighlighted()
2071 && aStructIter.Key()->IsVisible())
2073 hasSelection = Standard_True;
2078 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
2079 Standard_Integer aNbPoints = 0;
2080 gp_XYZ aResult (0.0, 0.0, 0.0);
2081 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2082 aStructIter.More(); aStructIter.Next())
2084 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2085 if (!aStruct->IsVisible()
2086 || (hasSelection && !aStruct->IsHighlighted())
2087 || aStruct->IsEmpty())
2092 Bnd_Box aBox = aStruct->MinMaxValues();
2093 if (aBox.IsVoid() || aStruct->IsInfinite())
2098 // use camera projection to find gravity point
2099 aBox.Get (Xmin, Ymin, Zmin,
2101 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2103 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2104 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2105 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2106 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2109 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2111 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2112 const gp_Pnt aProjected = myCamera->Project (aBndPnt);
2113 if (Abs (aProjected.X()) <= 1.0
2114 && Abs (aProjected.Y()) <= 1.0)
2116 aResult += aBndPnt.XYZ();
2124 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2125 aStructIter.More(); aStructIter.Next())
2127 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2128 if (aStruct->IsEmpty())
2133 Bnd_Box aBox = aStruct->MinMaxValues();
2134 if (aBox.IsVoid() || aStruct->IsInfinite())
2139 aBox.Get (Xmin, Ymin, Zmin,
2141 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2143 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2144 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2145 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2146 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2149 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2151 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2152 aResult += aBndPnt.XYZ();
2160 aResult /= aNbPoints;
2167 //=======================================================================
2170 //=======================================================================
2171 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2173 gp_Pnt aCameraEye = myCamera->Eye();
2179 //=============================================================================
2180 //function : FocalReferencePoint
2182 //=============================================================================
2183 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2188 //=============================================================================
2189 //function : ProjReferenceAxe
2191 //=============================================================================
2192 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2193 const Standard_Integer Ypix,
2199 Standard_Real& VZ) const
2201 Standard_Real Xo,Yo,Zo;
2203 Convert (Xpix, Ypix, XP, YP, ZP);
2204 if ( Type() == V3d_PERSPECTIVE )
2206 FocalReferencePoint (Xo,Yo,Zo);
2217 //=============================================================================
2220 //=============================================================================
2221 Standard_Real V3d_View::Depth() const
2223 return myCamera->Distance();
2226 //=============================================================================
2229 //=============================================================================
2230 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2232 gp_Dir aCameraDir = myCamera->Direction().Reversed();
2233 Dx = aCameraDir.X();
2234 Dy = aCameraDir.Y();
2235 Dz = aCameraDir.Z();
2238 //=============================================================================
2241 //=============================================================================
2242 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2244 gp_Pnt aCameraCenter = myCamera->Center();
2245 X = aCameraCenter.X();
2246 Y = aCameraCenter.Y();
2247 Z = aCameraCenter.Z();
2250 //=============================================================================
2253 //=============================================================================
2254 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2256 gp_Dir aCameraUp = myCamera->Up();
2262 //=============================================================================
2265 //=============================================================================
2266 Standard_Real V3d_View::Twist() const
2268 Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2269 Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
2270 Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
2271 Standard_Boolean TheStatus ;
2273 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
2277 anUp = gp_Dir (0.,0.,1.) ;
2278 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2280 anUp = gp_Dir (0.,1.,0.) ;
2281 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2284 anUp = gp_Dir (1.,0.,0.) ;
2285 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2287 Yaxis.Coord(X0,Y0,Z0) ;
2290 /* Compute Cross Vector From Up & Origin */
2291 pvx = Y0*Zup - Z0*Yup ;
2292 pvy = Z0*Xup - X0*Zup ;
2293 pvz = X0*Yup - Y0*Xup ;
2294 pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2295 sca = X0*Xup + Y0*Yup + Z0*Zup ;
2298 if( angle > 1. ) angle = 1. ;
2299 else if( angle < -1. ) angle = -1. ;
2300 angle = asin(angle) ;
2301 if( sca < 0. ) angle = M_PI - angle ;
2302 if( angle > 0. && angle < M_PI ) {
2303 sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2304 if( sca < 0. ) angle = DEUXPI - angle ;
2309 //=============================================================================
2310 //function : ShadingModel
2312 //=============================================================================
2313 V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2315 V3d_TypeOfShadingModel SM = (V3d_TypeOfShadingModel)MyViewContext.Model() ;
2319 //=============================================================================
2320 //function : SurfaceDetail
2322 //=============================================================================
2323 V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
2325 V3d_TypeOfSurfaceDetail SM = (V3d_TypeOfSurfaceDetail)MyViewContext.SurfaceDetail() ;
2329 //=============================================================================
2330 //function : TextureEnv
2332 //=============================================================================
2333 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2335 Handle(Graphic3d_TextureEnv) SM = MyViewContext.TextureEnv() ;
2339 //=============================================================================
2340 //function : Visualization
2342 //=============================================================================
2343 V3d_TypeOfVisualization V3d_View::Visualization() const
2345 V3d_TypeOfVisualization V =
2346 (V3d_TypeOfVisualization)MyViewContext.Visualization() ;
2350 //=============================================================================
2351 //function : Antialiasing
2353 //=============================================================================
2354 Standard_Boolean V3d_View::Antialiasing() const
2356 Standard_Boolean A = MyViewContext.AliasingIsOn() ;
2360 //=============================================================================
2363 //=============================================================================
2364 Handle(V3d_Viewer) V3d_View::Viewer() const
2369 //=============================================================================
2370 //function : IfWindow
2372 //=============================================================================
2373 Standard_Boolean V3d_View::IfWindow() const
2375 Standard_Boolean TheStatus = MyView->IsDefined() ;
2379 //=============================================================================
2382 //=============================================================================
2383 Handle(Aspect_Window) V3d_View::Window() const
2388 //=============================================================================
2391 //=============================================================================
2392 V3d_TypeOfView V3d_View::Type() const
2394 return myCamera->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2397 //=============================================================================
2398 //function : SetFocale
2400 //=============================================================================
2401 void V3d_View::SetFocale( const Standard_Real focale )
2403 if (myCamera->IsOrthographic())
2408 Standard_Real aFOVyRad = ATan (focale / (myCamera->Distance() * 2.0));
2410 myCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2415 //=============================================================================
2418 //=============================================================================
2419 Standard_Real V3d_View::Focale() const
2421 if (myCamera->IsOrthographic())
2426 return myCamera->Distance() * 2.0 * Tan(myCamera->FOVy() * M_PI / 360.0);
2429 //=============================================================================
2432 //=============================================================================
2433 Handle(Visual3d_View) V3d_View::View() const
2438 //=============================================================================
2439 //function : ScreenAxis
2441 //=============================================================================
2442 Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2444 Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2445 Standard_Real dx1, dy1, dz1, xx, yy, zz;
2447 Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2448 Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2449 xx = Yup*Zpn - Zup*Ypn;
2450 yy = Zup*Xpn - Xup*Zpn;
2451 zz = Xup*Ypn - Yup*Xpn;
2452 Xaxe.SetCoord (xx, yy, zz);
2453 if (Xaxe.LengthZero()) return Standard_False;
2455 Xaxe.Coord(dx1, dy1, dz1);
2456 xx = Ypn*dz1 - Zpn*dy1;
2457 yy = Zpn*dx1 - Xpn*dz1;
2458 zz = Xpn*dy1 - Ypn*dx1;
2459 Yaxe.SetCoord (xx, yy, zz) ;
2460 if (Yaxe.LengthZero()) return Standard_False;
2463 Zaxe.SetCoord (Xpn, Ypn, Zpn);
2465 return Standard_True;
2468 //=============================================================================
2469 //function : TrsPoint
2471 //=============================================================================
2472 Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2474 Graphic3d_Vertex PP ;
2475 Standard_Real X,Y,Z,XX,YY,ZZ ;
2478 Standard_Integer lr, ur, lc, uc;
2479 lr = Matrix.LowerRow ();
2480 ur = Matrix.UpperRow ();
2481 lc = Matrix.LowerCol ();
2482 uc = Matrix.UpperCol ();
2483 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
2485 PP.SetCoord(X,Y,Z) ;
2489 XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2490 Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2492 YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2493 Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2495 ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2496 Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2497 PP.SetCoord(XX,YY,ZZ) ;
2501 //=======================================================================
2504 //=======================================================================
2505 void V3d_View::Pan (const Standard_Integer theDXp,
2506 const Standard_Integer theDYp,
2507 const Quantity_Factor theZoomFactor,
2508 const Standard_Boolean theToStart)
2510 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2513 //=======================================================================
2514 //function : Panning
2516 //=======================================================================
2517 void V3d_View::Panning (const Standard_Real theDXv,
2518 const Standard_Real theDYv,
2519 const Quantity_Factor theZoomFactor,
2520 const Standard_Boolean theToStart)
2522 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2526 myCamStartOpEye = myCamera->Eye();
2527 myCamStartOpCenter = myCamera->Center();
2530 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2532 gp_Pnt aViewDims = myCamera->ViewDimensions();
2534 myCamera->SetEye (myCamStartOpEye);
2535 myCamera->SetCenter (myCamStartOpCenter);
2536 Translate (myCamera, -theDXv, -theDYv);
2537 Scale (myCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2539 SetImmediateUpdate (wasUpdateEnabled);
2544 //=======================================================================
2547 //=======================================================================
2548 void V3d_View::Zoom (const Standard_Integer theXp1,
2549 const Standard_Integer theYp1,
2550 const Standard_Integer theXp2,
2551 const Standard_Integer theYp2)
2553 Standard_Integer aDx = theXp2 - theXp1;
2554 Standard_Integer aDy = theYp2 - theYp1;
2555 if (aDx != 0 || aDy != 0)
2557 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2558 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2559 SetZoom (aCoeff, Standard_True);
2563 //=======================================================================
2564 //function : StartZoomAtPoint
2566 //=======================================================================
2567 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2568 const Standard_Integer theYp)
2570 MyZoomAtPointX = theXp;
2571 MyZoomAtPointY = theYp;
2574 //=======================================================================
2575 //function : ZoomAtPoint
2577 //=======================================================================
2578 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2579 const Standard_Integer theMouseStartY,
2580 const Standard_Integer theMouseEndX,
2581 const Standard_Integer theMouseEndY)
2583 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2586 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2587 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2588 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2590 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2592 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
2593 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
2595 // ensure that zoom will not be too small or too big.
2596 Standard_Real aCoef = aDZoom;
2597 if (aViewWidth < aCoef * Precision::Confusion())
2599 aCoef = aViewWidth / Precision::Confusion();
2601 else if (aViewWidth > aCoef * 1e12)
2603 aCoef = aViewWidth / 1e12;
2605 if (aViewHeight < aCoef * Precision::Confusion())
2607 aCoef = aViewHeight / Precision::Confusion();
2609 else if (aViewHeight > aCoef * 1e12)
2611 aCoef = aViewHeight / 1e12;
2614 Standard_Real aZoomAtPointXv = 0.0;
2615 Standard_Real aZoomAtPointYv = 0.0;
2616 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2618 V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
2619 V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
2621 myCamera->SetScale (myCamera->Scale() / aCoef);
2622 Translate (myCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2626 SetImmediateUpdate (wasUpdateEnabled);
2631 //=============================================================================
2632 //function : AxialScale
2634 //=============================================================================
2635 void V3d_View::AxialScale (const Standard_Integer Dx,
2636 const Standard_Integer Dy,
2637 const V3d_TypeOfAxe Axis)
2639 if( Dx != 0. || Dy != 0. ) {
2640 Standard_Real Sx, Sy, Sz;
2641 AxialScale( Sx, Sy, Sz );
2642 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2643 dscale = (Dx > 0) ? dscale : 1./dscale;
2644 if( Axis == V3d_X ) Sx = dscale;
2645 if( Axis == V3d_Y ) Sy = dscale;
2646 if( Axis == V3d_Z ) Sz = dscale;
2647 SetAxialScale( Sx, Sy, Sz );
2651 //=============================================================================
2654 //=============================================================================
2655 void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
2656 const Standard_Real Xmin,
2657 const Standard_Real Ymin,
2658 const Standard_Real Xmax,
2659 const Standard_Real Ymax)
2661 Standard_Integer aWinWidth, aWinHeight;
2662 aWindow->Size (aWinWidth, aWinHeight);
2664 Standard_Real aWinAspect = (Standard_Real)aWinWidth / aWinHeight;
2665 Standard_Real aFitSizeU = Abs (Xmax - Xmin);
2666 Standard_Real aFitSizeV = Abs (Ymax - Ymin);
2667 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2668 if (aFitAspect >= aWinAspect)
2670 aFitSizeV = aFitSizeU / aWinAspect;
2674 aFitSizeU = aFitSizeV * aWinAspect;
2677 myCamera->SetAspect (aWinAspect);
2678 Translate (myCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
2679 Scale (myCamera, aFitSizeU, aFitSizeV);
2685 //=============================================================================
2686 //function : StartRotation
2688 //=============================================================================
2689 static Standard_Boolean zRotation = Standard_False;
2690 void V3d_View::StartRotation(const Standard_Integer X,
2691 const Standard_Integer Y,
2692 const Quantity_Ratio zRotationThreshold)
2697 rx = Standard_Real(Convert(x));
2698 ry = Standard_Real(Convert(y));
2700 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2701 zRotation = Standard_False;
2702 if( zRotationThreshold > 0. ) {
2703 Standard_Real dx = Abs(sx - rx/2.);
2704 Standard_Real dy = Abs(sy - ry/2.);
2705 // if( dx > rx/3. || dy > ry/3. ) zRotation = Standard_True;
2706 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2707 if( dx > dd || dy > dd ) zRotation = Standard_True;
2712 //=============================================================================
2713 //function : Rotation
2715 //=============================================================================
2716 void V3d_View::Rotation(const Standard_Integer X,
2717 const Standard_Integer Y)
2719 if( rx == 0. || ry == 0. ) {
2723 Standard_Real dx=0.,dy=0.,dz=0.;
2725 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2726 atan2(sx-rx/2.,ry/2.-sy);
2728 dx = (Standard_Real(X) - sx) * M_PI / rx;
2729 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2732 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2735 //=============================================================================
2736 //function : SetComputedMode
2738 //=============================================================================
2739 void V3d_View::SetComputedMode (const Standard_Boolean aMode)
2745 MyView->SetComputedMode (Standard_True);
2751 MyView->SetComputedMode (Standard_False);
2756 //=============================================================================
2757 //function : ComputedMode
2759 //=============================================================================
2760 Standard_Boolean V3d_View::ComputedMode() const
2762 return MyView->ComputedMode();
2765 //=============================================================================
2766 //function : SetBackFacingModel
2768 //=============================================================================
2769 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel aModel)
2771 MyView->SetBackFacingModel (Visual3d_TypeOfBackfacingModel(aModel));
2775 //=============================================================================
2776 //function : BackFacingModel
2778 //=============================================================================
2779 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2781 return V3d_TypeOfBackfacingModel(MyView -> BackFacingModel ());
2784 void V3d_View::Init()
2786 myComputedMode = MyViewer->ComputedMode();
2787 if( !myComputedMode || !MyViewer->DefaultComputedMode() ) {
2788 SetComputedMode(Standard_False);
2792 //=============================================================================
2795 //=============================================================================
2796 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2797 const Graphic3d_BufferType& theBufferType)
2799 Standard_Integer aWinWidth, aWinHeight;
2800 MyWindow->Size (aWinWidth, aWinHeight);
2801 Image_AlienPixMap anImage;
2803 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2806 //=============================================================================
2807 //function : ToPixMap
2809 //=============================================================================
2810 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
2811 const Standard_Integer theWidth,
2812 const Standard_Integer theHeight,
2813 const Graphic3d_BufferType& theBufferType,
2814 const Standard_Boolean theToKeepAspect,
2815 const V3d_StereoDumpOptions theStereoOptions)
2817 Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
2819 // always prefer hardware accelerated offscreen buffer
2820 Graphic3d_PtrFrameBuffer aFBOPtr = NULL;
2821 Graphic3d_PtrFrameBuffer aPrevFBOPtr = (Graphic3d_PtrFrameBuffer )cView->ptrFBO;
2822 Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
2823 Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
2824 if (aPrevFBOPtr != NULL)
2826 MyView->FBOGetDimensions (aPrevFBOPtr,
2827 aPrevFBOVPSizeX, aPrevFBOVPSizeY,
2828 aPrevFBOSizeXMax, aPrevFBOSizeYMax);
2829 if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
2831 MyView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
2832 aFBOPtr = aPrevFBOPtr;
2836 if (aFBOPtr == NULL)
2838 // Try to create hardware accelerated buffer
2839 aFBOPtr = MyView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
2840 if (aFBOPtr != NULL)
2842 MyView->FBOGetDimensions (aFBOPtr,
2843 aFBOVPSizeX, aFBOVPSizeY,
2844 aFBOSizeXMax, aFBOSizeYMax);
2845 // reduce viewport in case of hardware limits
2846 if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
2847 if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
2848 MyView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
2851 cView->ptrFBO = aFBOPtr;
2853 // If hardware accelerated buffer - try to use onscreen buffer
2854 // Results may be bad!
2855 if (aFBOPtr == NULL)
2857 // retrieve window sizes
2858 Standard_Integer aWinWidth, aWinHeight;
2859 MyWindow->Size (aWinWidth, aWinHeight);
2861 // technically we can reduce existing viewport...
2862 // but currently allow only dumping the window itself
2863 if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
2865 return Standard_False;
2869 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2871 aStoreMapping->Copy (myCamera);
2873 if (myCamera->IsStereo())
2875 switch (theStereoOptions)
2878 myCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2881 case V3d_SDO_LEFT_EYE :
2882 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2885 case V3d_SDO_RIGHT_EYE :
2886 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2891 // render immediate structures into back buffer rather than front
2892 Handle(Graphic3d_GraphicDriver) aDriver = Handle(Graphic3d_GraphicDriver)::DownCast (MyView->GraphicDriver());
2893 const Standard_Boolean aPrevImmediateMode = aDriver.IsNull() ? Standard_True : aDriver->SetImmediateModeDrawToFront (*cView, Standard_False);
2895 const Standard_Boolean toAutoUpdate = myImmediateUpdate;
2896 myImmediateUpdate = Standard_False;
2898 myImmediateUpdate = toAutoUpdate;
2900 if (theToKeepAspect)
2902 myCamera->SetAspect ((Standard_Real) aFBOVPSizeX / aFBOVPSizeY);
2905 //workaround for rendering list of Over and Under Layers
2906 if (!MyLayerMgr.IsNull())
2908 MyLayerMgr->Compute();
2913 if (!aDriver.IsNull())
2915 aDriver->SetImmediateModeDrawToFront (*cView, aPrevImmediateMode);
2918 myCamera->Copy (aStoreMapping);
2920 Standard_Boolean isSuccess = Standard_True;
2922 // allocate image buffer for dumping
2923 if (theImage.IsEmpty()
2924 || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
2925 || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
2927 bool isBigEndian = Image_PixMap::IsBigEndianHost();
2928 Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
2929 switch (theBufferType)
2931 case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
2932 case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
2933 case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
2936 isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
2938 isSuccess = isSuccess && MyView->BufferDump (theImage, theBufferType);
2940 // FBO now useless, free resources
2941 if (aFBOPtr != aPrevFBOPtr)
2943 MyView->FBORelease (aFBOPtr);
2945 else if (aPrevFBOPtr != NULL)
2947 MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
2949 cView->ptrFBO = aPrevFBOPtr;
2953 void V3d_View::ImmediateUpdate() const
2955 if (myImmediateUpdate) Update();
2958 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2960 Standard_Boolean aPreviousMode = myImmediateUpdate;
2961 myImmediateUpdate = theImmediateUpdate;
2962 return aPreviousMode;
2965 // =======================================================================
2966 // function : SetCamera
2968 // =======================================================================
2969 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2971 Standard_ASSERT_RAISE (!theCamera.IsNull(), "Void camera is not allowed");
2973 myCamera = theCamera;
2975 MyView->SetCamera (theCamera);
2978 // =======================================================================
2979 // function : GetCamera
2981 // =======================================================================
2982 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
2987 // =======================================================================
2988 // function : FitMinMax
2989 // purpose : Internal
2990 // =======================================================================
2991 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
2992 const Bnd_Box& theBox,
2993 const Standard_Real theMargin,
2994 const Standard_Real theResolution,
2995 const Standard_Boolean theToEnlargeIfLine) const
2997 // Check bounding box for validness
2998 if (theBox.IsVoid())
3000 return Standard_False; // bounding box is out of bounds...
3003 // Apply "axial scaling" to the bounding points.
3004 // It is not the best approach to make this scaling as a part of fit all operation,
3005 // but the axial scale is integrated into camera orientation matrix and the other
3006 // option is to perform frustum plane adjustment algorithm in view camera space,
3007 // which will lead to a number of additional world-view space conversions and
3008 // loosing precision as well.
3009 gp_Pnt aMinCorner = theBox.CornerMin();
3010 gp_Pnt aMaxCorner = theBox.CornerMax();
3011 Standard_Real aXmin = aMinCorner.X() * theCamera->AxialScale().X();
3012 Standard_Real aXmax = aMaxCorner.X() * theCamera->AxialScale().X();
3013 Standard_Real aYmin = aMinCorner.Y() * theCamera->AxialScale().Y();
3014 Standard_Real aYmax = aMaxCorner.Y() * theCamera->AxialScale().Y();
3015 Standard_Real aZmin = aMinCorner.Z() * theCamera->AxialScale().Z();
3016 Standard_Real aZmax = aMaxCorner.Z() * theCamera->AxialScale().Z();
3019 aBBox.Update (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3020 if (aBBox.IsThin (RealEpsilon()))
3022 return Standard_False; // nothing to fit all
3025 gp_Pnt aBBCenter ((aXmin + aXmax) * 0.5, (aYmin + aYmax) * 0.5, (aZmin + aZmax) * 0.5);
3027 gp_Pln aFrustumLeft;
3028 gp_Pln aFrustumRight;
3029 gp_Pln aFrustumBottom;
3031 gp_Pln aFrustumNear;
3033 theCamera->Frustum (aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar);
3035 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3036 gp_Dir aCamDir = theCamera->Direction();
3037 gp_Dir aCamSide = aCamDir ^ aCamUp;
3039 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3040 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3041 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3042 // set up perspective-correct camera projection matching the bounding box.
3043 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3044 // The zooming can be done by calculating view plane size matching the bounding box at center of
3045 // the bounding box. The only limitation here is that the scale of camera should define size of
3046 // its view plane passing through the camera center, and the center of camera should be on the
3047 // same line with the center of bounding box.
3049 // The following method is applied:
3050 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3051 // 2) Determine new location of frustum planes, "matching" the bounding box.
3052 // 3) Determine new camera projection vector using the normalized asymmetry.
3053 // 4) Determine new zooming in view space.
3055 // Determine normalized projection asymmetry (if any).
3057 Standard_Real anAssymX = Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction()))
3058 - Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction()));
3059 Standard_Real anAssymY = Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction()))
3060 - Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction()));
3062 // Determine how far should be the frustum planes placed from center
3063 // of bounding box, in order to match the bounding box closely.
3064 gp_Pln aMatchSide[6] = {aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar};
3065 Standard_Real aMatchDistance[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
3066 for (Standard_Integer anIt = 0; anIt < 6; ++anIt)
3068 const gp_Dir& aPlaneN = aMatchSide[anIt].Axis().Direction();
3071 aPlaneTrsf.SetTransformation (gp_Ax3(), gp_Ax3 (aBBCenter, aPlaneN));
3072 Bnd_Box aRelativeBBox = aBBox.Transformed (aPlaneTrsf);
3074 Standard_Real aDummy = 0.0;
3075 Standard_Real aZmin = 0.0;
3076 Standard_Real aZmax = 0.0;
3077 aRelativeBBox.Get (aDummy, aDummy, aZmin, aDummy, aDummy, aZmax);
3078 aMatchDistance[anIt] = -aZmin;
3080 // The center of camera is placed on the same line with center of bounding box.
3081 // The view plane section crosses the bounding box at its center.
3082 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3083 // into view section size between the point and the frustum plane.
3085 // /|\ right half of frame //
3087 // point o<-- distance * coeff -->//---- (view plane section)
3097 aMatchDistance[0] *= Sqrt(1 + Pow (Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction())), 2.0));
3098 aMatchDistance[1] *= Sqrt(1 + Pow (Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction())), 2.0));
3099 aMatchDistance[2] *= Sqrt(1 + Pow (Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction())), 2.0));
3100 aMatchDistance[3] *= Sqrt(1 + Pow (Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction())), 2.0));
3101 aMatchDistance[4] *= Sqrt(1 + Pow (Tan ( aCamDir.Angle (aFrustumNear.Axis().Direction())), 2.0));
3102 aMatchDistance[5] *= Sqrt(1 + Pow (Tan (-aCamDir.Angle (aFrustumFar.Axis().Direction())), 2.0));
3104 Standard_Real aViewSizeXv = aMatchDistance[0] + aMatchDistance[1];
3105 Standard_Real aViewSizeYv = aMatchDistance[2] + aMatchDistance[3];
3106 Standard_Real aViewSizeZv = aMatchDistance[4] + aMatchDistance[5];
3108 // Place center of camera on the same line with center of bounding
3109 // box applying corresponding projection asymmetry (if any).
3110 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3111 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3112 Standard_Real anOffsetXv = (aMatchDistance[1] - aMatchDistance[0]) * 0.5 + anAssymXv;
3113 Standard_Real anOffsetYv = (aMatchDistance[3] - aMatchDistance[2]) * 0.5 + anAssymYv;
3114 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3115 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3116 gp_Pnt aNewCenter = aBBCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3118 gp_Trsf aCenterTrsf;
3119 aCenterTrsf.SetTranslation (theCamera->Center(), aNewCenter);
3120 theCamera->Transform (aCenterTrsf);
3121 theCamera->SetDistance (aMatchDistance[5] + aMatchDistance[4]);
3123 // Bounding box collapses to a point or thin line going in depth of the screen
3124 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3126 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3128 return Standard_True; // This is just one point or line and zooming has no effect.
3131 // Looking along line and "theToEnlargeIfLine" is requested.
3132 // Fit view to see whole scene on rotation.
3133 aViewSizeXv = aViewSizeZv;
3134 aViewSizeYv = aViewSizeZv;
3137 Scale (theCamera, aViewSizeXv * (1.0 + theMargin), aViewSizeYv * (1.0 + theMargin));
3139 return Standard_True;
3142 // =======================================================================
3144 // purpose : Internal
3145 // =======================================================================
3146 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3147 const Standard_Real theSizeXv,
3148 const Standard_Real theSizeYv) const
3150 Standard_Real anAspect = theCamera->Aspect();
3151 Standard_Real aMaxSize = Max (theSizeXv / anAspect, theSizeYv);
3152 theCamera->SetScale (aMaxSize);
3155 // =======================================================================
3156 // function : Translate
3157 // purpose : Internal
3158 // =======================================================================
3159 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3160 const Standard_Real theDXv,
3161 const Standard_Real theDYv) const
3163 const gp_Pnt& aCenter = theCamera->Center();
3164 const gp_Dir& aDir = theCamera->Direction();
3165 const gp_Dir& anUp = theCamera->Up();
3166 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3168 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3169 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3170 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3172 aPanTrsf.SetTranslation (aCameraPan);
3174 theCamera->Transform (aPanTrsf);
3177 // =======================================================================
3178 // function : IsCullingEnabled
3180 // =======================================================================
3181 Standard_Boolean V3d_View::IsCullingEnabled() const
3183 Graphic3d_CView* aView = (Graphic3d_CView* )MyView->CView();
3184 return aView->IsCullingEnabled;
3187 // =======================================================================
3188 // function : SetFrustumCulling
3190 // =======================================================================
3191 void V3d_View::SetFrustumCulling (const Standard_Boolean theToClip)
3193 Graphic3d_CView* aView = (Graphic3d_CView* )MyView->CView();
3194 aView->IsCullingEnabled = theToClip;