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 /***********************************************************************
18 HISTORIQUE DES MODIFICATIONS :
19 --------------------------------
20 00-09-92 : GG ; Creation.
21 02-10-96 : FMN ; Suppression appel Redraw sans MustBeResized()
22 05-06-97 : FMN ; Correction FitAll()
23 30-06-97 : GG ; Correction + Optimisation de Panning(...)
24 On fait la translation + le zoom en une seule
25 operation au lieu de 2 precedemment qui etait buggee.
26 09-07-97 : FMN ; Correction FitAll() sur le Ratio
27 16-07-97 : FMN ; Correction FitAll() sur le calcul de la Box
28 22-07-97 : FMN ; Ajout mode RetainMode pour le Transient
29 15-12-97 : FMN ; Ajout texture mapping
30 17-12-97 : FMN ; CTS19129 Correction FitAll() multiple
31 18-12-97 : FMN ; Ajout mode Ajout
32 24-12-97 : FMN ; Remplacement de math par MathGra
33 24-12-97 : CQO ; BUC50037 Xw_Window -> Aspect_Window
34 31-12-97 : CAL ; Remplacement de MathGra par Array2OfReal
35 07-01-98 : CAL ; Ajout de la methode DoMapping.
36 07-01-98 : CAL ; Retrait de tous les "this->" inutiles
37 21-01-98 : CAL ; Remplacement des Window->Position () par Window->Size ()
38 27-01-98 : FMN ; PERF: OPTIMISATION LOADER (LOPTIM)
39 12-02-98 : GG ; Reactivation du Redraw dans MustBeResized()
40 23-02-98 : FMN ; Remplacement PI par Standard_PI
41 25-02-98 : FMN ; PERF.27: Optimisation of view creation from existing view
42 11-03-98 : STT ; S3558
43 19-03-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
45 08-04-98 : STT ; suppr. S3558
46 10-04-98 : CAL ; Ajout des methodes RefToPix et PixToRef
47 13-06-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
48 ne marche pas. Contournement en appelant WNT_Window::Size(Int,Int).
49 16-08-98 : CAL ; S3892. Ajout grilles 3d.
50 09-09-98 : CAL ; S3892. Generalisation de TrsPoint.
51 06-10-98 : CAL ; Ajout d'un TIMER si CSF_GraphicTimer est definie.
52 16-10-98 : CAL ; Retrait d'un TIMER si CSF_GraphicTimer est definie.
53 06-11-98 : CAL ; PRO ?????. Probleme dans ZFitAll si un point dans la vue.
54 29-OCT-98 : DCB : Adding ScreenCopy () method.
57 About FitAll() multiple. This probleme is caused by missing
58 precision of transformation matrices. If it is supposed that
59 projection is made in the plane (U,V), there is a difference
60 after several Zoom - compared to the exact value (cf ZoomX).
61 Don't forget that the matrices work in float and not in double.
62 To solve the problem (for lack of a better solution) I make 2 passes.
63 ************************************************************************/
64 /*----------------------------------------------------------------------*/
69 #include <Aspect_ColorScale.hxx>
70 #include <Aspect_GradientBackground.hxx>
71 #include <Aspect_Grid.hxx>
72 #include <Aspect_Window.hxx>
73 #include <Bnd_Box.hxx>
77 #include <Graphic3d_AspectMarker3d.hxx>
78 #include <Graphic3d_GraphicDriver.hxx>
79 #include <Graphic3d_Group.hxx>
80 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
81 #include <Graphic3d_MapOfStructure.hxx>
82 #include <Graphic3d_Structure.hxx>
83 #include <Graphic3d_TextureEnv.hxx>
84 #include <Graphic3d_Vector.hxx>
85 #include <Image_AlienPixMap.hxx>
86 #include <NCollection_Array1.hxx>
87 #include <Precision.hxx>
88 #include <Quantity_Color.hxx>
89 #include <Standard_Assert.hxx>
90 #include <Standard_DivideByZero.hxx>
91 #include <Standard_ErrorHandler.hxx>
92 #include <Standard_MultiplyDefined.hxx>
93 #include <Standard_ShortReal.hxx>
94 #include <Standard_Type.hxx>
95 #include <Standard_TypeMismatch.hxx>
96 #include <TColStd_Array2OfReal.hxx>
97 #include <TColStd_HSequenceOfInteger.hxx>
99 #include <V3d_BadValue.hxx>
100 #include <V3d_LayerMgr.hxx>
101 #include <V3d_Light.hxx>
102 #include <V3d_StereoDumpOptions.hxx>
103 #include <V3d_UnMapped.hxx>
104 #include <V3d_View.hxx>
105 #include <V3d_Viewer.hxx>
106 #include <Visual3d_Layer.hxx>
107 #include <Visual3d_Light.hxx>
108 #include <Visual3d_View.hxx>
109 #include <Visual3d_ViewManager.hxx>
111 #define V3d_FLAG_COMPUTATION 0x00000004
114 #include <OSD_Environment.hxx>
116 /*----------------------------------------------------------------------*/
121 #define DEUXPI (2. * M_PI)
125 static const Standard_Integer THE_NB_BOUND_POINTS = 8;
128 //=============================================================================
129 //function : Constructor
131 //=============================================================================
132 V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) :
133 MyViewer(VM.operator->()),
136 myActiveLightsIterator(),
137 SwitchSetFront(Standard_False),
140 myImmediateUpdate = Standard_False;
141 MyView = new Visual3d_View(MyViewer->Viewer());
143 // { Begin to retrieve the definition from ViewContext.
144 // Step MyViewContext = MyView->Context() ;
145 // to permit MyView->SetContext to compare
146 // the old and the new context.
147 // No problem for MyViewMapping, MyViewOrientation
148 // as MyView->SetViewMapping and MyView->SetViewOrientation
149 // don't try to optimize the modifications introduced to
150 // viewmapping and vieworientation.
153 if ((MyView->Context ()).AliasingIsOn ())
154 MyViewContext.SetAliasingOn ();
156 MyViewContext.SetAliasingOff ();
159 MyViewContext.SetDepthCueingBackPlane
160 ((MyView->Context ()).DepthCueingBackPlane ());
161 MyViewContext.SetDepthCueingFrontPlane
162 ((MyView->Context ()).DepthCueingFrontPlane ());
164 if ((MyView->Context ()).DepthCueingIsOn ())
165 MyViewContext.SetDepthCueingOn ();
167 MyViewContext.SetDepthCueingOff ();
170 MyViewContext.SetZClippingBackPlane
171 ((MyView->Context ()).ZClippingBackPlane ());
172 MyViewContext.SetZClippingFrontPlane
173 ((MyView->Context ()).ZClippingFrontPlane ());
175 if ((MyView->Context ()).FrontZClippingIsOn ())
176 MyViewContext.SetFrontZClippingOn ();
178 MyViewContext.SetFrontZClippingOff ();
180 if ((MyView->Context ()).BackZClippingIsOn ())
181 MyViewContext.SetBackZClippingOn ();
183 MyViewContext.SetBackZClippingOff ();
185 // Visualization and Shading Model
186 MyViewContext.SetModel ((MyView->Context ()).Model ());
187 MyViewContext.SetVisualization ((MyView->Context ()).Visualization ());
190 MyViewContext.SetSurfaceDetail (MyView->Context ().SurfaceDetail ());
191 MyViewContext.SetTextureEnv (MyView->Context ().TextureEnv ());
192 // } End of retrieval of the definition of ViewContext.
194 MyBackground = VM->GetBackgroundColor() ;
195 MyGradientBackground = VM->GetGradientBackground() ;
198 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
199 aCamera->SetFOVy (45.0);
200 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
201 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
204 SetAxis (0.,0.,0.,1.,1.,1.);
205 SetVisualization (VM->DefaultVisualization());
206 SetShadingModel (VM->DefaultShadingModel());
207 SetSurfaceDetail (VM->DefaultSurfaceDetail());
210 SetProj (VM->DefaultViewProj());
211 SetSize (VM->DefaultViewSize());
212 Standard_Real zsize = VM->DefaultViewSize();
214 SetZClippingDepth (0.);
215 SetZClippingWidth (zsize);
216 SetZCueingDepth (0.);
217 SetZCueingWidth (zsize);
218 SetDepth (VM->DefaultViewSize()/2.0);
219 SetViewMappingDefault();
220 SetViewOrientationDefault();
223 myImmediateUpdate = Standard_True;
225 aCamera->SetProjectionType ((Type == V3d_ORTHOGRAPHIC)
226 ? Graphic3d_Camera::Projection_Orthographic
227 : Graphic3d_Camera::Projection_Perspective);
230 //=============================================================================
231 //function : Constructor
233 //=============================================================================
234 V3d_View::V3d_View(const Handle(V3d_Viewer)& theVM,const Handle(V3d_View)& theView) :
235 MyViewer(theVM.operator->()),
238 myActiveLightsIterator(),
239 SwitchSetFront(Standard_False),
242 Handle(Visual3d_View) aFromView = theView->View();
244 myImmediateUpdate = Standard_False;
245 MyView = new Visual3d_View (MyViewer->Viewer());
247 for (theView->InitActiveLights(); theView->MoreActiveLights(); theView->NextActiveLights())
249 MyActiveLights.Append (theView->ActiveLight());
252 MyViewContext = aFromView->Context() ;
254 SetCamera (new Graphic3d_Camera (theView->Camera()));
255 View()->SetAutoZFitMode (theView->View()->AutoZFitMode(), theView->View()->AutoZFitScaleFactor());
257 MyBackground = aFromView->Background() ;
258 MyGradientBackground = aFromView->GradientBackground();
260 MyView->SetContext (MyViewContext) ;
262 SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
264 SetViewMappingDefault();
265 SetViewOrientationDefault();
266 theVM->AddView (this);
270 myImmediateUpdate = Standard_True;
273 //=============================================================================
274 //function : SetMagnify
276 //=============================================================================
277 void V3d_View::SetMagnify(const Handle(Aspect_Window)& TheWindow,
278 const Handle(V3d_View)& aPreviousView,
279 const Standard_Integer x1,
280 const Standard_Integer y1,
281 const Standard_Integer x2,
282 const Standard_Integer y2)
284 if( !MyView->IsDefined() ) {
285 Standard_Real a,b,c,d;
286 aPreviousView->Convert(x1,y1,a,b);
287 aPreviousView->Convert(x2,y2,c,d);
288 MyView->SetWindow(TheWindow) ;
289 FitAll(TheWindow,a,b,c,d);
290 MyView->SetContext(MyViewContext) ;
291 MyView->SetBackground(MyBackground) ;
292 MyViewer->SetViewOn(this) ;
293 MyWindow = TheWindow;
295 SetViewMappingDefault();
299 //=============================================================================
300 //function : SetWindow
302 //=============================================================================
303 void V3d_View::SetWindow(const Handle(Aspect_Window)& TheWindow)
305 MyView->SetWindow(TheWindow) ;
306 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
307 MyWindow = TheWindow;
308 // SetWindow carries out SetRatio and modifies
309 MyView->SetContext(MyViewContext) ;
310 MyView->SetBackground(MyBackground) ;
311 MyViewer->SetViewOn(this) ;
315 //=============================================================================
316 //function : SetWindow
318 //=============================================================================
319 void V3d_View::SetWindow(const Handle(Aspect_Window)& aWindow,
320 const Aspect_RenderingContext aContext,
321 const Aspect_GraphicCallbackProc& aDisplayCB,
322 const Standard_Address aClientData)
324 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
326 MyView->SetWindow(aWindow, aContext, aDisplayCB, aClientData) ;
327 MyView->SetContext(MyViewContext) ;
328 MyView->SetBackground(MyBackground) ;
329 MyViewer->SetViewOn(this) ;
333 //=============================================================================
336 //=============================================================================
337 void V3d_View::Remove() const
339 MyViewer->DelView (this);
341 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
345 //=============================================================================
348 //=============================================================================
349 void V3d_View::Update() const
351 if( MyView->IsDefined() ) MyView->Update (Aspect_TOU_ASAP) ;
354 //=============================================================================
357 //=============================================================================
358 void V3d_View::Redraw() const
360 if( MyView->IsDefined() ) MyView->Redraw() ;
363 //=============================================================================
364 //function : RedrawImmediate
366 //=============================================================================
367 void V3d_View::RedrawImmediate() const
369 if (MyView->IsDefined())
371 MyView->RedrawImmediate();
375 //=============================================================================
376 //function : Invalidate
378 //=============================================================================
379 void V3d_View::Invalidate() const
381 if (MyView->IsDefined())
383 MyView->Invalidate();
387 //=============================================================================
388 //function : IsInvalidated
390 //=============================================================================
391 Standard_Boolean V3d_View::IsInvalidated() const
393 return !MyView->IsDefined()
394 || MyView->IsInvalidated();
397 //=============================================================================
398 //function : AutoZFit
400 //=============================================================================
401 void V3d_View::AutoZFit()
406 //=============================================================================
409 //=============================================================================
410 void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
412 View()->ZFitAll (theScaleFactor);
415 //=============================================================================
418 //=============================================================================
419 void V3d_View::Redraw(const Standard_Integer xc,const Standard_Integer yc,
420 const Standard_Integer width,const Standard_Integer height) const
422 if( MyView->IsDefined() ) MyView->Redraw(xc,yc,width,height) ;
425 //=============================================================================
428 //=============================================================================
429 Standard_Boolean V3d_View::IsEmpty() const
431 Standard_Boolean TheStatus = Standard_True ;
432 if( MyView->IsDefined() ) {
433 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
434 if( Nstruct > 0 ) TheStatus = Standard_False ;
439 //=============================================================================
440 //function : UpdateLights
442 //=============================================================================
443 void V3d_View::UpdateLights() const
445 MyView->SetContext(MyViewContext);
449 //=============================================================================
450 //function : DoMapping
452 //=============================================================================
453 void V3d_View::DoMapping()
455 if( MyView->IsDefined() ) {
456 (MyView->Window())->DoMapping() ;
460 //=============================================================================
461 //function : MustBeResized
463 //=============================================================================
464 void V3d_View::MustBeResized()
466 if ( !MyLayerMgr.IsNull() )
467 MyLayerMgr->Resized();
469 if( MyView->IsDefined() ) {
475 //=============================================================================
476 //function : SetBackgroundColor
478 //=============================================================================
479 void V3d_View::SetBackgroundColor(const Quantity_TypeOfColor Type, const Standard_Real v1, const Standard_Real v2, const Standard_Real v3)
481 Standard_Real V1 = Max( Min( v1, 1.0 ), 0.0 );
482 Standard_Real V2 = Max( Min( v2, 1.0 ), 0.0 );
483 Standard_Real V3 = Max( Min( v3, 1.0 ), 0.0 );
485 Quantity_Color C( V1, V2, V3, Type );
486 SetBackgroundColor( C );
489 //=============================================================================
490 //function : SetBackgroundColor
492 //=============================================================================
493 void V3d_View::SetBackgroundColor(const Quantity_Color &Color)
495 MyBackground.SetColor( Color );
496 if ( MyView->IsDefined() )
497 MyView->SetBackground( MyBackground );
499 if ( !MyLayerMgr.IsNull() )
500 MyLayerMgr->Resized();
503 //=============================================================================
504 //function : SetBackgroundColor
506 //=============================================================================
507 void V3d_View::SetBackgroundColor(const Quantity_NameOfColor Name)
509 Quantity_Color C( Name );
510 SetBackgroundColor( C );
513 //=============================================================================
514 //function : SetBgGradientColors
516 //=============================================================================
517 void V3d_View::SetBgGradientColors( const Quantity_Color& Color1,
518 const Quantity_Color& Color2,
519 const Aspect_GradientFillMethod FillStyle,
520 const Standard_Boolean status)
522 MyGradientBackground.SetColors(Color1, Color2, FillStyle);
523 if ( MyView->IsDefined() )
524 MyView->SetGradientBackground( MyGradientBackground, status );
527 //=============================================================================
528 //function : SetBgGradientColors
530 //=============================================================================
531 void V3d_View::SetBgGradientColors( const Quantity_NameOfColor Color1,
532 const Quantity_NameOfColor Color2,
533 const Aspect_GradientFillMethod FillStyle,
534 const Standard_Boolean status )
536 Quantity_Color C1( Color1 );
537 Quantity_Color C2( Color2 );
538 MyGradientBackground.SetColors( C1, C2, FillStyle );
539 if ( MyView->IsDefined() )
540 MyView->SetGradientBackground( MyGradientBackground, status );
543 //=============================================================================
544 //function : SetBgGradientStyle
546 //=============================================================================
547 void V3d_View::SetBgGradientStyle( const Aspect_GradientFillMethod FillStyle,
548 const Standard_Boolean update)
550 Quantity_Color Color1, Color2;
551 MyGradientBackground.Colors( Color1, Color2 );
552 MyGradientBackground.SetColors( Color1, Color2, FillStyle );
553 if( MyView->IsDefined() )
554 MyView->SetBgGradientStyle( FillStyle, update ) ;
557 //=============================================================================
558 //function : SetBackgroundImage
560 //=============================================================================
561 void V3d_View::SetBackgroundImage( const Standard_CString FileName,
562 const Aspect_FillMethod FillStyle,
563 const Standard_Boolean update )
565 if( MyView->IsDefined() )
566 MyView->SetBackgroundImage( FileName, FillStyle, update ) ;
569 //=============================================================================
570 //function : SetBgImageStyle
572 //=============================================================================
573 void V3d_View::SetBgImageStyle( const Aspect_FillMethod FillStyle,
574 const Standard_Boolean update )
576 if( MyView->IsDefined() )
577 MyView->SetBgImageStyle( FillStyle, update ) ;
580 //=============================================================================
583 //=============================================================================
584 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)
586 Standard_Real D,Nx = Vx,Ny = Vy,Nz = Vz ;
588 D = Sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) ;
589 V3d_BadValue_Raise_if ( D <= 0. , "V3d_View::SetAxis, bad axis");
590 Nx /= D ; Ny /= D ; Nz /= D ;
591 MyDefaultViewPoint.SetCoord(X,Y,Z) ;
592 MyDefaultViewAxis.SetCoord(Nx,Ny,Nz) ;
595 //=============================================================================
596 //function : SetShadingModel
598 //=============================================================================
599 void V3d_View::SetShadingModel(const V3d_TypeOfShadingModel Model)
601 MyViewContext.SetModel((Visual3d_TypeOfModel) Model) ;
602 MyView->SetContext(MyViewContext) ;
605 //=============================================================================
606 //function : SetSurfaceDetail
608 //=============================================================================
609 void V3d_View::SetSurfaceDetail(const V3d_TypeOfSurfaceDetail Model)
611 MyViewContext.SetSurfaceDetail((Visual3d_TypeOfSurfaceDetail) Model) ;
612 MyView->SetContext(MyViewContext) ;
615 //=============================================================================
616 //function : SetTextureEnv
618 //=============================================================================
619 void V3d_View::SetTextureEnv(const Handle(Graphic3d_TextureEnv)& ATexture)
621 MyViewContext.SetTextureEnv(ATexture) ;
622 MyView->SetContext(MyViewContext) ;
625 //=============================================================================
626 //function : SetVisualization
628 //=============================================================================
629 void V3d_View::SetVisualization(const V3d_TypeOfVisualization Mode)
631 MyViewContext.SetVisualization((Visual3d_TypeOfVisualization) Mode);
632 MyView->SetContext(MyViewContext) ;
635 //=============================================================================
636 //function : SetFront
638 //=============================================================================
639 void V3d_View::SetFront()
641 gp_Ax3 a = MyViewer->PrivilegedPlane();
642 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
644 a.Direction().Coord(vx,vy,vz);
645 a.YDirection().Coord(xu,yu,zu);
646 a.Location().Coord(xo,yo,zo);
648 myCamera->SetCenter (gp_Pnt (xo, yo, zo));
650 myCamera->SetDirection (gp_Dir (vx, vy, vz));
652 myCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
653 myCamera->SetUp (gp_Dir (xu, yu, zu));
657 SwitchSetFront = !SwitchSetFront;
662 //=============================================================================
665 //=============================================================================
666 void V3d_View::Rotate (const Standard_Real ax,
667 const Standard_Real ay,
668 const Standard_Real az,
669 const Standard_Boolean Start)
671 Standard_Real Ax = ax;
672 Standard_Real Ay = ay;
673 Standard_Real Az = az;
675 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
676 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
677 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
678 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
679 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
680 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
684 myCamStartOpUp = myCamera->Up();
685 myCamStartOpEye = myCamera->Eye();
686 myCamStartOpCenter = myCamera->Center();
689 myCamera->SetUp (myCamStartOpUp);
690 myCamera->SetEye (myCamStartOpEye);
691 myCamera->SetCenter (myCamStartOpCenter);
693 // rotate camera around 3 initial axes
694 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
695 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
696 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
697 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
699 gp_Trsf aRot[3], aTrsf;
700 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
701 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
702 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
703 aTrsf.Multiply (aRot[0]);
704 aTrsf.Multiply (aRot[1]);
705 aTrsf.Multiply (aRot[2]);
707 myCamera->Transform (aTrsf);
714 //=============================================================================
717 //=============================================================================
718 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
719 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
722 Standard_Real Ax = ax ;
723 Standard_Real Ay = ay ;
724 Standard_Real Az = az ;
726 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
727 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
728 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
729 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
730 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
731 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
735 myGravityReferencePoint.SetCoord (X, Y, Z);
736 myCamStartOpUp = myCamera->Up();
737 myCamStartOpEye = myCamera->Eye();
738 myCamStartOpCenter = myCamera->Center();
741 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
743 myCamera->SetUp (myCamStartOpUp);
744 myCamera->SetEye (myCamStartOpEye);
745 myCamera->SetCenter (myCamStartOpCenter);
747 // rotate camera around 3 initial axes
748 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
750 gp_Dir aZAxis (myCamera->Direction().Reversed());
751 gp_Dir aYAxis (myCamera->Up());
752 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
754 gp_Trsf aRot[3], aTrsf;
755 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
756 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
757 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
758 aTrsf.Multiply (aRot[0]);
759 aTrsf.Multiply (aRot[1]);
760 aTrsf.Multiply (aRot[2]);
762 myCamera->Transform (aTrsf);
769 //=============================================================================
772 //=============================================================================
773 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
777 Rotate(angle,0.,0.,Start);
780 Rotate(0.,angle,0.,Start);
783 Rotate(0.,0.,angle,Start);
788 //=============================================================================
791 //=============================================================================
792 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
793 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
795 Standard_Real Angle = angle ;
797 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
798 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
802 myGravityReferencePoint.SetCoord (X, Y, Z);
803 myCamStartOpUp = myCamera->Up();
804 myCamStartOpEye = myCamera->Eye();
805 myCamStartOpCenter = myCamera->Center();
809 myViewAxis.SetCoord(1.,0.,0.) ;
812 myViewAxis.SetCoord(0.,1.,0.) ;
815 myViewAxis.SetCoord(0.,0.,1.) ;
819 myCamStartOpUp = myCamera->Up();
820 myCamStartOpEye = myCamera->Eye();
821 myCamStartOpCenter = myCamera->Center();
824 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
826 myCamera->SetUp (myCamStartOpUp);
827 myCamera->SetEye (myCamStartOpEye);
828 myCamera->SetCenter (myCamStartOpCenter);
830 // rotate camera around passed axis
832 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
833 gp_Dir aRAxis ((Axe == V3d_X) ? 1.0 : 0.0,
834 (Axe == V3d_Y) ? 1.0 : 0.0,
835 (Axe == V3d_Z) ? 1.0 : 0.0);
837 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
838 myCamera->Transform (aRotation);
845 //=============================================================================
848 //=============================================================================
849 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
851 Standard_Real Angle = angle;
853 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
854 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
857 myCamStartOpUp = myCamera->Up();
858 myCamStartOpEye = myCamera->Eye();
859 myCamStartOpCenter = myCamera->Center();
862 const Graphic3d_Vertex& aPnt = MyDefaultViewPoint;
863 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
865 myCamera->SetUp (myCamStartOpUp);
866 myCamera->SetEye (myCamStartOpEye);
867 myCamera->SetCenter (myCamStartOpCenter);
870 gp_Pnt aRCenter (aPnt.X(), aPnt.Y(), aPnt.Z());
871 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
872 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
873 myCamera->Transform (aRotation);
880 //=============================================================================
883 //=============================================================================
884 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
886 Standard_Real Ax = ax;
887 Standard_Real Ay = ay;
888 Standard_Real Az = az;
890 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
891 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
892 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
893 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
894 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
895 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
898 myCamStartOpUp = myCamera->Up();
899 myCamStartOpEye = myCamera->Eye();
900 myCamStartOpCenter = myCamera->Center();
903 myCamera->SetUp (myCamStartOpUp);
904 myCamera->SetEye (myCamStartOpEye);
905 myCamera->SetCenter (myCamStartOpCenter);
907 // rotate camera around 3 initial axes
908 gp_Pnt aRCenter = myCamera->Eye();
909 gp_Dir aZAxis (myCamera->Direction().Reversed());
910 gp_Dir aYAxis (myCamera->Up());
911 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
913 gp_Trsf aRot[3], aTrsf;
914 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
915 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
916 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
917 aTrsf.Multiply (aRot[0]);
918 aTrsf.Multiply (aRot[1]);
919 aTrsf.Multiply (aRot[2]);
921 myCamera->Transform (aTrsf);
928 //=============================================================================
931 //=============================================================================
932 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
936 Turn(angle,0.,0.,Start);
939 Turn(0.,angle,0.,Start);
942 Turn(0.,0.,angle,Start);
947 //=============================================================================
950 //=============================================================================
951 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
953 Standard_Real Angle = angle ;
955 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
956 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
959 myCamStartOpUp = myCamera->Up();
960 myCamStartOpEye = myCamera->Eye();
961 myCamStartOpCenter = myCamera->Center();
964 myCamera->SetUp (myCamStartOpUp);
965 myCamera->SetEye (myCamStartOpEye);
966 myCamera->SetCenter (myCamStartOpCenter);
968 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
971 gp_Pnt aRCenter = myCamera->Eye();
972 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
973 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
974 myCamera->Transform (aRotation);
981 //=============================================================================
982 //function : SetTwist
984 //=============================================================================
985 void V3d_View::SetTwist(const Standard_Real angle)
987 Standard_Real Angle = angle ;
988 Standard_Boolean TheStatus;
990 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
991 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
993 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
996 anUp = gp_Dir (0.0, 0.0, 1.0);
998 TheStatus = ScreenAxis(aReferencePlane, anUp,
999 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1001 anUp = gp_Dir (0.0, 1.0, 0.0);
1002 TheStatus = ScreenAxis(aReferencePlane, anUp,
1003 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1006 anUp = gp_Dir (1.0, 0.0, 0.0);
1007 TheStatus = ScreenAxis(aReferencePlane, anUp,
1008 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1011 V3d_BadValue_Raise_if( !TheStatus,"V3d_ViewSetTwist, alignment of Eye,At,Up,");
1013 gp_Pnt aRCenter = myCamera->Center();
1014 gp_Dir aZAxis (myCamera->Direction().Reversed());
1017 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
1019 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1020 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1022 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1023 myCamera->Transform (aTrsf);
1030 //=============================================================================
1033 //=============================================================================
1034 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1036 Standard_Real aTwistBefore = Twist();
1038 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1040 myCamera->SetEye (gp_Pnt (X, Y, Z));
1041 SetTwist (aTwistBefore);
1045 SetImmediateUpdate (wasUpdateEnabled);
1050 //=============================================================================
1051 //function : SetDepth
1053 //=============================================================================
1054 void V3d_View::SetDepth(const Standard_Real Depth)
1056 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1060 // Move eye using center (target) as anchor.
1061 myCamera->SetDistance (Depth);
1065 // Move the view ref point instead of the eye.
1066 gp_Vec aDir (myCamera->Direction());
1067 gp_Pnt aCameraEye = myCamera->Eye();
1068 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1070 myCamera->SetCenter (aCameraCenter);
1078 //=============================================================================
1079 //function : SetProj
1081 //=============================================================================
1082 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1084 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1085 "V3d_View::SetProj, null projection vector");
1087 Standard_Real aTwistBefore = Twist();
1089 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1091 myCamera->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1093 SetTwist(aTwistBefore);
1097 SetImmediateUpdate (wasUpdateEnabled);
1102 //=============================================================================
1103 //function : SetProj
1105 //=============================================================================
1106 void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1108 Standard_Real Xpn=0;
1109 Standard_Real Ypn=0;
1110 Standard_Real Zpn=0;
1112 switch (Orientation) {
1123 const Graphic3d_Vector& aBck = V3d::GetProjAxis (Orientation);
1125 // retain camera panning from origin when switching projection
1126 gp_Pnt anOriginVCS = myCamera->ConvertWorld2View (gp::Origin());
1127 Standard_Real aPanX = anOriginVCS.X();
1128 Standard_Real aPanY = anOriginVCS.Y();
1130 myCamera->SetCenter (gp_Pnt (0, 0, 0));
1131 myCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1132 myCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
1133 myCamera->OrthogonalizeUp();
1135 Panning (aPanX, aPanY);
1142 //=============================================================================
1145 //=============================================================================
1146 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1148 Standard_Real aTwistBefore = Twist();
1150 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1152 myCamera->SetCenter (gp_Pnt (X, Y, Z));
1154 SetTwist (aTwistBefore);
1158 SetImmediateUpdate (wasUpdateEnabled);
1163 //=============================================================================
1166 //=============================================================================
1167 void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standard_Real Vz)
1169 Standard_Boolean TheStatus ;
1170 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0. ,
1171 "V3d_View::SetUp, nullUp vector");
1173 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1174 gp_Dir anUp (Vx, Vy, Vz);
1176 TheStatus = ScreenAxis(aReferencePlane,anUp,
1177 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1179 anUp = gp_Dir (0.0, 0.0, 1.0);
1180 TheStatus = ScreenAxis(aReferencePlane,anUp,
1181 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1184 anUp = gp_Dir (0.0, 1.0, 0.0);
1185 TheStatus = ScreenAxis(aReferencePlane,anUp,
1186 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1189 anUp = gp_Dir (1.0, 0.0, 0.0);
1190 TheStatus = ScreenAxis(aReferencePlane,anUp,
1191 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1193 V3d_BadValue_Raise_if( !TheStatus,"V3d_View::Setup, alignment of Eye,At,Up");
1195 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1196 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1198 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1205 //=============================================================================
1208 //=============================================================================
1209 void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
1211 Standard_Boolean TheStatus ;
1213 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1216 const Graphic3d_Vector& aViewReferenceUp = V3d::GetProjAxis(Orientation) ;
1217 anUp = gp_Dir (aViewReferenceUp.X(), aViewReferenceUp.Y(), aViewReferenceUp.Z());
1219 TheStatus = ScreenAxis(aReferencePlane,anUp,
1220 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1222 anUp = gp_Dir (0.,0.,1.);
1223 TheStatus = ScreenAxis(aReferencePlane,anUp,
1224 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1227 anUp = gp_Dir (0.,1.,0.);
1228 TheStatus = ScreenAxis(aReferencePlane,anUp,
1229 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1232 anUp = gp_Dir (1.,0.,0.);
1233 TheStatus = ScreenAxis(aReferencePlane,anUp,
1234 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1236 V3d_BadValue_Raise_if( !TheStatus, "V3d_View::SetUp, alignment of Eye,At,Up");
1238 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1239 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1241 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1248 //=============================================================================
1249 //function : SetViewOrientationDefault
1251 //=============================================================================
1252 void V3d_View::SetViewOrientationDefault()
1254 MyView->SetViewOrientationDefault() ;
1259 //=============================================================================
1260 //function : ResetViewOrientation
1262 //=============================================================================
1263 void V3d_View::ResetViewOrientation()
1265 MyView->ViewOrientationReset() ;
1270 //=============================================================================
1273 //=============================================================================
1274 void V3d_View::Reset( const Standard_Boolean update )
1276 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1278 if (!aDefaultCamera.IsNull())
1280 myCamera->CopyMappingData (aDefaultCamera);
1281 myCamera->CopyOrientationData (aDefaultCamera);
1286 SwitchSetFront = Standard_False;
1288 if( myImmediateUpdate || update ) Update();
1291 //=======================================================================
1292 //function : SetCenter
1294 //=======================================================================
1295 void V3d_View::SetCenter (const Standard_Integer theXp,
1296 const Standard_Integer theYp)
1298 Standard_Real aXv, aYv;
1299 Convert (theXp, theYp, aXv, aYv);
1300 Translate (myCamera, aXv, aYv);
1305 //=============================================================================
1306 //function : SetSize
1308 //=============================================================================
1309 void V3d_View::SetSize (const Standard_Real theSize)
1311 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1313 myCamera->SetScale (myCamera->Aspect() >= 1.0 ? theSize / myCamera->Aspect() : theSize);
1320 //=============================================================================
1321 //function : SetZSize
1323 //=============================================================================
1324 void V3d_View::SetZSize(const Standard_Real Size)
1326 Standard_Real Zmax = Size/2.;
1328 Standard_Real aDistance = myCamera->Distance();
1334 Standard_Real Front = MyViewContext.ZClippingFrontPlane();
1335 Standard_Real Back = MyViewContext.ZClippingBackPlane();
1337 // ShortReal precision factor used to add meaningful tolerance to
1338 // ZNear, ZFar values in order to avoid equality after type conversion
1339 // to ShortReal matrices type.
1340 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1342 Standard_Real aZFar = Zmax + aDistance * 2.0;
1343 Standard_Real aZNear = -Zmax + aDistance;
1344 aZNear -= Abs (aZNear) * aPrecision;
1345 aZFar += Abs (aZFar) * aPrecision;
1347 if (!myCamera->IsOrthographic())
1349 if (aZFar < aPrecision)
1351 // Invalid case when both values are negative
1352 aZNear = aPrecision;
1353 aZFar = aPrecision * 2.0;
1355 else if (aZNear < Abs (aZFar) * aPrecision)
1357 // Z is less than 0.0, try to fix it using any appropriate z-scale
1358 aZNear = Abs (aZFar) * aPrecision;
1362 // If range is too small
1363 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1365 aZFar = aZNear + Abs (aZFar) * aPrecision;
1368 myCamera->SetZRange (aZNear, aZFar);
1370 if (MyViewContext.FrontZClippingIsOn() ||
1371 MyViewContext.BackZClippingIsOn())
1373 MyViewContext.SetZClippingFrontPlane (Front);
1374 MyViewContext.SetZClippingBackPlane (Back);
1375 MyView->SetContext (MyViewContext);
1379 //=============================================================================
1380 //function : SetZoom
1382 //=============================================================================
1383 void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1385 V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
1389 myCamStartOpEye = myCamera->Eye();
1390 myCamStartOpCenter = myCamera->Center();
1393 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
1394 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
1396 // ensure that zoom will not be too small or too big
1397 Standard_Real coef = Coef;
1398 if (aViewWidth < coef * Precision::Confusion())
1400 coef = aViewWidth / Precision::Confusion();
1402 else if (aViewWidth > coef * 1e12)
1404 coef = aViewWidth / 1e12;
1406 if (aViewHeight < coef * Precision::Confusion())
1408 coef = aViewHeight / Precision::Confusion();
1410 else if (aViewHeight > coef * 1e12)
1412 coef = aViewHeight / 1e12;
1415 myCamera->SetEye (myCamStartOpEye);
1416 myCamera->SetCenter (myCamStartOpCenter);
1417 myCamera->SetScale (myCamera->Scale() / Coef);
1423 //=============================================================================
1424 //function : SetScale
1426 //=============================================================================
1427 void V3d_View::SetScale( const Standard_Real Coef )
1429 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1431 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1433 // Strange behavior for the sake of compatibility.
1434 if (!aDefaultCamera.IsNull())
1436 myCamera->SetAspect (aDefaultCamera->Aspect());
1437 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1438 myCamera->SetScale (aDefaultScale / Coef);
1442 myCamera->SetScale (myCamera->Scale() / Coef);
1450 //=============================================================================
1451 //function : SetAxialScale
1453 //=============================================================================
1454 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1456 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1458 myCamera->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1462 //=============================================================================
1465 //=============================================================================
1466 void V3d_View::FitAll (const Quantity_Coefficient theMargin, const Standard_Boolean theToUpdate)
1468 FitAll (MyView->MinMaxValues(), theMargin, theToUpdate);
1471 //=============================================================================
1474 //=============================================================================
1475 void V3d_View::FitAll (const Bnd_Box& theBox, const Quantity_Coefficient theMargin, const Standard_Boolean theToUpdate)
1477 Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1479 if (MyView->NumberOfDisplayedStructures() == 0)
1484 if (!FitMinMax (myCamera, theBox, theMargin, 10.0 * Precision::Confusion()))
1491 if (myImmediateUpdate || theToUpdate)
1497 //=============================================================================
1498 //function : DepthFitAll
1500 //=============================================================================
1501 void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1502 const Quantity_Coefficient Margin)
1504 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1505 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1506 Standard_Real Dx,Dy,Dz,Size;
1508 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1510 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1515 Bnd_Box aBox = MyView->MinMaxValues();
1521 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1522 MyView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
1523 MyView->Projects(Xmax,Ymax,Zmax,U1,V1,W1) ;
1524 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1525 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1526 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1527 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
1528 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1529 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1530 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1531 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
1532 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1533 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1534 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1535 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
1536 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1537 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1538 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1539 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
1540 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1541 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1542 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1543 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
1544 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1545 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1546 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1547 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
1548 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1549 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1550 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1553 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1554 Dz = 2.*Wmax + Margin * Wmax;
1556 // Compute depth value
1557 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1558 Dx += Margin * Dx; Dy += Margin * Dy;
1559 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1562 SetDepth( Aspect * Size / 2.);
1568 //=============================================================================
1571 //=============================================================================
1572 void V3d_View::FitAll(const Standard_Real theMinXv,
1573 const Standard_Real theMinYv,
1574 const Standard_Real theMaxXv,
1575 const Standard_Real theMaxYv)
1577 FitAll (MyWindow, theMinXv, theMinYv, theMaxXv, theMaxYv);
1580 //=============================================================================
1581 //function : WindowFitAll
1583 //=============================================================================
1584 void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1585 const Standard_Integer Ymin,
1586 const Standard_Integer Xmax,
1587 const Standard_Integer Ymax)
1589 WindowFit(Xmin,Ymin,Xmax,Ymax);
1592 //=======================================================================
1593 //function : WindowFit
1595 //=======================================================================
1596 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1597 const Standard_Integer theMinYp,
1598 const Standard_Integer theMaxXp,
1599 const Standard_Integer theMaxYp)
1601 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1603 if (!myCamera->IsOrthographic())
1605 // normalize view coordinates
1606 Standard_Integer aWinWidth, aWinHeight;
1607 MyWindow->Size (aWinWidth, aWinHeight);
1609 // z coordinate of camera center
1610 Standard_Real aDepth = myCamera->Project (myCamera->Center()).Z();
1612 // camera projection coordinate are in NDC which are normalized [-1, 1]
1613 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1614 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1615 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1616 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1618 // compute camera panning
1619 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1620 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1621 gp_Pnt aPanTo = myCamera->ConvertProj2View (aFitCenter);
1622 gp_Pnt aPanFrom = myCamera->ConvertProj2View (aScreenCenter);
1623 gp_Vec aPanVec (aPanFrom, aPanTo);
1625 // compute section size
1626 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1627 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1628 gp_Pnt aViewBotLeft = myCamera->ConvertProj2View (aFitBotLeft);
1629 gp_Pnt aViewTopRight = myCamera->ConvertProj2View (aFitTopRight);
1631 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1632 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1634 Translate (myCamera, aPanVec.X(), -aPanVec.Y());
1635 Scale (myCamera, aUSize, aVSize);
1640 Standard_Real aX1, aY1, aX2, aY2;
1641 Convert (theMinXp, theMinYp, aX1, aY1);
1642 Convert (theMaxXp, theMaxYp, aX2, aY2);
1643 FitAll (aX1, aY1, aX2, aY2);
1646 SetImmediateUpdate (wasUpdateEnabled);
1651 //=======================================================================
1652 //function : SetViewMappingDefault
1654 //=======================================================================
1655 void V3d_View::SetViewMappingDefault()
1657 MyView->SetViewMappingDefault();
1662 //=======================================================================
1663 //function : ResetViewMapping
1665 //=======================================================================
1666 void V3d_View::ResetViewMapping()
1668 MyView->ViewMappingReset();
1673 //=======================================================================
1674 //function : ConvertToGrid
1676 //=======================================================================
1677 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1678 const Standard_Integer Yp,
1681 Standard_Real& Zg) const
1683 Graphic3d_Vertex aVrp;
1684 Standard_Real anX, anY, aZ;
1685 Convert (Xp, Yp, anX, anY, aZ);
1686 aVrp.SetCoord (anX, anY, aZ);
1688 if( MyViewer->Grid()->IsActive() ) {
1689 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1690 aNewVrp.Coord (Xg,Yg,Zg) ;
1692 aVrp.Coord (Xg,Yg,Zg) ;
1695 //=======================================================================
1696 //function : ConvertToGrid
1698 //=======================================================================
1699 void V3d_View::ConvertToGrid(const Standard_Real X,
1700 const Standard_Real Y,
1701 const Standard_Real Z,
1704 Standard_Real& Zg) const
1706 if( MyViewer->Grid()->IsActive() ) {
1707 Graphic3d_Vertex aVrp (X,Y,Z) ;
1708 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1709 aNewVrp.Coord(Xg,Yg,Zg) ;
1711 Xg = X; Yg = Y; Zg = Z;
1715 //=======================================================================
1716 //function : Convert
1718 //=======================================================================
1719 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1721 Standard_Integer aDxw, aDyw ;
1723 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1725 MyWindow->Size (aDxw, aDyw);
1726 Standard_Real aValue;
1728 gp_Pnt aViewDims = myCamera->ViewDimensions();
1729 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1734 //=======================================================================
1735 //function : Convert
1737 //=======================================================================
1738 void V3d_View::Convert(const Standard_Integer Xp,
1739 const Standard_Integer Yp,
1741 Standard_Real& Yv) const
1743 Standard_Integer aDxw, aDyw;
1745 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1747 MyWindow->Size (aDxw, aDyw);
1749 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1750 aPoint = myCamera->ConvertProj2View (aPoint);
1756 //=======================================================================
1757 //function : Convert
1759 //=======================================================================
1760 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1762 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1764 Standard_Integer aDxw, aDyw;
1765 MyWindow->Size (aDxw, aDyw);
1767 gp_Pnt aViewDims = myCamera->ViewDimensions();
1768 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1773 //=======================================================================
1774 //function : Convert
1776 //=======================================================================
1777 void V3d_View::Convert(const Standard_Real Xv,
1778 const Standard_Real Yv,
1779 Standard_Integer& Xp,
1780 Standard_Integer& Yp) const
1782 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1784 Standard_Integer aDxw, aDyw;
1785 MyWindow->Size (aDxw, aDyw);
1787 gp_Pnt aPoint (Xv, Yv, 0.0);
1788 aPoint = myCamera->ConvertView2Proj (aPoint);
1789 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1791 Xp = RealToInt (aPoint.X());
1792 Yp = RealToInt (aPoint.Y());
1795 //=======================================================================
1796 //function : Convert
1798 //=======================================================================
1799 void V3d_View::Convert(const Standard_Integer Xp,
1800 const Standard_Integer Yp,
1803 Standard_Real& Z) const
1805 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1806 Standard_Integer aHeight, aWidth;
1807 MyWindow->Size (aWidth, aHeight);
1809 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1810 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1811 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1813 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
1820 //=======================================================================
1821 //function : ConvertWithProj
1823 //=======================================================================
1824 void V3d_View::ConvertWithProj(const Standard_Integer Xp,
1825 const Standard_Integer Yp,
1831 Standard_Real& Dz) const
1833 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
1834 Standard_Integer aHeight, aWidth;
1835 MyWindow->Size (aWidth, aHeight);
1837 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1838 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1839 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1841 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
1847 Graphic3d_Vertex aVrp;
1848 aVrp.SetCoord (X, Y, Z);
1850 aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1852 Graphic3d_Vec3d aNormDir;
1853 aNormDir.x() = X - aResult.X();
1854 aNormDir.y() = Y - aResult.Y();
1855 aNormDir.z() = Z - aResult.Z();
1856 aNormDir.Normalize();
1863 //=======================================================================
1864 //function : Convert
1866 //=======================================================================
1867 void V3d_View::Convert(const Standard_Real X,
1868 const Standard_Real Y,
1869 const Standard_Real Z,
1870 Standard_Integer& Xp,
1871 Standard_Integer& Yp) const
1873 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
1874 Standard_Integer aHeight, aWidth;
1875 MyWindow->Size (aWidth, aHeight);
1877 gp_Pnt aPoint = myCamera->Project (gp_Pnt (X, Y, Z));
1879 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1880 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1883 //=======================================================================
1884 //function : Project
1886 //=======================================================================
1887 void V3d_View::Project(const Standard_Real X,
1888 const Standard_Real Y,
1889 const Standard_Real Z,
1891 Standard_Real &Yp) const
1894 MyView->Projects (X, Y, Z, Xp, Yp, Zp);
1897 //=======================================================================
1898 //function : BackgroundColor
1900 //=======================================================================
1901 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1904 Standard_Real& V3) const
1906 Quantity_Color C = BackgroundColor() ;
1907 C.Values(V1,V2,V3,Type) ;
1910 //=======================================================================
1911 //function : BackgroundColor
1913 //=======================================================================
1914 Quantity_Color V3d_View::BackgroundColor() const
1916 return MyBackground.Color() ;
1919 //=======================================================================
1920 //function : GradientBackgroundColors
1922 //=======================================================================
1923 void V3d_View::GradientBackgroundColors(Quantity_Color& Color1,Quantity_Color& Color2) const
1925 MyGradientBackground.Colors(Color1, Color2);
1928 //=======================================================================
1929 //function : GradientBackground
1931 //=======================================================================
1932 Aspect_GradientBackground V3d_View::GradientBackground() const
1934 return MyGradientBackground;
1937 //=======================================================================
1940 //=======================================================================
1941 Standard_Real V3d_View::Scale() const
1943 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1945 Standard_Real aCameraScale;
1947 // Strange behavior for the sake of compatibility.
1948 if (!aDefaultCamera.IsNull())
1950 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1951 aCameraScale = aDefaultScale / myCamera->Scale();
1955 aCameraScale = myCamera->Scale();
1958 return aCameraScale;
1961 //=======================================================================
1962 //function : AxialScale
1964 //=======================================================================
1965 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1967 gp_Pnt anAxialScale = myCamera->AxialScale();
1968 Sx = anAxialScale.X();
1969 Sy = anAxialScale.Y();
1970 Sz = anAxialScale.Z();
1973 //=======================================================================
1976 //=======================================================================
1977 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1979 gp_Pnt aViewDims = myCamera->ViewDimensions();
1981 Width = aViewDims.X();
1982 Height = aViewDims.Y();
1985 //=======================================================================
1988 //=======================================================================
1989 Standard_Real V3d_View::ZSize() const
1991 gp_Pnt aViewDims = myCamera->ViewDimensions();
1993 return aViewDims.Z();
1996 //=======================================================================
1999 //=======================================================================
2000 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
2001 Standard_Real& Vmin,
2002 Standard_Real& Umax,
2003 Standard_Real& Vmax) const
2005 Standard_Real Wmin,Wmax,U,V,W ;
2006 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
2008 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2011 Bnd_Box aBox = MyView->MinMaxValues();
2012 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2013 MyView->Projects(Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
2014 MyView->Projects(Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
2015 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
2016 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2017 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2018 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2019 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
2020 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2021 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2022 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2023 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
2024 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2025 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2026 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2027 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
2028 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2029 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2030 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2031 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
2032 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2033 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2034 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2035 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
2036 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2037 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2038 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2043 //=======================================================================
2046 //=======================================================================
2047 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
2048 Standard_Real& Ymin,
2049 Standard_Real& Zmin,
2050 Standard_Real& Xmax,
2051 Standard_Real& Ymax,
2052 Standard_Real& Zmax) const
2055 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
2056 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2059 Bnd_Box aBox = MyView->MinMaxValues();
2060 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2065 //=======================================================================
2066 //function : Gravity
2068 //=======================================================================
2069 void V3d_View::Gravity (Standard_Real& theX,
2070 Standard_Real& theY,
2071 Standard_Real& theZ) const
2073 Graphic3d_MapOfStructure aSetOfStructures;
2074 MyView->DisplayedStructures (aSetOfStructures);
2076 Standard_Boolean hasSelection = Standard_False;
2077 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2078 aStructIter.More(); aStructIter.Next())
2080 if (aStructIter.Key()->IsHighlighted()
2081 && aStructIter.Key()->IsVisible())
2083 hasSelection = Standard_True;
2088 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
2089 Standard_Integer aNbPoints = 0;
2090 gp_XYZ aResult (0.0, 0.0, 0.0);
2091 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2092 aStructIter.More(); aStructIter.Next())
2094 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2095 if (!aStruct->IsVisible()
2096 || (hasSelection && !aStruct->IsHighlighted())
2097 || aStruct->IsEmpty())
2102 Bnd_Box aBox = aStruct->MinMaxValues();
2103 if (aBox.IsVoid() || aStruct->IsInfinite())
2108 // use camera projection to find gravity point
2109 aBox.Get (Xmin, Ymin, Zmin,
2111 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2113 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2114 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2115 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2116 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2119 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2121 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2122 const gp_Pnt aProjected = myCamera->Project (aBndPnt);
2123 if (Abs (aProjected.X()) <= 1.0
2124 && Abs (aProjected.Y()) <= 1.0)
2126 aResult += aBndPnt.XYZ();
2134 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2135 aStructIter.More(); aStructIter.Next())
2137 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2138 if (aStruct->IsEmpty())
2143 Bnd_Box aBox = aStruct->MinMaxValues();
2144 if (aBox.IsVoid() || aStruct->IsInfinite())
2149 aBox.Get (Xmin, Ymin, Zmin,
2151 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2153 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2154 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2155 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2156 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2159 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2161 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2162 aResult += aBndPnt.XYZ();
2170 aResult /= aNbPoints;
2177 //=======================================================================
2180 //=======================================================================
2181 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2183 gp_Pnt aCameraEye = myCamera->Eye();
2189 //=============================================================================
2190 //function : FocalReferencePoint
2192 //=============================================================================
2193 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2198 //=============================================================================
2199 //function : ProjReferenceAxe
2201 //=============================================================================
2202 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2203 const Standard_Integer Ypix,
2209 Standard_Real& VZ) const
2211 Standard_Real Xo,Yo,Zo;
2213 Convert (Xpix, Ypix, XP, YP, ZP);
2214 if ( Type() == V3d_PERSPECTIVE )
2216 FocalReferencePoint (Xo,Yo,Zo);
2227 //=============================================================================
2230 //=============================================================================
2231 Standard_Real V3d_View::Depth() const
2233 return myCamera->Distance();
2236 //=============================================================================
2239 //=============================================================================
2240 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2242 gp_Dir aCameraDir = myCamera->Direction().Reversed();
2243 Dx = aCameraDir.X();
2244 Dy = aCameraDir.Y();
2245 Dz = aCameraDir.Z();
2248 //=============================================================================
2251 //=============================================================================
2252 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2254 gp_Pnt aCameraCenter = myCamera->Center();
2255 X = aCameraCenter.X();
2256 Y = aCameraCenter.Y();
2257 Z = aCameraCenter.Z();
2260 //=============================================================================
2263 //=============================================================================
2264 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2266 gp_Dir aCameraUp = myCamera->Up();
2272 //=============================================================================
2275 //=============================================================================
2276 Standard_Real V3d_View::Twist() const
2278 Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2279 Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
2280 Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
2281 Standard_Boolean TheStatus ;
2283 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
2287 anUp = gp_Dir (0.,0.,1.) ;
2288 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2290 anUp = gp_Dir (0.,1.,0.) ;
2291 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2294 anUp = gp_Dir (1.,0.,0.) ;
2295 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2297 Yaxis.Coord(X0,Y0,Z0) ;
2300 /* Compute Cross Vector From Up & Origin */
2301 pvx = Y0*Zup - Z0*Yup ;
2302 pvy = Z0*Xup - X0*Zup ;
2303 pvz = X0*Yup - Y0*Xup ;
2304 pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2305 sca = X0*Xup + Y0*Yup + Z0*Zup ;
2308 if( angle > 1. ) angle = 1. ;
2309 else if( angle < -1. ) angle = -1. ;
2310 angle = asin(angle) ;
2311 if( sca < 0. ) angle = M_PI - angle ;
2312 if( angle > 0. && angle < M_PI ) {
2313 sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2314 if( sca < 0. ) angle = DEUXPI - angle ;
2319 //=============================================================================
2320 //function : ShadingModel
2322 //=============================================================================
2323 V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2325 V3d_TypeOfShadingModel SM = (V3d_TypeOfShadingModel)MyViewContext.Model() ;
2329 //=============================================================================
2330 //function : SurfaceDetail
2332 //=============================================================================
2333 V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
2335 V3d_TypeOfSurfaceDetail SM = (V3d_TypeOfSurfaceDetail)MyViewContext.SurfaceDetail() ;
2339 //=============================================================================
2340 //function : TextureEnv
2342 //=============================================================================
2343 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2345 Handle(Graphic3d_TextureEnv) SM = MyViewContext.TextureEnv() ;
2349 //=============================================================================
2350 //function : Visualization
2352 //=============================================================================
2353 V3d_TypeOfVisualization V3d_View::Visualization() const
2355 V3d_TypeOfVisualization V =
2356 (V3d_TypeOfVisualization)MyViewContext.Visualization() ;
2360 //=============================================================================
2361 //function : Antialiasing
2363 //=============================================================================
2364 Standard_Boolean V3d_View::Antialiasing() const
2366 Standard_Boolean A = MyViewContext.AliasingIsOn() ;
2370 //=============================================================================
2373 //=============================================================================
2374 Handle(V3d_Viewer) V3d_View::Viewer() const
2379 //=============================================================================
2380 //function : IfWindow
2382 //=============================================================================
2383 Standard_Boolean V3d_View::IfWindow() const
2385 Standard_Boolean TheStatus = MyView->IsDefined() ;
2389 //=============================================================================
2392 //=============================================================================
2393 Handle(Aspect_Window) V3d_View::Window() const
2398 //=============================================================================
2401 //=============================================================================
2402 V3d_TypeOfView V3d_View::Type() const
2404 return myCamera->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2407 //=============================================================================
2408 //function : SetFocale
2410 //=============================================================================
2411 void V3d_View::SetFocale( const Standard_Real focale )
2413 if (myCamera->IsOrthographic())
2418 Standard_Real aFOVyRad = ATan (focale / (myCamera->Distance() * 2.0));
2420 myCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2425 //=============================================================================
2428 //=============================================================================
2429 Standard_Real V3d_View::Focale() const
2431 if (myCamera->IsOrthographic())
2436 return myCamera->Distance() * 2.0 * Tan(myCamera->FOVy() * M_PI / 360.0);
2439 //=============================================================================
2442 //=============================================================================
2443 Handle(Visual3d_View) V3d_View::View() const
2448 //=============================================================================
2449 //function : ScreenAxis
2451 //=============================================================================
2452 Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2454 Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2455 Standard_Real dx1, dy1, dz1, xx, yy, zz;
2457 Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2458 Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2459 xx = Yup*Zpn - Zup*Ypn;
2460 yy = Zup*Xpn - Xup*Zpn;
2461 zz = Xup*Ypn - Yup*Xpn;
2462 Xaxe.SetCoord (xx, yy, zz);
2463 if (Xaxe.LengthZero()) return Standard_False;
2465 Xaxe.Coord(dx1, dy1, dz1);
2466 xx = Ypn*dz1 - Zpn*dy1;
2467 yy = Zpn*dx1 - Xpn*dz1;
2468 zz = Xpn*dy1 - Ypn*dx1;
2469 Yaxe.SetCoord (xx, yy, zz) ;
2470 if (Yaxe.LengthZero()) return Standard_False;
2473 Zaxe.SetCoord (Xpn, Ypn, Zpn);
2475 return Standard_True;
2478 //=============================================================================
2479 //function : TrsPoint
2481 //=============================================================================
2482 Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2484 Graphic3d_Vertex PP ;
2485 Standard_Real X,Y,Z,XX,YY,ZZ ;
2488 Standard_Integer lr, ur, lc, uc;
2489 lr = Matrix.LowerRow ();
2490 ur = Matrix.UpperRow ();
2491 lc = Matrix.LowerCol ();
2492 uc = Matrix.UpperCol ();
2493 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
2495 PP.SetCoord(X,Y,Z) ;
2499 XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2500 Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2502 YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2503 Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2505 ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2506 Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2507 PP.SetCoord(XX,YY,ZZ) ;
2511 //=======================================================================
2514 //=======================================================================
2515 void V3d_View::Pan (const Standard_Integer theDXp,
2516 const Standard_Integer theDYp,
2517 const Quantity_Factor theZoomFactor,
2518 const Standard_Boolean theToStart)
2520 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2523 //=======================================================================
2524 //function : Panning
2526 //=======================================================================
2527 void V3d_View::Panning (const Standard_Real theDXv,
2528 const Standard_Real theDYv,
2529 const Quantity_Factor theZoomFactor,
2530 const Standard_Boolean theToStart)
2532 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2536 myCamStartOpEye = myCamera->Eye();
2537 myCamStartOpCenter = myCamera->Center();
2540 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2542 gp_Pnt aViewDims = myCamera->ViewDimensions();
2544 myCamera->SetEye (myCamStartOpEye);
2545 myCamera->SetCenter (myCamStartOpCenter);
2546 Translate (myCamera, -theDXv, -theDYv);
2547 Scale (myCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2549 SetImmediateUpdate (wasUpdateEnabled);
2554 //=======================================================================
2557 //=======================================================================
2558 void V3d_View::Zoom (const Standard_Integer theXp1,
2559 const Standard_Integer theYp1,
2560 const Standard_Integer theXp2,
2561 const Standard_Integer theYp2)
2563 Standard_Integer aDx = theXp2 - theXp1;
2564 Standard_Integer aDy = theYp2 - theYp1;
2565 if (aDx != 0 || aDy != 0)
2567 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2568 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2569 SetZoom (aCoeff, Standard_True);
2573 //=======================================================================
2574 //function : StartZoomAtPoint
2576 //=======================================================================
2577 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2578 const Standard_Integer theYp)
2580 MyZoomAtPointX = theXp;
2581 MyZoomAtPointY = theYp;
2584 //=======================================================================
2585 //function : ZoomAtPoint
2587 //=======================================================================
2588 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2589 const Standard_Integer theMouseStartY,
2590 const Standard_Integer theMouseEndX,
2591 const Standard_Integer theMouseEndY)
2593 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2596 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2597 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2598 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2600 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2602 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
2603 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
2605 // ensure that zoom will not be too small or too big.
2606 Standard_Real aCoef = aDZoom;
2607 if (aViewWidth < aCoef * Precision::Confusion())
2609 aCoef = aViewWidth / Precision::Confusion();
2611 else if (aViewWidth > aCoef * 1e12)
2613 aCoef = aViewWidth / 1e12;
2615 if (aViewHeight < aCoef * Precision::Confusion())
2617 aCoef = aViewHeight / Precision::Confusion();
2619 else if (aViewHeight > aCoef * 1e12)
2621 aCoef = aViewHeight / 1e12;
2624 Standard_Real aZoomAtPointXv = 0.0;
2625 Standard_Real aZoomAtPointYv = 0.0;
2626 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2628 V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
2629 V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
2631 myCamera->SetScale (myCamera->Scale() / aCoef);
2632 Translate (myCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2636 SetImmediateUpdate (wasUpdateEnabled);
2641 //=============================================================================
2642 //function : AxialScale
2644 //=============================================================================
2645 void V3d_View::AxialScale (const Standard_Integer Dx,
2646 const Standard_Integer Dy,
2647 const V3d_TypeOfAxe Axis)
2649 if( Dx != 0. || Dy != 0. ) {
2650 Standard_Real Sx, Sy, Sz;
2651 AxialScale( Sx, Sy, Sz );
2652 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2653 dscale = (Dx > 0) ? dscale : 1./dscale;
2654 if( Axis == V3d_X ) Sx = dscale;
2655 if( Axis == V3d_Y ) Sy = dscale;
2656 if( Axis == V3d_Z ) Sz = dscale;
2657 SetAxialScale( Sx, Sy, Sz );
2661 //=============================================================================
2664 //=============================================================================
2665 void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
2666 const Standard_Real Xmin,
2667 const Standard_Real Ymin,
2668 const Standard_Real Xmax,
2669 const Standard_Real Ymax)
2671 Standard_Integer aWinWidth, aWinHeight;
2672 aWindow->Size (aWinWidth, aWinHeight);
2674 Standard_Real aWinAspect = (Standard_Real)aWinWidth / aWinHeight;
2675 Standard_Real aFitSizeU = Abs (Xmax - Xmin);
2676 Standard_Real aFitSizeV = Abs (Ymax - Ymin);
2677 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2678 if (aFitAspect >= aWinAspect)
2680 aFitSizeV = aFitSizeU / aWinAspect;
2684 aFitSizeU = aFitSizeV * aWinAspect;
2687 myCamera->SetAspect (aWinAspect);
2688 Translate (myCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
2689 Scale (myCamera, aFitSizeU, aFitSizeV);
2695 //=============================================================================
2696 //function : StartRotation
2698 //=============================================================================
2699 static Standard_Boolean zRotation = Standard_False;
2700 void V3d_View::StartRotation(const Standard_Integer X,
2701 const Standard_Integer Y,
2702 const Quantity_Ratio zRotationThreshold)
2707 rx = Standard_Real(Convert(x));
2708 ry = Standard_Real(Convert(y));
2710 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2711 zRotation = Standard_False;
2712 if( zRotationThreshold > 0. ) {
2713 Standard_Real dx = Abs(sx - rx/2.);
2714 Standard_Real dy = Abs(sy - ry/2.);
2715 // if( dx > rx/3. || dy > ry/3. ) zRotation = Standard_True;
2716 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2717 if( dx > dd || dy > dd ) zRotation = Standard_True;
2722 //=============================================================================
2723 //function : Rotation
2725 //=============================================================================
2726 void V3d_View::Rotation(const Standard_Integer X,
2727 const Standard_Integer Y)
2729 if( rx == 0. || ry == 0. ) {
2733 Standard_Real dx=0.,dy=0.,dz=0.;
2735 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2736 atan2(sx-rx/2.,ry/2.-sy);
2738 dx = (Standard_Real(X) - sx) * M_PI / rx;
2739 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2742 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2745 //=============================================================================
2746 //function : SetComputedMode
2748 //=============================================================================
2749 void V3d_View::SetComputedMode (const Standard_Boolean aMode)
2755 MyView->SetComputedMode (Standard_True);
2761 MyView->SetComputedMode (Standard_False);
2766 //=============================================================================
2767 //function : ComputedMode
2769 //=============================================================================
2770 Standard_Boolean V3d_View::ComputedMode() const
2772 return MyView->ComputedMode();
2775 //=============================================================================
2776 //function : SetBackFacingModel
2778 //=============================================================================
2779 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel aModel)
2781 MyView->SetBackFacingModel (Visual3d_TypeOfBackfacingModel(aModel));
2785 //=============================================================================
2786 //function : BackFacingModel
2788 //=============================================================================
2789 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2791 return V3d_TypeOfBackfacingModel(MyView -> BackFacingModel ());
2794 void V3d_View::Init()
2796 myComputedMode = MyViewer->ComputedMode();
2797 if( !myComputedMode || !MyViewer->DefaultComputedMode() ) {
2798 SetComputedMode(Standard_False);
2802 //=============================================================================
2805 //=============================================================================
2806 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2807 const Graphic3d_BufferType& theBufferType)
2809 Standard_Integer aWinWidth, aWinHeight;
2810 MyWindow->Size (aWinWidth, aWinHeight);
2811 Image_AlienPixMap anImage;
2813 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2816 //=============================================================================
2817 //function : ToPixMap
2819 //=============================================================================
2820 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
2821 const Standard_Integer theWidth,
2822 const Standard_Integer theHeight,
2823 const Graphic3d_BufferType& theBufferType,
2824 const Standard_Boolean theToKeepAspect,
2825 const V3d_StereoDumpOptions theStereoOptions)
2827 Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
2829 // always prefer hardware accelerated offscreen buffer
2830 Graphic3d_PtrFrameBuffer aFBOPtr = NULL;
2831 Graphic3d_PtrFrameBuffer aPrevFBOPtr = (Graphic3d_PtrFrameBuffer )cView->ptrFBO;
2832 Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
2833 Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
2834 if (aPrevFBOPtr != NULL)
2836 MyView->FBOGetDimensions (aPrevFBOPtr,
2837 aPrevFBOVPSizeX, aPrevFBOVPSizeY,
2838 aPrevFBOSizeXMax, aPrevFBOSizeYMax);
2839 if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
2841 MyView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
2842 aFBOPtr = aPrevFBOPtr;
2846 if (aFBOPtr == NULL)
2848 // Try to create hardware accelerated buffer
2849 aFBOPtr = MyView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
2850 if (aFBOPtr != NULL)
2852 MyView->FBOGetDimensions (aFBOPtr,
2853 aFBOVPSizeX, aFBOVPSizeY,
2854 aFBOSizeXMax, aFBOSizeYMax);
2855 // reduce viewport in case of hardware limits
2856 if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
2857 if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
2858 MyView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
2861 cView->ptrFBO = aFBOPtr;
2863 // If hardware accelerated buffer - try to use onscreen buffer
2864 // Results may be bad!
2865 if (aFBOPtr == NULL)
2867 // retrieve window sizes
2868 Standard_Integer aWinWidth, aWinHeight;
2869 MyWindow->Size (aWinWidth, aWinHeight);
2871 // technically we can reduce existing viewport...
2872 // but currently allow only dumping the window itself
2873 if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
2875 return Standard_False;
2879 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2881 aStoreMapping->Copy (myCamera);
2883 if (myCamera->IsStereo())
2885 switch (theStereoOptions)
2889 myCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2892 case V3d_SDO_LEFT_EYE:
2894 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2897 case V3d_SDO_RIGHT_EYE:
2899 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2902 case V3d_SDO_BLENDED:
2904 break; // dump as is
2909 // render immediate structures into back buffer rather than front
2910 Handle(Graphic3d_GraphicDriver) aDriver = Handle(Graphic3d_GraphicDriver)::DownCast (MyView->GraphicDriver());
2911 const Standard_Boolean aPrevImmediateMode = aDriver.IsNull() ? Standard_True : aDriver->SetImmediateModeDrawToFront (*cView, Standard_False);
2913 const Standard_Boolean toAutoUpdate = myImmediateUpdate;
2914 myImmediateUpdate = Standard_False;
2916 myImmediateUpdate = toAutoUpdate;
2918 if (theToKeepAspect)
2920 myCamera->SetAspect ((Standard_Real) aFBOVPSizeX / aFBOVPSizeY);
2923 //workaround for rendering list of Over and Under Layers
2924 if (!MyLayerMgr.IsNull())
2926 MyLayerMgr->Compute();
2931 if (!aDriver.IsNull())
2933 aDriver->SetImmediateModeDrawToFront (*cView, aPrevImmediateMode);
2936 myCamera->Copy (aStoreMapping);
2938 Standard_Boolean isSuccess = Standard_True;
2940 // allocate image buffer for dumping
2941 if (theImage.IsEmpty()
2942 || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
2943 || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
2945 bool isBigEndian = Image_PixMap::IsBigEndianHost();
2946 Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
2947 switch (theBufferType)
2949 case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
2950 case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
2951 case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
2954 isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
2956 isSuccess = isSuccess && MyView->BufferDump (theImage, theBufferType);
2958 // FBO now useless, free resources
2959 if (aFBOPtr != aPrevFBOPtr)
2961 MyView->FBORelease (aFBOPtr);
2963 else if (aPrevFBOPtr != NULL)
2965 MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
2967 cView->ptrFBO = aPrevFBOPtr;
2971 void V3d_View::ImmediateUpdate() const
2973 if (myImmediateUpdate) Update();
2976 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2978 Standard_Boolean aPreviousMode = myImmediateUpdate;
2979 myImmediateUpdate = theImmediateUpdate;
2980 return aPreviousMode;
2983 // =======================================================================
2984 // function : SetCamera
2986 // =======================================================================
2987 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2989 Standard_ASSERT_RAISE (!theCamera.IsNull(), "Void camera is not allowed");
2991 myCamera = theCamera;
2993 MyView->SetCamera (theCamera);
2996 // =======================================================================
2997 // function : GetCamera
2999 // =======================================================================
3000 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
3005 // =======================================================================
3006 // function : FitMinMax
3007 // purpose : Internal
3008 // =======================================================================
3009 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
3010 const Bnd_Box& theBox,
3011 const Standard_Real theMargin,
3012 const Standard_Real theResolution,
3013 const Standard_Boolean theToEnlargeIfLine) const
3015 // Check bounding box for validness
3016 if (theBox.IsVoid())
3018 return Standard_False; // bounding box is out of bounds...
3021 // Apply "axial scaling" to the bounding points.
3022 // It is not the best approach to make this scaling as a part of fit all operation,
3023 // but the axial scale is integrated into camera orientation matrix and the other
3024 // option is to perform frustum plane adjustment algorithm in view camera space,
3025 // which will lead to a number of additional world-view space conversions and
3026 // loosing precision as well.
3027 gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (theCamera->AxialScale());
3028 gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (theCamera->AxialScale());
3030 if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
3032 return Standard_False; // nothing to fit all
3035 // Prepare camera frustum planes.
3036 NCollection_Array1<gp_Pln> aFrustumPlane (1, 6);
3037 theCamera->Frustum (aFrustumPlane.ChangeValue (1),
3038 aFrustumPlane.ChangeValue (2),
3039 aFrustumPlane.ChangeValue (3),
3040 aFrustumPlane.ChangeValue (4),
3041 aFrustumPlane.ChangeValue (5),
3042 aFrustumPlane.ChangeValue (6));
3044 // Prepare camera up, side, direction vectors.
3045 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3046 gp_Dir aCamDir = theCamera->Direction();
3047 gp_Dir aCamSide = aCamDir ^ aCamUp;
3049 // Prepare scene bounding box parameters.
3050 gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
3052 NCollection_Array1<gp_Pnt> aBndCorner (1, 8);
3053 aBndCorner.ChangeValue (1) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
3054 aBndCorner.ChangeValue (2) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
3055 aBndCorner.ChangeValue (3) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
3056 aBndCorner.ChangeValue (4) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
3057 aBndCorner.ChangeValue (5) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
3058 aBndCorner.ChangeValue (6) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
3059 aBndCorner.ChangeValue (7) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
3060 aBndCorner.ChangeValue (8) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
3062 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3063 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3064 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3065 // set up perspective-correct camera projection matching the bounding box.
3066 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3067 // The zooming can be done by calculating view plane size matching the bounding box at center of
3068 // the bounding box. The only limitation here is that the scale of camera should define size of
3069 // its view plane passing through the camera center, and the center of camera should be on the
3070 // same line with the center of bounding box.
3072 // The following method is applied:
3073 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3074 // 2) Determine new location of frustum planes, "matching" the bounding box.
3075 // 3) Determine new camera projection vector using the normalized asymmetry.
3076 // 4) Determine new zooming in view space.
3078 // 1. Determine normalized projection asymmetry (if any).
3079 Standard_Real anAssymX = Tan ( aCamSide.Angle (aFrustumPlane (1).Axis().Direction()))
3080 - Tan (-aCamSide.Angle (aFrustumPlane (2).Axis().Direction()));
3081 Standard_Real anAssymY = Tan ( aCamUp.Angle (aFrustumPlane (3).Axis().Direction()))
3082 - Tan (-aCamUp.Angle (aFrustumPlane (4).Axis().Direction()));
3084 // 2. Determine how far should be the frustum planes placed from center
3085 // of bounding box, in order to match the bounding box closely.
3086 NCollection_Array1<Standard_Real> aFitDistance (1, 6);
3087 aFitDistance.ChangeValue (1) = 0.0;
3088 aFitDistance.ChangeValue (2) = 0.0;
3089 aFitDistance.ChangeValue (3) = 0.0;
3090 aFitDistance.ChangeValue (4) = 0.0;
3091 aFitDistance.ChangeValue (5) = 0.0;
3092 aFitDistance.ChangeValue (6) = 0.0;
3094 for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
3096 // Measure distances from center of bounding box to its corners towards the frustum plane.
3097 const gp_Dir& aPlaneN = aFrustumPlane.ChangeValue (anI).Axis().Direction();
3099 Standard_Real& aFitDist = aFitDistance.ChangeValue (anI);
3101 for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
3103 aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner (aJ)).Dot (aPlaneN));
3106 // The center of camera is placed on the same line with center of bounding box.
3107 // The view plane section crosses the bounding box at its center.
3108 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3109 // into view section size between the point and the frustum plane.
3111 // /|\ right half of frame //
3113 // point o<-- distance * coeff -->//---- (view plane section)
3122 aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan ( aCamSide.Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
3123 aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan (-aCamSide.Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
3124 aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan ( aCamUp.Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
3125 aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan (-aCamUp.Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
3126 aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan ( aCamDir.Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
3127 aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan (-aCamDir.Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
3129 Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
3130 Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
3131 Standard_Real aViewSizeZv = aFitDistance (5) + aFitDistance (6);
3133 // 3. Place center of camera on the same line with center of bounding
3134 // box applying corresponding projection asymmetry (if any).
3135 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3136 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3137 Standard_Real anOffsetXv = (aFitDistance (2) - aFitDistance (1)) * 0.5 + anAssymXv;
3138 Standard_Real anOffsetYv = (aFitDistance (4) - aFitDistance (3)) * 0.5 + anAssymYv;
3139 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3140 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3141 gp_Pnt aCamNewCenter = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3143 gp_Trsf aCenterTrsf;
3144 aCenterTrsf.SetTranslation (theCamera->Center(), aCamNewCenter);
3145 theCamera->Transform (aCenterTrsf);
3146 theCamera->SetDistance (aFitDistance (6) + aFitDistance (5));
3148 // Bounding box collapses to a point or thin line going in depth of the screen
3149 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3151 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3153 return Standard_True; // This is just one point or line and zooming has no effect.
3156 // Looking along line and "theToEnlargeIfLine" is requested.
3157 // Fit view to see whole scene on rotation.
3158 aViewSizeXv = aViewSizeZv;
3159 aViewSizeYv = aViewSizeZv;
3162 Scale (theCamera, aViewSizeXv * (1.0 + theMargin), aViewSizeYv * (1.0 + theMargin));
3164 return Standard_True;
3167 // =======================================================================
3169 // purpose : Internal
3170 // =======================================================================
3171 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3172 const Standard_Real theSizeXv,
3173 const Standard_Real theSizeYv) const
3175 Standard_Real anAspect = theCamera->Aspect();
3178 theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
3182 theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
3186 // =======================================================================
3187 // function : Translate
3188 // purpose : Internal
3189 // =======================================================================
3190 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3191 const Standard_Real theDXv,
3192 const Standard_Real theDYv) const
3194 const gp_Pnt& aCenter = theCamera->Center();
3195 const gp_Dir& aDir = theCamera->Direction();
3196 const gp_Dir& anUp = theCamera->Up();
3197 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3199 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3200 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3201 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3203 aPanTrsf.SetTranslation (aCameraPan);
3205 theCamera->Transform (aPanTrsf);
3208 // =======================================================================
3209 // function : IsCullingEnabled
3211 // =======================================================================
3212 Standard_Boolean V3d_View::IsCullingEnabled() const
3214 Graphic3d_CView* aView = (Graphic3d_CView* )MyView->CView();
3215 return aView->IsCullingEnabled;
3218 // =======================================================================
3219 // function : SetFrustumCulling
3221 // =======================================================================
3222 void V3d_View::SetFrustumCulling (const Standard_Boolean theToClip)
3224 Graphic3d_CView* aView = (Graphic3d_CView* )MyView->CView();
3225 aView->IsCullingEnabled = theToClip;