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_GradientBackground.hxx>
70 #include <Aspect_Grid.hxx>
71 #include <Aspect_Window.hxx>
72 #include <Bnd_Box.hxx>
76 #include <Graphic3d_AspectMarker3d.hxx>
77 #include <Graphic3d_GraphicDriver.hxx>
78 #include <Graphic3d_Group.hxx>
79 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
80 #include <Graphic3d_MapOfStructure.hxx>
81 #include <Graphic3d_Structure.hxx>
82 #include <Graphic3d_TextureEnv.hxx>
83 #include <Graphic3d_Vector.hxx>
84 #include <Image_AlienPixMap.hxx>
85 #include <NCollection_Array1.hxx>
86 #include <Precision.hxx>
87 #include <Quantity_Color.hxx>
88 #include <Standard_Assert.hxx>
89 #include <Standard_DivideByZero.hxx>
90 #include <Standard_ErrorHandler.hxx>
91 #include <Standard_MultiplyDefined.hxx>
92 #include <Standard_ShortReal.hxx>
93 #include <Standard_Type.hxx>
94 #include <Standard_TypeMismatch.hxx>
95 #include <TColStd_Array2OfReal.hxx>
96 #include <TColStd_HSequenceOfInteger.hxx>
98 #include <V3d_BadValue.hxx>
99 #include <V3d_LayerMgr.hxx>
100 #include <V3d_Light.hxx>
101 #include <V3d_StereoDumpOptions.hxx>
102 #include <V3d_UnMapped.hxx>
103 #include <V3d_View.hxx>
104 #include <V3d_Viewer.hxx>
105 #include <Visual3d_Layer.hxx>
106 #include <Visual3d_Light.hxx>
107 #include <Visual3d_View.hxx>
108 #include <Visual3d_ViewManager.hxx>
110 #define V3d_FLAG_COMPUTATION 0x00000004
113 #include <OSD_Environment.hxx>
115 /*----------------------------------------------------------------------*/
120 #define DEUXPI (2. * M_PI)
124 static const Standard_Integer THE_NB_BOUND_POINTS = 8;
127 //=============================================================================
128 //function : Constructor
130 //=============================================================================
131 V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) :
132 MyViewer(VM.operator->()),
135 myActiveLightsIterator(),
136 SwitchSetFront(Standard_False),
139 myImmediateUpdate = Standard_False;
140 MyView = new Visual3d_View(MyViewer->Viewer());
142 // { Begin to retrieve the definition from ViewContext.
143 // Step MyViewContext = MyView->Context() ;
144 // to permit MyView->SetContext to compare
145 // the old and the new context.
146 // No problem for MyViewMapping, MyViewOrientation
147 // as MyView->SetViewMapping and MyView->SetViewOrientation
148 // don't try to optimize the modifications introduced to
149 // viewmapping and vieworientation.
152 if ((MyView->Context ()).AliasingIsOn ())
153 MyViewContext.SetAliasingOn ();
155 MyViewContext.SetAliasingOff ();
158 MyViewContext.SetDepthCueingBackPlane
159 ((MyView->Context ()).DepthCueingBackPlane ());
160 MyViewContext.SetDepthCueingFrontPlane
161 ((MyView->Context ()).DepthCueingFrontPlane ());
163 if ((MyView->Context ()).DepthCueingIsOn ())
164 MyViewContext.SetDepthCueingOn ();
166 MyViewContext.SetDepthCueingOff ();
169 MyViewContext.SetZClippingBackPlane
170 ((MyView->Context ()).ZClippingBackPlane ());
171 MyViewContext.SetZClippingFrontPlane
172 ((MyView->Context ()).ZClippingFrontPlane ());
174 if ((MyView->Context ()).FrontZClippingIsOn ())
175 MyViewContext.SetFrontZClippingOn ();
177 MyViewContext.SetFrontZClippingOff ();
179 if ((MyView->Context ()).BackZClippingIsOn ())
180 MyViewContext.SetBackZClippingOn ();
182 MyViewContext.SetBackZClippingOff ();
184 // Visualization and Shading Model
185 MyViewContext.SetModel ((MyView->Context ()).Model ());
186 MyViewContext.SetVisualization ((MyView->Context ()).Visualization ());
189 MyViewContext.SetSurfaceDetail (MyView->Context ().SurfaceDetail ());
190 MyViewContext.SetTextureEnv (MyView->Context ().TextureEnv ());
191 // } End of retrieval of the definition of ViewContext.
193 MyBackground = VM->GetBackgroundColor() ;
194 MyGradientBackground = VM->GetGradientBackground() ;
197 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
198 aCamera->SetFOVy (45.0);
199 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
200 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
203 SetAxis (0.,0.,0.,1.,1.,1.);
204 SetVisualization (VM->DefaultVisualization());
205 SetShadingModel (VM->DefaultShadingModel());
206 SetSurfaceDetail (VM->DefaultSurfaceDetail());
209 SetProj (VM->DefaultViewProj());
210 SetSize (VM->DefaultViewSize());
211 Standard_Real zsize = VM->DefaultViewSize();
213 SetZClippingDepth (0.);
214 SetZClippingWidth (zsize);
215 SetZCueingDepth (0.);
216 SetZCueingWidth (zsize);
217 SetDepth (VM->DefaultViewSize()/2.0);
218 SetViewMappingDefault();
219 SetViewOrientationDefault();
222 myImmediateUpdate = Standard_True;
224 aCamera->SetProjectionType ((Type == V3d_ORTHOGRAPHIC)
225 ? Graphic3d_Camera::Projection_Orthographic
226 : Graphic3d_Camera::Projection_Perspective);
229 //=============================================================================
230 //function : Constructor
232 //=============================================================================
233 V3d_View::V3d_View(const Handle(V3d_Viewer)& theVM,const Handle(V3d_View)& theView) :
234 MyViewer(theVM.operator->()),
237 myActiveLightsIterator(),
238 SwitchSetFront(Standard_False),
241 Handle(Visual3d_View) aFromView = theView->View();
243 myImmediateUpdate = Standard_False;
244 MyView = new Visual3d_View (MyViewer->Viewer());
246 for (theView->InitActiveLights(); theView->MoreActiveLights(); theView->NextActiveLights())
248 MyActiveLights.Append (theView->ActiveLight());
251 MyViewContext = aFromView->Context() ;
253 SetCamera (new Graphic3d_Camera (theView->Camera()));
254 View()->SetAutoZFitMode (theView->View()->AutoZFitMode(), theView->View()->AutoZFitScaleFactor());
256 MyBackground = aFromView->Background() ;
257 MyGradientBackground = aFromView->GradientBackground();
259 MyView->SetContext (MyViewContext) ;
261 SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
263 SetViewMappingDefault();
264 SetViewOrientationDefault();
265 theVM->AddView (this);
269 myImmediateUpdate = Standard_True;
272 //=============================================================================
273 //function : SetMagnify
275 //=============================================================================
276 void V3d_View::SetMagnify(const Handle(Aspect_Window)& TheWindow,
277 const Handle(V3d_View)& aPreviousView,
278 const Standard_Integer x1,
279 const Standard_Integer y1,
280 const Standard_Integer x2,
281 const Standard_Integer y2)
283 if( !MyView->IsDefined() ) {
284 Standard_Real a,b,c,d;
285 aPreviousView->Convert(x1,y1,a,b);
286 aPreviousView->Convert(x2,y2,c,d);
287 MyView->SetWindow(TheWindow) ;
288 FitAll(TheWindow,a,b,c,d);
289 MyView->SetContext(MyViewContext) ;
290 MyView->SetBackground(MyBackground) ;
291 MyViewer->SetViewOn(this) ;
292 MyWindow = TheWindow;
294 SetViewMappingDefault();
298 //=============================================================================
299 //function : SetWindow
301 //=============================================================================
302 void V3d_View::SetWindow(const Handle(Aspect_Window)& TheWindow)
304 MyView->SetWindow(TheWindow) ;
305 // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
306 MyWindow = TheWindow;
307 // SetWindow carries out SetRatio and modifies
308 MyView->SetContext(MyViewContext) ;
309 MyView->SetBackground(MyBackground) ;
310 MyView->SetGradientBackground (MyGradientBackground, Standard_False);
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 MyView->SetGradientBackground (MyGradientBackground, Standard_False);
330 MyViewer->SetViewOn(this) ;
334 //=============================================================================
337 //=============================================================================
338 void V3d_View::Remove() const
340 MyViewer->DelView (this);
342 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
346 //=============================================================================
349 //=============================================================================
350 void V3d_View::Update() const
352 if( MyView->IsDefined() ) MyView->Update (Aspect_TOU_ASAP) ;
355 //=============================================================================
358 //=============================================================================
359 void V3d_View::Redraw() const
361 if( MyView->IsDefined() ) MyView->Redraw() ;
364 //=============================================================================
365 //function : RedrawImmediate
367 //=============================================================================
368 void V3d_View::RedrawImmediate() const
370 if (MyView->IsDefined())
372 MyView->RedrawImmediate();
376 //=============================================================================
377 //function : Invalidate
379 //=============================================================================
380 void V3d_View::Invalidate() const
382 if (MyView->IsDefined())
384 MyView->Invalidate();
388 //=============================================================================
389 //function : IsInvalidated
391 //=============================================================================
392 Standard_Boolean V3d_View::IsInvalidated() const
394 return !MyView->IsDefined()
395 || MyView->IsInvalidated();
398 //=============================================================================
399 //function : AutoZFit
401 //=============================================================================
402 void V3d_View::AutoZFit()
407 //=============================================================================
410 //=============================================================================
411 void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
413 View()->ZFitAll (theScaleFactor);
416 //=============================================================================
419 //=============================================================================
420 void V3d_View::Redraw(const Standard_Integer xc,const Standard_Integer yc,
421 const Standard_Integer width,const Standard_Integer height) const
423 if( MyView->IsDefined() ) MyView->Redraw(xc,yc,width,height) ;
426 //=============================================================================
429 //=============================================================================
430 Standard_Boolean V3d_View::IsEmpty() const
432 Standard_Boolean TheStatus = Standard_True ;
433 if( MyView->IsDefined() ) {
434 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
435 if( Nstruct > 0 ) TheStatus = Standard_False ;
440 //=============================================================================
441 //function : UpdateLights
443 //=============================================================================
444 void V3d_View::UpdateLights() const
446 MyView->SetContext(MyViewContext);
450 //=============================================================================
451 //function : DoMapping
453 //=============================================================================
454 void V3d_View::DoMapping()
456 if( MyView->IsDefined() ) {
457 (MyView->Window())->DoMapping() ;
461 //=============================================================================
462 //function : MustBeResized
464 //=============================================================================
465 void V3d_View::MustBeResized()
467 if ( !MyLayerMgr.IsNull() )
468 MyLayerMgr->Resized();
470 if( MyView->IsDefined() ) {
476 //=============================================================================
477 //function : SetBackgroundColor
479 //=============================================================================
480 void V3d_View::SetBackgroundColor(const Quantity_TypeOfColor Type, const Standard_Real v1, const Standard_Real v2, const Standard_Real v3)
482 Standard_Real V1 = Max( Min( v1, 1.0 ), 0.0 );
483 Standard_Real V2 = Max( Min( v2, 1.0 ), 0.0 );
484 Standard_Real V3 = Max( Min( v3, 1.0 ), 0.0 );
486 Quantity_Color C( V1, V2, V3, Type );
487 SetBackgroundColor( C );
490 //=============================================================================
491 //function : SetBackgroundColor
493 //=============================================================================
494 void V3d_View::SetBackgroundColor(const Quantity_Color &Color)
496 MyBackground.SetColor( Color );
497 if ( MyView->IsDefined() )
498 MyView->SetBackground( MyBackground );
500 if ( !MyLayerMgr.IsNull() )
501 MyLayerMgr->Resized();
504 //=============================================================================
505 //function : SetBackgroundColor
507 //=============================================================================
508 void V3d_View::SetBackgroundColor(const Quantity_NameOfColor Name)
510 Quantity_Color C( Name );
511 SetBackgroundColor( C );
514 //=============================================================================
515 //function : SetBgGradientColors
517 //=============================================================================
518 void V3d_View::SetBgGradientColors( const Quantity_Color& Color1,
519 const Quantity_Color& Color2,
520 const Aspect_GradientFillMethod FillStyle,
521 const Standard_Boolean status)
523 MyGradientBackground.SetColors(Color1, Color2, FillStyle);
524 if ( MyView->IsDefined() )
525 MyView->SetGradientBackground( MyGradientBackground, status );
528 //=============================================================================
529 //function : SetBgGradientColors
531 //=============================================================================
532 void V3d_View::SetBgGradientColors( const Quantity_NameOfColor Color1,
533 const Quantity_NameOfColor Color2,
534 const Aspect_GradientFillMethod FillStyle,
535 const Standard_Boolean status )
537 Quantity_Color C1( Color1 );
538 Quantity_Color C2( Color2 );
539 MyGradientBackground.SetColors( C1, C2, FillStyle );
540 if ( MyView->IsDefined() )
541 MyView->SetGradientBackground( MyGradientBackground, status );
544 //=============================================================================
545 //function : SetBgGradientStyle
547 //=============================================================================
548 void V3d_View::SetBgGradientStyle( const Aspect_GradientFillMethod FillStyle,
549 const Standard_Boolean update)
551 Quantity_Color Color1, Color2;
552 MyGradientBackground.Colors( Color1, Color2 );
553 MyGradientBackground.SetColors( Color1, Color2, FillStyle );
554 if( MyView->IsDefined() )
555 MyView->SetBgGradientStyle( FillStyle, update ) ;
558 //=============================================================================
559 //function : SetBackgroundImage
561 //=============================================================================
562 void V3d_View::SetBackgroundImage( const Standard_CString FileName,
563 const Aspect_FillMethod FillStyle,
564 const Standard_Boolean update )
566 if( MyView->IsDefined() )
567 MyView->SetBackgroundImage( FileName, FillStyle, update ) ;
570 //=============================================================================
571 //function : SetBgImageStyle
573 //=============================================================================
574 void V3d_View::SetBgImageStyle( const Aspect_FillMethod FillStyle,
575 const Standard_Boolean update )
577 if( MyView->IsDefined() )
578 MyView->SetBgImageStyle( FillStyle, update ) ;
581 //=============================================================================
584 //=============================================================================
585 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)
587 Standard_Real D,Nx = Vx,Ny = Vy,Nz = Vz ;
589 D = Sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) ;
590 V3d_BadValue_Raise_if ( D <= 0. , "V3d_View::SetAxis, bad axis");
591 Nx /= D ; Ny /= D ; Nz /= D ;
592 MyDefaultViewPoint.SetCoord(X,Y,Z) ;
593 MyDefaultViewAxis.SetCoord(Nx,Ny,Nz) ;
596 //=============================================================================
597 //function : SetShadingModel
599 //=============================================================================
600 void V3d_View::SetShadingModel(const V3d_TypeOfShadingModel Model)
602 MyViewContext.SetModel((Visual3d_TypeOfModel) Model) ;
603 MyView->SetContext(MyViewContext) ;
606 //=============================================================================
607 //function : SetSurfaceDetail
609 //=============================================================================
610 void V3d_View::SetSurfaceDetail(const V3d_TypeOfSurfaceDetail Model)
612 MyViewContext.SetSurfaceDetail((Visual3d_TypeOfSurfaceDetail) Model) ;
613 MyView->SetContext(MyViewContext) ;
616 //=============================================================================
617 //function : SetTextureEnv
619 //=============================================================================
620 void V3d_View::SetTextureEnv(const Handle(Graphic3d_TextureEnv)& ATexture)
622 MyViewContext.SetTextureEnv(ATexture) ;
623 MyView->SetContext(MyViewContext) ;
626 //=============================================================================
627 //function : SetVisualization
629 //=============================================================================
630 void V3d_View::SetVisualization(const V3d_TypeOfVisualization Mode)
632 MyViewContext.SetVisualization((Visual3d_TypeOfVisualization) Mode);
633 MyView->SetContext(MyViewContext) ;
636 //=============================================================================
637 //function : SetFront
639 //=============================================================================
640 void V3d_View::SetFront()
642 gp_Ax3 a = MyViewer->PrivilegedPlane();
643 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
645 a.Direction().Coord(vx,vy,vz);
646 a.YDirection().Coord(xu,yu,zu);
647 a.Location().Coord(xo,yo,zo);
649 myCamera->SetCenter (gp_Pnt (xo, yo, zo));
651 myCamera->SetDirection (gp_Dir (vx, vy, vz));
653 myCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
654 myCamera->SetUp (gp_Dir (xu, yu, zu));
658 SwitchSetFront = !SwitchSetFront;
663 //=============================================================================
666 //=============================================================================
667 void V3d_View::Rotate (const Standard_Real ax,
668 const Standard_Real ay,
669 const Standard_Real az,
670 const Standard_Boolean Start)
672 Standard_Real Ax = ax;
673 Standard_Real Ay = ay;
674 Standard_Real Az = az;
676 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
677 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
678 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
679 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
680 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
681 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
685 myCamStartOpUp = myCamera->Up();
686 myCamStartOpEye = myCamera->Eye();
687 myCamStartOpCenter = myCamera->Center();
690 myCamera->SetUp (myCamStartOpUp);
691 myCamera->SetEye (myCamStartOpEye);
692 myCamera->SetCenter (myCamStartOpCenter);
694 // rotate camera around 3 initial axes
695 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
696 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
697 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
698 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
700 gp_Trsf aRot[3], aTrsf;
701 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
702 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
703 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
704 aTrsf.Multiply (aRot[0]);
705 aTrsf.Multiply (aRot[1]);
706 aTrsf.Multiply (aRot[2]);
708 myCamera->Transform (aTrsf);
715 //=============================================================================
718 //=============================================================================
719 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
720 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
723 Standard_Real Ax = ax ;
724 Standard_Real Ay = ay ;
725 Standard_Real Az = az ;
727 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
728 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
729 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
730 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
731 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
732 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
736 myGravityReferencePoint.SetCoord (X, Y, Z);
737 myCamStartOpUp = myCamera->Up();
738 myCamStartOpEye = myCamera->Eye();
739 myCamStartOpCenter = myCamera->Center();
742 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
744 myCamera->SetUp (myCamStartOpUp);
745 myCamera->SetEye (myCamStartOpEye);
746 myCamera->SetCenter (myCamStartOpCenter);
748 // rotate camera around 3 initial axes
749 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
751 gp_Dir aZAxis (myCamera->Direction().Reversed());
752 gp_Dir aYAxis (myCamera->Up());
753 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
755 gp_Trsf aRot[3], aTrsf;
756 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
757 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
758 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
759 aTrsf.Multiply (aRot[0]);
760 aTrsf.Multiply (aRot[1]);
761 aTrsf.Multiply (aRot[2]);
763 myCamera->Transform (aTrsf);
770 //=============================================================================
773 //=============================================================================
774 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
778 Rotate(angle,0.,0.,Start);
781 Rotate(0.,angle,0.,Start);
784 Rotate(0.,0.,angle,Start);
789 //=============================================================================
792 //=============================================================================
793 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
794 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
796 Standard_Real Angle = angle ;
798 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
799 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
803 myGravityReferencePoint.SetCoord (X, Y, Z);
804 myCamStartOpUp = myCamera->Up();
805 myCamStartOpEye = myCamera->Eye();
806 myCamStartOpCenter = myCamera->Center();
810 myViewAxis.SetCoord(1.,0.,0.) ;
813 myViewAxis.SetCoord(0.,1.,0.) ;
816 myViewAxis.SetCoord(0.,0.,1.) ;
820 myCamStartOpUp = myCamera->Up();
821 myCamStartOpEye = myCamera->Eye();
822 myCamStartOpCenter = myCamera->Center();
825 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
827 myCamera->SetUp (myCamStartOpUp);
828 myCamera->SetEye (myCamStartOpEye);
829 myCamera->SetCenter (myCamStartOpCenter);
831 // rotate camera around passed axis
833 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
834 gp_Dir aRAxis ((Axe == V3d_X) ? 1.0 : 0.0,
835 (Axe == V3d_Y) ? 1.0 : 0.0,
836 (Axe == V3d_Z) ? 1.0 : 0.0);
838 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
839 myCamera->Transform (aRotation);
846 //=============================================================================
849 //=============================================================================
850 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
852 Standard_Real Angle = angle;
854 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
855 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
858 myCamStartOpUp = myCamera->Up();
859 myCamStartOpEye = myCamera->Eye();
860 myCamStartOpCenter = myCamera->Center();
863 const Graphic3d_Vertex& aPnt = MyDefaultViewPoint;
864 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
866 myCamera->SetUp (myCamStartOpUp);
867 myCamera->SetEye (myCamStartOpEye);
868 myCamera->SetCenter (myCamStartOpCenter);
871 gp_Pnt aRCenter (aPnt.X(), aPnt.Y(), aPnt.Z());
872 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
873 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
874 myCamera->Transform (aRotation);
881 //=============================================================================
884 //=============================================================================
885 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
887 Standard_Real Ax = ax;
888 Standard_Real Ay = ay;
889 Standard_Real Az = az;
891 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
892 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
893 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
894 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
895 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
896 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
899 myCamStartOpUp = myCamera->Up();
900 myCamStartOpEye = myCamera->Eye();
901 myCamStartOpCenter = myCamera->Center();
904 myCamera->SetUp (myCamStartOpUp);
905 myCamera->SetEye (myCamStartOpEye);
906 myCamera->SetCenter (myCamStartOpCenter);
908 // rotate camera around 3 initial axes
909 gp_Pnt aRCenter = myCamera->Eye();
910 gp_Dir aZAxis (myCamera->Direction().Reversed());
911 gp_Dir aYAxis (myCamera->Up());
912 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
914 gp_Trsf aRot[3], aTrsf;
915 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
916 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
917 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
918 aTrsf.Multiply (aRot[0]);
919 aTrsf.Multiply (aRot[1]);
920 aTrsf.Multiply (aRot[2]);
922 myCamera->Transform (aTrsf);
929 //=============================================================================
932 //=============================================================================
933 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
937 Turn(angle,0.,0.,Start);
940 Turn(0.,angle,0.,Start);
943 Turn(0.,0.,angle,Start);
948 //=============================================================================
951 //=============================================================================
952 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
954 Standard_Real Angle = angle ;
956 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
957 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
960 myCamStartOpUp = myCamera->Up();
961 myCamStartOpEye = myCamera->Eye();
962 myCamStartOpCenter = myCamera->Center();
965 myCamera->SetUp (myCamStartOpUp);
966 myCamera->SetEye (myCamStartOpEye);
967 myCamera->SetCenter (myCamStartOpCenter);
969 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
972 gp_Pnt aRCenter = myCamera->Eye();
973 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
974 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
975 myCamera->Transform (aRotation);
982 //=============================================================================
983 //function : SetTwist
985 //=============================================================================
986 void V3d_View::SetTwist(const Standard_Real angle)
988 Standard_Real Angle = angle ;
989 Standard_Boolean TheStatus;
991 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
992 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
994 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
997 anUp = gp_Dir (0.0, 0.0, 1.0);
999 TheStatus = ScreenAxis(aReferencePlane, anUp,
1000 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1002 anUp = gp_Dir (0.0, 1.0, 0.0);
1003 TheStatus = ScreenAxis(aReferencePlane, anUp,
1004 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1007 anUp = gp_Dir (1.0, 0.0, 0.0);
1008 TheStatus = ScreenAxis(aReferencePlane, anUp,
1009 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1012 V3d_BadValue_Raise_if( !TheStatus,"V3d_ViewSetTwist, alignment of Eye,At,Up,");
1014 gp_Pnt aRCenter = myCamera->Center();
1015 gp_Dir aZAxis (myCamera->Direction().Reversed());
1018 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
1020 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1021 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1023 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1024 myCamera->Transform (aTrsf);
1031 //=============================================================================
1034 //=============================================================================
1035 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1037 Standard_Real aTwistBefore = Twist();
1039 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1041 myCamera->SetEye (gp_Pnt (X, Y, Z));
1042 SetTwist (aTwistBefore);
1046 SetImmediateUpdate (wasUpdateEnabled);
1051 //=============================================================================
1052 //function : SetDepth
1054 //=============================================================================
1055 void V3d_View::SetDepth(const Standard_Real Depth)
1057 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1061 // Move eye using center (target) as anchor.
1062 myCamera->SetDistance (Depth);
1066 // Move the view ref point instead of the eye.
1067 gp_Vec aDir (myCamera->Direction());
1068 gp_Pnt aCameraEye = myCamera->Eye();
1069 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1071 myCamera->SetCenter (aCameraCenter);
1079 //=============================================================================
1080 //function : SetProj
1082 //=============================================================================
1083 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1085 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1086 "V3d_View::SetProj, null projection vector");
1088 Standard_Real aTwistBefore = Twist();
1090 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1092 myCamera->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1094 SetTwist(aTwistBefore);
1098 SetImmediateUpdate (wasUpdateEnabled);
1103 //=============================================================================
1104 //function : SetProj
1106 //=============================================================================
1107 void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1109 Standard_Real Xpn=0;
1110 Standard_Real Ypn=0;
1111 Standard_Real Zpn=0;
1113 switch (Orientation) {
1124 const Graphic3d_Vector& aBck = V3d::GetProjAxis (Orientation);
1126 // retain camera panning from origin when switching projection
1127 gp_Pnt anOriginVCS = myCamera->ConvertWorld2View (gp::Origin());
1128 Standard_Real aPanX = anOriginVCS.X();
1129 Standard_Real aPanY = anOriginVCS.Y();
1131 myCamera->SetCenter (gp_Pnt (0, 0, 0));
1132 myCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1133 myCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
1134 myCamera->OrthogonalizeUp();
1136 Panning (aPanX, aPanY);
1143 //=============================================================================
1146 //=============================================================================
1147 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1149 Standard_Real aTwistBefore = Twist();
1151 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1153 myCamera->SetCenter (gp_Pnt (X, Y, Z));
1155 SetTwist (aTwistBefore);
1159 SetImmediateUpdate (wasUpdateEnabled);
1164 //=============================================================================
1167 //=============================================================================
1168 void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standard_Real Vz)
1170 Standard_Boolean TheStatus ;
1171 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0. ,
1172 "V3d_View::SetUp, nullUp vector");
1174 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1175 gp_Dir anUp (Vx, Vy, Vz);
1177 TheStatus = ScreenAxis(aReferencePlane,anUp,
1178 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1180 anUp = gp_Dir (0.0, 0.0, 1.0);
1181 TheStatus = ScreenAxis(aReferencePlane,anUp,
1182 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1185 anUp = gp_Dir (0.0, 1.0, 0.0);
1186 TheStatus = ScreenAxis(aReferencePlane,anUp,
1187 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1190 anUp = gp_Dir (1.0, 0.0, 0.0);
1191 TheStatus = ScreenAxis(aReferencePlane,anUp,
1192 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1194 V3d_BadValue_Raise_if( !TheStatus,"V3d_View::Setup, alignment of Eye,At,Up");
1196 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1197 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1199 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1206 //=============================================================================
1209 //=============================================================================
1210 void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
1212 Standard_Boolean TheStatus ;
1214 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1217 const Graphic3d_Vector& aViewReferenceUp = V3d::GetProjAxis(Orientation) ;
1218 anUp = gp_Dir (aViewReferenceUp.X(), aViewReferenceUp.Y(), aViewReferenceUp.Z());
1220 TheStatus = ScreenAxis(aReferencePlane,anUp,
1221 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1223 anUp = gp_Dir (0.,0.,1.);
1224 TheStatus = ScreenAxis(aReferencePlane,anUp,
1225 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1228 anUp = gp_Dir (0.,1.,0.);
1229 TheStatus = ScreenAxis(aReferencePlane,anUp,
1230 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1233 anUp = gp_Dir (1.,0.,0.);
1234 TheStatus = ScreenAxis(aReferencePlane,anUp,
1235 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
1237 V3d_BadValue_Raise_if( !TheStatus, "V3d_View::SetUp, alignment of Eye,At,Up");
1239 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1240 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1242 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1249 //=============================================================================
1250 //function : SetViewOrientationDefault
1252 //=============================================================================
1253 void V3d_View::SetViewOrientationDefault()
1255 MyView->SetViewOrientationDefault() ;
1260 //=============================================================================
1261 //function : ResetViewOrientation
1263 //=============================================================================
1264 void V3d_View::ResetViewOrientation()
1266 MyView->ViewOrientationReset() ;
1271 //=============================================================================
1274 //=============================================================================
1275 void V3d_View::Reset( const Standard_Boolean update )
1277 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1279 if (!aDefaultCamera.IsNull())
1281 myCamera->CopyMappingData (aDefaultCamera);
1282 myCamera->CopyOrientationData (aDefaultCamera);
1287 SwitchSetFront = Standard_False;
1289 if( myImmediateUpdate || update ) Update();
1292 //=======================================================================
1293 //function : SetCenter
1295 //=======================================================================
1296 void V3d_View::SetCenter (const Standard_Integer theXp,
1297 const Standard_Integer theYp)
1299 Standard_Real aXv, aYv;
1300 Convert (theXp, theYp, aXv, aYv);
1301 Translate (myCamera, aXv, aYv);
1306 //=============================================================================
1307 //function : SetSize
1309 //=============================================================================
1310 void V3d_View::SetSize (const Standard_Real theSize)
1312 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1314 myCamera->SetScale (myCamera->Aspect() >= 1.0 ? theSize / myCamera->Aspect() : theSize);
1321 //=============================================================================
1322 //function : SetZSize
1324 //=============================================================================
1325 void V3d_View::SetZSize(const Standard_Real Size)
1327 Standard_Real Zmax = Size/2.;
1329 Standard_Real aDistance = myCamera->Distance();
1335 Standard_Real Front = MyViewContext.ZClippingFrontPlane();
1336 Standard_Real Back = MyViewContext.ZClippingBackPlane();
1338 // ShortReal precision factor used to add meaningful tolerance to
1339 // ZNear, ZFar values in order to avoid equality after type conversion
1340 // to ShortReal matrices type.
1341 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1343 Standard_Real aZFar = Zmax + aDistance * 2.0;
1344 Standard_Real aZNear = -Zmax + aDistance;
1345 aZNear -= Abs (aZNear) * aPrecision;
1346 aZFar += Abs (aZFar) * aPrecision;
1348 if (!myCamera->IsOrthographic())
1350 if (aZFar < aPrecision)
1352 // Invalid case when both values are negative
1353 aZNear = aPrecision;
1354 aZFar = aPrecision * 2.0;
1356 else if (aZNear < Abs (aZFar) * aPrecision)
1358 // Z is less than 0.0, try to fix it using any appropriate z-scale
1359 aZNear = Abs (aZFar) * aPrecision;
1363 // If range is too small
1364 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1366 aZFar = aZNear + Abs (aZFar) * aPrecision;
1369 myCamera->SetZRange (aZNear, aZFar);
1371 if (MyViewContext.FrontZClippingIsOn() ||
1372 MyViewContext.BackZClippingIsOn())
1374 MyViewContext.SetZClippingFrontPlane (Front);
1375 MyViewContext.SetZClippingBackPlane (Back);
1376 MyView->SetContext (MyViewContext);
1380 //=============================================================================
1381 //function : SetZoom
1383 //=============================================================================
1384 void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1386 V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
1390 myCamStartOpEye = myCamera->Eye();
1391 myCamStartOpCenter = myCamera->Center();
1394 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
1395 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
1397 // ensure that zoom will not be too small or too big
1398 Standard_Real coef = Coef;
1399 if (aViewWidth < coef * Precision::Confusion())
1401 coef = aViewWidth / Precision::Confusion();
1403 else if (aViewWidth > coef * 1e12)
1405 coef = aViewWidth / 1e12;
1407 if (aViewHeight < coef * Precision::Confusion())
1409 coef = aViewHeight / Precision::Confusion();
1411 else if (aViewHeight > coef * 1e12)
1413 coef = aViewHeight / 1e12;
1416 myCamera->SetEye (myCamStartOpEye);
1417 myCamera->SetCenter (myCamStartOpCenter);
1418 myCamera->SetScale (myCamera->Scale() / Coef);
1424 //=============================================================================
1425 //function : SetScale
1427 //=============================================================================
1428 void V3d_View::SetScale( const Standard_Real Coef )
1430 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1432 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1434 // Strange behavior for the sake of compatibility.
1435 if (!aDefaultCamera.IsNull())
1437 myCamera->SetAspect (aDefaultCamera->Aspect());
1438 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1439 myCamera->SetScale (aDefaultScale / Coef);
1443 myCamera->SetScale (myCamera->Scale() / Coef);
1451 //=============================================================================
1452 //function : SetAxialScale
1454 //=============================================================================
1455 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1457 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1459 myCamera->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1463 //=============================================================================
1466 //=============================================================================
1467 void V3d_View::FitAll (const Quantity_Coefficient theMargin, const Standard_Boolean theToUpdate)
1469 FitAll (MyView->MinMaxValues(), theMargin, theToUpdate);
1472 //=============================================================================
1475 //=============================================================================
1476 void V3d_View::FitAll (const Bnd_Box& theBox, const Quantity_Coefficient theMargin, const Standard_Boolean theToUpdate)
1478 Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1480 if (MyView->NumberOfDisplayedStructures() == 0)
1485 if (!FitMinMax (myCamera, theBox, theMargin, 10.0 * Precision::Confusion()))
1492 if (myImmediateUpdate || theToUpdate)
1498 //=============================================================================
1499 //function : DepthFitAll
1501 //=============================================================================
1502 void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1503 const Quantity_Coefficient Margin)
1505 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1506 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1507 Standard_Real Dx,Dy,Dz,Size;
1509 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1511 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1516 Bnd_Box aBox = MyView->MinMaxValues();
1522 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1523 MyView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
1524 MyView->Projects(Xmax,Ymax,Zmax,U1,V1,W1) ;
1525 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1526 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1527 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1528 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
1529 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1530 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1531 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1532 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
1533 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1534 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1535 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1536 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
1537 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1538 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1539 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1540 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
1541 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1542 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1543 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1544 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
1545 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1546 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1547 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1548 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
1549 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1550 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1551 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1554 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1555 Dz = 2.*Wmax + Margin * Wmax;
1557 // Compute depth value
1558 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1559 Dx += Margin * Dx; Dy += Margin * Dy;
1560 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1563 SetDepth( Aspect * Size / 2.);
1569 //=============================================================================
1572 //=============================================================================
1573 void V3d_View::FitAll(const Standard_Real theMinXv,
1574 const Standard_Real theMinYv,
1575 const Standard_Real theMaxXv,
1576 const Standard_Real theMaxYv)
1578 FitAll (MyWindow, theMinXv, theMinYv, theMaxXv, theMaxYv);
1581 //=============================================================================
1582 //function : WindowFitAll
1584 //=============================================================================
1585 void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1586 const Standard_Integer Ymin,
1587 const Standard_Integer Xmax,
1588 const Standard_Integer Ymax)
1590 WindowFit(Xmin,Ymin,Xmax,Ymax);
1593 //=======================================================================
1594 //function : WindowFit
1596 //=======================================================================
1597 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1598 const Standard_Integer theMinYp,
1599 const Standard_Integer theMaxXp,
1600 const Standard_Integer theMaxYp)
1602 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1604 if (!myCamera->IsOrthographic())
1606 // normalize view coordinates
1607 Standard_Integer aWinWidth, aWinHeight;
1608 MyWindow->Size (aWinWidth, aWinHeight);
1610 // z coordinate of camera center
1611 Standard_Real aDepth = myCamera->Project (myCamera->Center()).Z();
1613 // camera projection coordinate are in NDC which are normalized [-1, 1]
1614 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1615 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1616 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1617 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1619 // compute camera panning
1620 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1621 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1622 gp_Pnt aPanTo = myCamera->ConvertProj2View (aFitCenter);
1623 gp_Pnt aPanFrom = myCamera->ConvertProj2View (aScreenCenter);
1624 gp_Vec aPanVec (aPanFrom, aPanTo);
1626 // compute section size
1627 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1628 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1629 gp_Pnt aViewBotLeft = myCamera->ConvertProj2View (aFitBotLeft);
1630 gp_Pnt aViewTopRight = myCamera->ConvertProj2View (aFitTopRight);
1632 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1633 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1635 Translate (myCamera, aPanVec.X(), -aPanVec.Y());
1636 Scale (myCamera, aUSize, aVSize);
1641 Standard_Real aX1, aY1, aX2, aY2;
1642 Convert (theMinXp, theMinYp, aX1, aY1);
1643 Convert (theMaxXp, theMaxYp, aX2, aY2);
1644 FitAll (aX1, aY1, aX2, aY2);
1647 SetImmediateUpdate (wasUpdateEnabled);
1652 //=======================================================================
1653 //function : SetViewMappingDefault
1655 //=======================================================================
1656 void V3d_View::SetViewMappingDefault()
1658 MyView->SetViewMappingDefault();
1663 //=======================================================================
1664 //function : ResetViewMapping
1666 //=======================================================================
1667 void V3d_View::ResetViewMapping()
1669 MyView->ViewMappingReset();
1674 //=======================================================================
1675 //function : ConvertToGrid
1677 //=======================================================================
1678 void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1679 const Standard_Integer Yp,
1682 Standard_Real& Zg) const
1684 Graphic3d_Vertex aVrp;
1685 Standard_Real anX, anY, aZ;
1686 Convert (Xp, Yp, anX, anY, aZ);
1687 aVrp.SetCoord (anX, anY, aZ);
1689 if( MyViewer->Grid()->IsActive() ) {
1690 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1691 aNewVrp.Coord (Xg,Yg,Zg) ;
1693 aVrp.Coord (Xg,Yg,Zg) ;
1696 //=======================================================================
1697 //function : ConvertToGrid
1699 //=======================================================================
1700 void V3d_View::ConvertToGrid(const Standard_Real X,
1701 const Standard_Real Y,
1702 const Standard_Real Z,
1705 Standard_Real& Zg) const
1707 if( MyViewer->Grid()->IsActive() ) {
1708 Graphic3d_Vertex aVrp (X,Y,Z) ;
1709 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1710 aNewVrp.Coord(Xg,Yg,Zg) ;
1712 Xg = X; Yg = Y; Zg = Z;
1716 //=======================================================================
1717 //function : Convert
1719 //=======================================================================
1720 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1722 Standard_Integer aDxw, aDyw ;
1724 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1726 MyWindow->Size (aDxw, aDyw);
1727 Standard_Real aValue;
1729 gp_Pnt aViewDims = myCamera->ViewDimensions();
1730 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1735 //=======================================================================
1736 //function : Convert
1738 //=======================================================================
1739 void V3d_View::Convert(const Standard_Integer Xp,
1740 const Standard_Integer Yp,
1742 Standard_Real& Yv) const
1744 Standard_Integer aDxw, aDyw;
1746 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1748 MyWindow->Size (aDxw, aDyw);
1750 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1751 aPoint = myCamera->ConvertProj2View (aPoint);
1757 //=======================================================================
1758 //function : Convert
1760 //=======================================================================
1761 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1763 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1765 Standard_Integer aDxw, aDyw;
1766 MyWindow->Size (aDxw, aDyw);
1768 gp_Pnt aViewDims = myCamera->ViewDimensions();
1769 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1774 //=======================================================================
1775 //function : Convert
1777 //=======================================================================
1778 void V3d_View::Convert(const Standard_Real Xv,
1779 const Standard_Real Yv,
1780 Standard_Integer& Xp,
1781 Standard_Integer& Yp) const
1783 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1785 Standard_Integer aDxw, aDyw;
1786 MyWindow->Size (aDxw, aDyw);
1788 gp_Pnt aPoint (Xv, Yv, 0.0);
1789 aPoint = myCamera->ConvertView2Proj (aPoint);
1790 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1792 Xp = RealToInt (aPoint.X());
1793 Yp = RealToInt (aPoint.Y());
1796 //=======================================================================
1797 //function : Convert
1799 //=======================================================================
1800 void V3d_View::Convert(const Standard_Integer Xp,
1801 const Standard_Integer Yp,
1804 Standard_Real& Z) const
1806 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1807 Standard_Integer aHeight, aWidth;
1808 MyWindow->Size (aWidth, aHeight);
1810 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1811 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1812 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1814 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
1821 //=======================================================================
1822 //function : ConvertWithProj
1824 //=======================================================================
1825 void V3d_View::ConvertWithProj(const Standard_Integer Xp,
1826 const Standard_Integer Yp,
1832 Standard_Real& Dz) const
1834 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
1835 Standard_Integer aHeight, aWidth;
1836 MyWindow->Size (aWidth, aHeight);
1838 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
1839 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
1840 Standard_Real aZ = 2.0 * 0.0 - 1.0;
1842 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
1848 Graphic3d_Vertex aVrp;
1849 aVrp.SetCoord (X, Y, Z);
1851 aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1853 Graphic3d_Vec3d aNormDir;
1854 aNormDir.x() = X - aResult.X();
1855 aNormDir.y() = Y - aResult.Y();
1856 aNormDir.z() = Z - aResult.Z();
1857 aNormDir.Normalize();
1864 //=======================================================================
1865 //function : Convert
1867 //=======================================================================
1868 void V3d_View::Convert(const Standard_Real X,
1869 const Standard_Real Y,
1870 const Standard_Real Z,
1871 Standard_Integer& Xp,
1872 Standard_Integer& Yp) const
1874 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
1875 Standard_Integer aHeight, aWidth;
1876 MyWindow->Size (aWidth, aHeight);
1878 gp_Pnt aPoint = myCamera->Project (gp_Pnt (X, Y, Z));
1880 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1881 Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1884 //=======================================================================
1885 //function : Project
1887 //=======================================================================
1888 void V3d_View::Project(const Standard_Real X,
1889 const Standard_Real Y,
1890 const Standard_Real Z,
1892 Standard_Real &Yp) const
1895 MyView->Projects (X, Y, Z, Xp, Yp, Zp);
1898 //=======================================================================
1899 //function : BackgroundColor
1901 //=======================================================================
1902 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1905 Standard_Real& V3) const
1907 Quantity_Color C = BackgroundColor() ;
1908 C.Values(V1,V2,V3,Type) ;
1911 //=======================================================================
1912 //function : BackgroundColor
1914 //=======================================================================
1915 Quantity_Color V3d_View::BackgroundColor() const
1917 return MyBackground.Color() ;
1920 //=======================================================================
1921 //function : GradientBackgroundColors
1923 //=======================================================================
1924 void V3d_View::GradientBackgroundColors(Quantity_Color& Color1,Quantity_Color& Color2) const
1926 MyGradientBackground.Colors(Color1, Color2);
1929 //=======================================================================
1930 //function : GradientBackground
1932 //=======================================================================
1933 Aspect_GradientBackground V3d_View::GradientBackground() const
1935 return MyGradientBackground;
1938 //=======================================================================
1941 //=======================================================================
1942 Standard_Real V3d_View::Scale() const
1944 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1946 Standard_Real aCameraScale;
1948 // Strange behavior for the sake of compatibility.
1949 if (!aDefaultCamera.IsNull())
1951 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1952 aCameraScale = aDefaultScale / myCamera->Scale();
1956 aCameraScale = myCamera->Scale();
1959 return aCameraScale;
1962 //=======================================================================
1963 //function : AxialScale
1965 //=======================================================================
1966 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1968 gp_Pnt anAxialScale = myCamera->AxialScale();
1969 Sx = anAxialScale.X();
1970 Sy = anAxialScale.Y();
1971 Sz = anAxialScale.Z();
1974 //=======================================================================
1977 //=======================================================================
1978 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1980 gp_Pnt aViewDims = myCamera->ViewDimensions();
1982 Width = aViewDims.X();
1983 Height = aViewDims.Y();
1986 //=======================================================================
1989 //=======================================================================
1990 Standard_Real V3d_View::ZSize() const
1992 gp_Pnt aViewDims = myCamera->ViewDimensions();
1994 return aViewDims.Z();
1997 //=======================================================================
2000 //=======================================================================
2001 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
2002 Standard_Real& Vmin,
2003 Standard_Real& Umax,
2004 Standard_Real& Vmax) const
2006 Standard_Real Wmin,Wmax,U,V,W ;
2007 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
2009 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2012 Bnd_Box aBox = MyView->MinMaxValues();
2013 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2014 MyView->Projects(Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
2015 MyView->Projects(Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
2016 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
2017 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2018 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2019 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2020 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
2021 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2022 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2023 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2024 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
2025 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2026 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2027 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2028 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
2029 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2030 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2031 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2032 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
2033 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2034 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2035 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2036 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
2037 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2038 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2039 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2044 //=======================================================================
2047 //=======================================================================
2048 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
2049 Standard_Real& Ymin,
2050 Standard_Real& Zmin,
2051 Standard_Real& Xmax,
2052 Standard_Real& Ymax,
2053 Standard_Real& Zmax) const
2056 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
2057 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2060 Bnd_Box aBox = MyView->MinMaxValues();
2061 aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
2066 //=======================================================================
2067 //function : Gravity
2069 //=======================================================================
2070 void V3d_View::Gravity (Standard_Real& theX,
2071 Standard_Real& theY,
2072 Standard_Real& theZ) const
2074 Graphic3d_MapOfStructure aSetOfStructures;
2075 MyView->DisplayedStructures (aSetOfStructures);
2077 Standard_Boolean hasSelection = Standard_False;
2078 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2079 aStructIter.More(); aStructIter.Next())
2081 if (aStructIter.Key()->IsHighlighted()
2082 && aStructIter.Key()->IsVisible())
2084 hasSelection = Standard_True;
2089 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
2090 Standard_Integer aNbPoints = 0;
2091 gp_XYZ aResult (0.0, 0.0, 0.0);
2092 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2093 aStructIter.More(); aStructIter.Next())
2095 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2096 if (!aStruct->IsVisible()
2097 || (hasSelection && !aStruct->IsHighlighted())
2098 || aStruct->IsEmpty())
2103 Bnd_Box aBox = aStruct->MinMaxValues();
2104 if (aBox.IsVoid() || aStruct->IsInfinite())
2109 // use camera projection to find gravity point
2110 aBox.Get (Xmin, Ymin, Zmin,
2112 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2114 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2115 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2116 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2117 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2120 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2122 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2123 const gp_Pnt aProjected = myCamera->Project (aBndPnt);
2124 if (Abs (aProjected.X()) <= 1.0
2125 && Abs (aProjected.Y()) <= 1.0)
2127 aResult += aBndPnt.XYZ();
2135 for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
2136 aStructIter.More(); aStructIter.Next())
2138 const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2139 if (aStruct->IsEmpty())
2144 Bnd_Box aBox = aStruct->MinMaxValues();
2145 if (aBox.IsVoid() || aStruct->IsInfinite())
2150 aBox.Get (Xmin, Ymin, Zmin,
2152 gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2154 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2155 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2156 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2157 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2160 for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2162 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2163 aResult += aBndPnt.XYZ();
2171 aResult /= aNbPoints;
2178 //=======================================================================
2181 //=======================================================================
2182 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2184 gp_Pnt aCameraEye = myCamera->Eye();
2190 //=============================================================================
2191 //function : FocalReferencePoint
2193 //=============================================================================
2194 void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2199 //=============================================================================
2200 //function : ProjReferenceAxe
2202 //=============================================================================
2203 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2204 const Standard_Integer Ypix,
2210 Standard_Real& VZ) const
2212 Standard_Real Xo,Yo,Zo;
2214 Convert (Xpix, Ypix, XP, YP, ZP);
2215 if ( Type() == V3d_PERSPECTIVE )
2217 FocalReferencePoint (Xo,Yo,Zo);
2228 //=============================================================================
2231 //=============================================================================
2232 Standard_Real V3d_View::Depth() const
2234 return myCamera->Distance();
2237 //=============================================================================
2240 //=============================================================================
2241 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2243 gp_Dir aCameraDir = myCamera->Direction().Reversed();
2244 Dx = aCameraDir.X();
2245 Dy = aCameraDir.Y();
2246 Dz = aCameraDir.Z();
2249 //=============================================================================
2252 //=============================================================================
2253 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2255 gp_Pnt aCameraCenter = myCamera->Center();
2256 X = aCameraCenter.X();
2257 Y = aCameraCenter.Y();
2258 Z = aCameraCenter.Z();
2261 //=============================================================================
2264 //=============================================================================
2265 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2267 gp_Dir aCameraUp = myCamera->Up();
2273 //=============================================================================
2276 //=============================================================================
2277 Standard_Real V3d_View::Twist() const
2279 Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2280 Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
2281 Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
2282 Standard_Boolean TheStatus ;
2284 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
2288 anUp = gp_Dir (0.,0.,1.) ;
2289 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2291 anUp = gp_Dir (0.,1.,0.) ;
2292 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2295 anUp = gp_Dir (1.,0.,0.) ;
2296 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
2298 Yaxis.Coord(X0,Y0,Z0) ;
2301 /* Compute Cross Vector From Up & Origin */
2302 pvx = Y0*Zup - Z0*Yup ;
2303 pvy = Z0*Xup - X0*Zup ;
2304 pvz = X0*Yup - Y0*Xup ;
2305 pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2306 sca = X0*Xup + Y0*Yup + Z0*Zup ;
2309 if( angle > 1. ) angle = 1. ;
2310 else if( angle < -1. ) angle = -1. ;
2311 angle = asin(angle) ;
2312 if( sca < 0. ) angle = M_PI - angle ;
2313 if( angle > 0. && angle < M_PI ) {
2314 sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2315 if( sca < 0. ) angle = DEUXPI - angle ;
2320 //=============================================================================
2321 //function : ShadingModel
2323 //=============================================================================
2324 V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2326 V3d_TypeOfShadingModel SM = (V3d_TypeOfShadingModel)MyViewContext.Model() ;
2330 //=============================================================================
2331 //function : SurfaceDetail
2333 //=============================================================================
2334 V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
2336 V3d_TypeOfSurfaceDetail SM = (V3d_TypeOfSurfaceDetail)MyViewContext.SurfaceDetail() ;
2340 //=============================================================================
2341 //function : TextureEnv
2343 //=============================================================================
2344 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2346 Handle(Graphic3d_TextureEnv) SM = MyViewContext.TextureEnv() ;
2350 //=============================================================================
2351 //function : Visualization
2353 //=============================================================================
2354 V3d_TypeOfVisualization V3d_View::Visualization() const
2356 V3d_TypeOfVisualization V =
2357 (V3d_TypeOfVisualization)MyViewContext.Visualization() ;
2361 //=============================================================================
2362 //function : Antialiasing
2364 //=============================================================================
2365 Standard_Boolean V3d_View::Antialiasing() const
2367 Standard_Boolean A = MyViewContext.AliasingIsOn() ;
2371 //=============================================================================
2374 //=============================================================================
2375 Handle(V3d_Viewer) V3d_View::Viewer() const
2380 //=============================================================================
2381 //function : IfWindow
2383 //=============================================================================
2384 Standard_Boolean V3d_View::IfWindow() const
2386 Standard_Boolean TheStatus = MyView->IsDefined() ;
2390 //=============================================================================
2393 //=============================================================================
2394 Handle(Aspect_Window) V3d_View::Window() const
2399 //=============================================================================
2402 //=============================================================================
2403 V3d_TypeOfView V3d_View::Type() const
2405 return myCamera->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2408 //=============================================================================
2409 //function : SetFocale
2411 //=============================================================================
2412 void V3d_View::SetFocale( const Standard_Real focale )
2414 if (myCamera->IsOrthographic())
2419 Standard_Real aFOVyRad = ATan (focale / (myCamera->Distance() * 2.0));
2421 myCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2426 //=============================================================================
2429 //=============================================================================
2430 Standard_Real V3d_View::Focale() const
2432 if (myCamera->IsOrthographic())
2437 return myCamera->Distance() * 2.0 * Tan(myCamera->FOVy() * M_PI / 360.0);
2440 //=============================================================================
2443 //=============================================================================
2444 Handle(Visual3d_View) V3d_View::View() const
2449 //=============================================================================
2450 //function : ScreenAxis
2452 //=============================================================================
2453 Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2455 Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2456 Standard_Real dx1, dy1, dz1, xx, yy, zz;
2458 Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2459 Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2460 xx = Yup*Zpn - Zup*Ypn;
2461 yy = Zup*Xpn - Xup*Zpn;
2462 zz = Xup*Ypn - Yup*Xpn;
2463 Xaxe.SetCoord (xx, yy, zz);
2464 if (Xaxe.LengthZero()) return Standard_False;
2466 Xaxe.Coord(dx1, dy1, dz1);
2467 xx = Ypn*dz1 - Zpn*dy1;
2468 yy = Zpn*dx1 - Xpn*dz1;
2469 zz = Xpn*dy1 - Ypn*dx1;
2470 Yaxe.SetCoord (xx, yy, zz) ;
2471 if (Yaxe.LengthZero()) return Standard_False;
2474 Zaxe.SetCoord (Xpn, Ypn, Zpn);
2476 return Standard_True;
2479 //=============================================================================
2480 //function : TrsPoint
2482 //=============================================================================
2483 Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2485 Graphic3d_Vertex PP ;
2486 Standard_Real X,Y,Z,XX,YY,ZZ ;
2489 Standard_Integer lr, ur, lc, uc;
2490 lr = Matrix.LowerRow ();
2491 ur = Matrix.UpperRow ();
2492 lc = Matrix.LowerCol ();
2493 uc = Matrix.UpperCol ();
2494 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
2496 PP.SetCoord(X,Y,Z) ;
2500 XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2501 Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2503 YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2504 Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2506 ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2507 Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2508 PP.SetCoord(XX,YY,ZZ) ;
2512 //=======================================================================
2515 //=======================================================================
2516 void V3d_View::Pan (const Standard_Integer theDXp,
2517 const Standard_Integer theDYp,
2518 const Quantity_Factor theZoomFactor,
2519 const Standard_Boolean theToStart)
2521 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2524 //=======================================================================
2525 //function : Panning
2527 //=======================================================================
2528 void V3d_View::Panning (const Standard_Real theDXv,
2529 const Standard_Real theDYv,
2530 const Quantity_Factor theZoomFactor,
2531 const Standard_Boolean theToStart)
2533 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2537 myCamStartOpEye = myCamera->Eye();
2538 myCamStartOpCenter = myCamera->Center();
2541 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2543 gp_Pnt aViewDims = myCamera->ViewDimensions();
2545 myCamera->SetEye (myCamStartOpEye);
2546 myCamera->SetCenter (myCamStartOpCenter);
2547 Translate (myCamera, -theDXv, -theDYv);
2548 Scale (myCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2550 SetImmediateUpdate (wasUpdateEnabled);
2555 //=======================================================================
2558 //=======================================================================
2559 void V3d_View::Zoom (const Standard_Integer theXp1,
2560 const Standard_Integer theYp1,
2561 const Standard_Integer theXp2,
2562 const Standard_Integer theYp2)
2564 Standard_Integer aDx = theXp2 - theXp1;
2565 Standard_Integer aDy = theYp2 - theYp1;
2566 if (aDx != 0 || aDy != 0)
2568 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2569 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2570 SetZoom (aCoeff, Standard_True);
2574 //=======================================================================
2575 //function : StartZoomAtPoint
2577 //=======================================================================
2578 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2579 const Standard_Integer theYp)
2581 MyZoomAtPointX = theXp;
2582 MyZoomAtPointY = theYp;
2585 //=======================================================================
2586 //function : ZoomAtPoint
2588 //=======================================================================
2589 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2590 const Standard_Integer theMouseStartY,
2591 const Standard_Integer theMouseEndX,
2592 const Standard_Integer theMouseEndY)
2594 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2597 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2598 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2599 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
2601 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2603 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
2604 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
2606 // ensure that zoom will not be too small or too big.
2607 Standard_Real aCoef = aDZoom;
2608 if (aViewWidth < aCoef * Precision::Confusion())
2610 aCoef = aViewWidth / Precision::Confusion();
2612 else if (aViewWidth > aCoef * 1e12)
2614 aCoef = aViewWidth / 1e12;
2616 if (aViewHeight < aCoef * Precision::Confusion())
2618 aCoef = aViewHeight / Precision::Confusion();
2620 else if (aViewHeight > aCoef * 1e12)
2622 aCoef = aViewHeight / 1e12;
2625 Standard_Real aZoomAtPointXv = 0.0;
2626 Standard_Real aZoomAtPointYv = 0.0;
2627 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2629 V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
2630 V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
2632 myCamera->SetScale (myCamera->Scale() / aCoef);
2633 Translate (myCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2637 SetImmediateUpdate (wasUpdateEnabled);
2642 //=============================================================================
2643 //function : AxialScale
2645 //=============================================================================
2646 void V3d_View::AxialScale (const Standard_Integer Dx,
2647 const Standard_Integer Dy,
2648 const V3d_TypeOfAxe Axis)
2650 if( Dx != 0. || Dy != 0. ) {
2651 Standard_Real Sx, Sy, Sz;
2652 AxialScale( Sx, Sy, Sz );
2653 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2654 dscale = (Dx > 0) ? dscale : 1./dscale;
2655 if( Axis == V3d_X ) Sx = dscale;
2656 if( Axis == V3d_Y ) Sy = dscale;
2657 if( Axis == V3d_Z ) Sz = dscale;
2658 SetAxialScale( Sx, Sy, Sz );
2662 //=============================================================================
2665 //=============================================================================
2666 void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
2667 const Standard_Real Xmin,
2668 const Standard_Real Ymin,
2669 const Standard_Real Xmax,
2670 const Standard_Real Ymax)
2672 Standard_Integer aWinWidth, aWinHeight;
2673 aWindow->Size (aWinWidth, aWinHeight);
2675 Standard_Real aWinAspect = (Standard_Real)aWinWidth / aWinHeight;
2676 Standard_Real aFitSizeU = Abs (Xmax - Xmin);
2677 Standard_Real aFitSizeV = Abs (Ymax - Ymin);
2678 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2679 if (aFitAspect >= aWinAspect)
2681 aFitSizeV = aFitSizeU / aWinAspect;
2685 aFitSizeU = aFitSizeV * aWinAspect;
2688 myCamera->SetAspect (aWinAspect);
2689 Translate (myCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
2690 Scale (myCamera, aFitSizeU, aFitSizeV);
2696 //=============================================================================
2697 //function : StartRotation
2699 //=============================================================================
2700 static Standard_Boolean zRotation = Standard_False;
2701 void V3d_View::StartRotation(const Standard_Integer X,
2702 const Standard_Integer Y,
2703 const Quantity_Ratio zRotationThreshold)
2708 rx = Standard_Real(Convert(x));
2709 ry = Standard_Real(Convert(y));
2711 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2712 zRotation = Standard_False;
2713 if( zRotationThreshold > 0. ) {
2714 Standard_Real dx = Abs(sx - rx/2.);
2715 Standard_Real dy = Abs(sy - ry/2.);
2716 // if( dx > rx/3. || dy > ry/3. ) zRotation = Standard_True;
2717 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2718 if( dx > dd || dy > dd ) zRotation = Standard_True;
2723 //=============================================================================
2724 //function : Rotation
2726 //=============================================================================
2727 void V3d_View::Rotation(const Standard_Integer X,
2728 const Standard_Integer Y)
2730 if( rx == 0. || ry == 0. ) {
2734 Standard_Real dx=0.,dy=0.,dz=0.;
2736 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2737 atan2(sx-rx/2.,ry/2.-sy);
2739 dx = (Standard_Real(X) - sx) * M_PI / rx;
2740 dy = (sy - Standard_Real(Y)) * M_PI / ry;
2743 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2746 //=============================================================================
2747 //function : SetComputedMode
2749 //=============================================================================
2750 void V3d_View::SetComputedMode (const Standard_Boolean aMode)
2756 MyView->SetComputedMode (Standard_True);
2762 MyView->SetComputedMode (Standard_False);
2767 //=============================================================================
2768 //function : ComputedMode
2770 //=============================================================================
2771 Standard_Boolean V3d_View::ComputedMode() const
2773 return MyView->ComputedMode();
2776 //=============================================================================
2777 //function : SetBackFacingModel
2779 //=============================================================================
2780 void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel aModel)
2782 MyView->SetBackFacingModel (Visual3d_TypeOfBackfacingModel(aModel));
2786 //=============================================================================
2787 //function : BackFacingModel
2789 //=============================================================================
2790 V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2792 return V3d_TypeOfBackfacingModel(MyView -> BackFacingModel ());
2795 void V3d_View::Init()
2797 myComputedMode = MyViewer->ComputedMode();
2798 if( !myComputedMode || !MyViewer->DefaultComputedMode() ) {
2799 SetComputedMode(Standard_False);
2803 //=============================================================================
2806 //=============================================================================
2807 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
2808 const Graphic3d_BufferType& theBufferType)
2810 Standard_Integer aWinWidth, aWinHeight;
2811 MyWindow->Size (aWinWidth, aWinHeight);
2812 Image_AlienPixMap anImage;
2814 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2817 //=============================================================================
2818 //function : ToPixMap
2820 //=============================================================================
2821 Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
2822 const Standard_Integer theWidth,
2823 const Standard_Integer theHeight,
2824 const Graphic3d_BufferType& theBufferType,
2825 const Standard_Boolean theToKeepAspect,
2826 const V3d_StereoDumpOptions theStereoOptions)
2828 Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
2830 // always prefer hardware accelerated offscreen buffer
2831 Graphic3d_PtrFrameBuffer aFBOPtr = NULL;
2832 Graphic3d_PtrFrameBuffer aPrevFBOPtr = (Graphic3d_PtrFrameBuffer )cView->ptrFBO;
2833 Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
2834 Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
2835 if (aPrevFBOPtr != NULL)
2837 MyView->FBOGetDimensions (aPrevFBOPtr,
2838 aPrevFBOVPSizeX, aPrevFBOVPSizeY,
2839 aPrevFBOSizeXMax, aPrevFBOSizeYMax);
2840 if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
2842 MyView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
2843 aFBOPtr = aPrevFBOPtr;
2847 if (aFBOPtr == NULL)
2849 // Try to create hardware accelerated buffer
2850 aFBOPtr = MyView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
2851 if (aFBOPtr != NULL)
2853 MyView->FBOGetDimensions (aFBOPtr,
2854 aFBOVPSizeX, aFBOVPSizeY,
2855 aFBOSizeXMax, aFBOSizeYMax);
2856 // reduce viewport in case of hardware limits
2857 if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
2858 if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
2859 MyView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
2862 cView->ptrFBO = aFBOPtr;
2864 // If hardware accelerated buffer - try to use onscreen buffer
2865 // Results may be bad!
2866 if (aFBOPtr == NULL)
2868 // retrieve window sizes
2869 Standard_Integer aWinWidth, aWinHeight;
2870 MyWindow->Size (aWinWidth, aWinHeight);
2872 // technically we can reduce existing viewport...
2873 // but currently allow only dumping the window itself
2874 if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
2876 return Standard_False;
2880 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2882 aStoreMapping->Copy (myCamera);
2884 if (myCamera->IsStereo())
2886 switch (theStereoOptions)
2890 myCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2893 case V3d_SDO_LEFT_EYE:
2895 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2898 case V3d_SDO_RIGHT_EYE:
2900 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2903 case V3d_SDO_BLENDED:
2905 break; // dump as is
2910 // render immediate structures into back buffer rather than front
2911 Handle(Graphic3d_GraphicDriver) aDriver = Handle(Graphic3d_GraphicDriver)::DownCast (MyView->GraphicDriver());
2912 const Standard_Boolean aPrevImmediateMode = aDriver.IsNull() ? Standard_True : aDriver->SetImmediateModeDrawToFront (*cView, Standard_False);
2914 const Standard_Boolean toAutoUpdate = myImmediateUpdate;
2915 myImmediateUpdate = Standard_False;
2917 myImmediateUpdate = toAutoUpdate;
2919 if (theToKeepAspect)
2921 myCamera->SetAspect ((Standard_Real) aFBOVPSizeX / aFBOVPSizeY);
2924 //workaround for rendering list of Over and Under Layers
2925 if (!MyLayerMgr.IsNull())
2927 MyLayerMgr->Compute();
2932 if (!aDriver.IsNull())
2934 aDriver->SetImmediateModeDrawToFront (*cView, aPrevImmediateMode);
2937 myCamera->Copy (aStoreMapping);
2939 Standard_Boolean isSuccess = Standard_True;
2941 // allocate image buffer for dumping
2942 if (theImage.IsEmpty()
2943 || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
2944 || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
2946 bool isBigEndian = Image_PixMap::IsBigEndianHost();
2947 Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
2948 switch (theBufferType)
2950 case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
2951 case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
2952 case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
2955 isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
2957 isSuccess = isSuccess && MyView->BufferDump (theImage, theBufferType);
2959 // FBO now useless, free resources
2960 if (aFBOPtr != aPrevFBOPtr)
2962 MyView->FBORelease (aFBOPtr);
2964 else if (aPrevFBOPtr != NULL)
2966 MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
2968 cView->ptrFBO = aPrevFBOPtr;
2972 void V3d_View::ImmediateUpdate() const
2974 if (myImmediateUpdate) Update();
2977 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2979 Standard_Boolean aPreviousMode = myImmediateUpdate;
2980 myImmediateUpdate = theImmediateUpdate;
2981 return aPreviousMode;
2984 // =======================================================================
2985 // function : SetCamera
2987 // =======================================================================
2988 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2990 Standard_ASSERT_RAISE (!theCamera.IsNull(), "Void camera is not allowed");
2992 myCamera = theCamera;
2994 MyView->SetCamera (theCamera);
2997 // =======================================================================
2998 // function : GetCamera
3000 // =======================================================================
3001 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
3006 // =======================================================================
3007 // function : FitMinMax
3008 // purpose : Internal
3009 // =======================================================================
3010 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
3011 const Bnd_Box& theBox,
3012 const Standard_Real theMargin,
3013 const Standard_Real theResolution,
3014 const Standard_Boolean theToEnlargeIfLine) const
3016 // Check bounding box for validness
3017 if (theBox.IsVoid())
3019 return Standard_False; // bounding box is out of bounds...
3022 // Apply "axial scaling" to the bounding points.
3023 // It is not the best approach to make this scaling as a part of fit all operation,
3024 // but the axial scale is integrated into camera orientation matrix and the other
3025 // option is to perform frustum plane adjustment algorithm in view camera space,
3026 // which will lead to a number of additional world-view space conversions and
3027 // loosing precision as well.
3028 gp_Pnt aBndMin = theBox.CornerMin().XYZ().Multiplied (theCamera->AxialScale());
3029 gp_Pnt aBndMax = theBox.CornerMax().XYZ().Multiplied (theCamera->AxialScale());
3031 if (aBndMax.IsEqual (aBndMin, RealEpsilon()))
3033 return Standard_False; // nothing to fit all
3036 // Prepare camera frustum planes.
3037 NCollection_Array1<gp_Pln> aFrustumPlane (1, 6);
3038 theCamera->Frustum (aFrustumPlane.ChangeValue (1),
3039 aFrustumPlane.ChangeValue (2),
3040 aFrustumPlane.ChangeValue (3),
3041 aFrustumPlane.ChangeValue (4),
3042 aFrustumPlane.ChangeValue (5),
3043 aFrustumPlane.ChangeValue (6));
3045 // Prepare camera up, side, direction vectors.
3046 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3047 gp_Dir aCamDir = theCamera->Direction();
3048 gp_Dir aCamSide = aCamDir ^ aCamUp;
3050 // Prepare scene bounding box parameters.
3051 gp_Pnt aBndCenter = (aBndMin.XYZ() + aBndMax.XYZ()) / 2.0;
3053 NCollection_Array1<gp_Pnt> aBndCorner (1, 8);
3054 aBndCorner.ChangeValue (1) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMin.Z());
3055 aBndCorner.ChangeValue (2) = gp_Pnt (aBndMin.X(), aBndMin.Y(), aBndMax.Z());
3056 aBndCorner.ChangeValue (3) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMin.Z());
3057 aBndCorner.ChangeValue (4) = gp_Pnt (aBndMin.X(), aBndMax.Y(), aBndMax.Z());
3058 aBndCorner.ChangeValue (5) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMin.Z());
3059 aBndCorner.ChangeValue (6) = gp_Pnt (aBndMax.X(), aBndMin.Y(), aBndMax.Z());
3060 aBndCorner.ChangeValue (7) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMin.Z());
3061 aBndCorner.ChangeValue (8) = gp_Pnt (aBndMax.X(), aBndMax.Y(), aBndMax.Z());
3063 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3064 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3065 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3066 // set up perspective-correct camera projection matching the bounding box.
3067 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3068 // The zooming can be done by calculating view plane size matching the bounding box at center of
3069 // the bounding box. The only limitation here is that the scale of camera should define size of
3070 // its view plane passing through the camera center, and the center of camera should be on the
3071 // same line with the center of bounding box.
3073 // The following method is applied:
3074 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3075 // 2) Determine new location of frustum planes, "matching" the bounding box.
3076 // 3) Determine new camera projection vector using the normalized asymmetry.
3077 // 4) Determine new zooming in view space.
3079 // 1. Determine normalized projection asymmetry (if any).
3080 Standard_Real anAssymX = Tan ( aCamSide.Angle (aFrustumPlane (1).Axis().Direction()))
3081 - Tan (-aCamSide.Angle (aFrustumPlane (2).Axis().Direction()));
3082 Standard_Real anAssymY = Tan ( aCamUp.Angle (aFrustumPlane (3).Axis().Direction()))
3083 - Tan (-aCamUp.Angle (aFrustumPlane (4).Axis().Direction()));
3085 // 2. Determine how far should be the frustum planes placed from center
3086 // of bounding box, in order to match the bounding box closely.
3087 NCollection_Array1<Standard_Real> aFitDistance (1, 6);
3088 aFitDistance.ChangeValue (1) = 0.0;
3089 aFitDistance.ChangeValue (2) = 0.0;
3090 aFitDistance.ChangeValue (3) = 0.0;
3091 aFitDistance.ChangeValue (4) = 0.0;
3092 aFitDistance.ChangeValue (5) = 0.0;
3093 aFitDistance.ChangeValue (6) = 0.0;
3095 for (Standard_Integer anI = aFrustumPlane.Lower(); anI <= aFrustumPlane.Upper(); ++anI)
3097 // Measure distances from center of bounding box to its corners towards the frustum plane.
3098 const gp_Dir& aPlaneN = aFrustumPlane.ChangeValue (anI).Axis().Direction();
3100 Standard_Real& aFitDist = aFitDistance.ChangeValue (anI);
3102 for (Standard_Integer aJ = aBndCorner.Lower(); aJ <= aBndCorner.Upper(); ++aJ)
3104 aFitDist = Max (aFitDist, gp_Vec (aBndCenter, aBndCorner (aJ)).Dot (aPlaneN));
3107 // The center of camera is placed on the same line with center of bounding box.
3108 // The view plane section crosses the bounding box at its center.
3109 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3110 // into view section size between the point and the frustum plane.
3112 // /|\ right half of frame //
3114 // point o<-- distance * coeff -->//---- (view plane section)
3123 aFitDistance.ChangeValue (1) *= Sqrt(1 + Pow (Tan ( aCamSide.Angle (aFrustumPlane (1).Axis().Direction())), 2.0));
3124 aFitDistance.ChangeValue (2) *= Sqrt(1 + Pow (Tan (-aCamSide.Angle (aFrustumPlane (2).Axis().Direction())), 2.0));
3125 aFitDistance.ChangeValue (3) *= Sqrt(1 + Pow (Tan ( aCamUp.Angle (aFrustumPlane (3).Axis().Direction())), 2.0));
3126 aFitDistance.ChangeValue (4) *= Sqrt(1 + Pow (Tan (-aCamUp.Angle (aFrustumPlane (4).Axis().Direction())), 2.0));
3127 aFitDistance.ChangeValue (5) *= Sqrt(1 + Pow (Tan ( aCamDir.Angle (aFrustumPlane (5).Axis().Direction())), 2.0));
3128 aFitDistance.ChangeValue (6) *= Sqrt(1 + Pow (Tan (-aCamDir.Angle (aFrustumPlane (6).Axis().Direction())), 2.0));
3130 Standard_Real aViewSizeXv = aFitDistance (1) + aFitDistance (2);
3131 Standard_Real aViewSizeYv = aFitDistance (3) + aFitDistance (4);
3132 Standard_Real aViewSizeZv = aFitDistance (5) + aFitDistance (6);
3134 // 3. Place center of camera on the same line with center of bounding
3135 // box applying corresponding projection asymmetry (if any).
3136 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3137 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3138 Standard_Real anOffsetXv = (aFitDistance (2) - aFitDistance (1)) * 0.5 + anAssymXv;
3139 Standard_Real anOffsetYv = (aFitDistance (4) - aFitDistance (3)) * 0.5 + anAssymYv;
3140 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3141 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3142 gp_Pnt aCamNewCenter = aBndCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3144 gp_Trsf aCenterTrsf;
3145 aCenterTrsf.SetTranslation (theCamera->Center(), aCamNewCenter);
3146 theCamera->Transform (aCenterTrsf);
3147 theCamera->SetDistance (aFitDistance (6) + aFitDistance (5));
3149 // Bounding box collapses to a point or thin line going in depth of the screen
3150 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
3152 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3154 return Standard_True; // This is just one point or line and zooming has no effect.
3157 // Looking along line and "theToEnlargeIfLine" is requested.
3158 // Fit view to see whole scene on rotation.
3159 aViewSizeXv = aViewSizeZv;
3160 aViewSizeYv = aViewSizeZv;
3163 Scale (theCamera, aViewSizeXv * (1.0 + theMargin), aViewSizeYv * (1.0 + theMargin));
3165 return Standard_True;
3168 // =======================================================================
3170 // purpose : Internal
3171 // =======================================================================
3172 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3173 const Standard_Real theSizeXv,
3174 const Standard_Real theSizeYv) const
3176 Standard_Real anAspect = theCamera->Aspect();
3179 theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
3183 theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
3187 // =======================================================================
3188 // function : Translate
3189 // purpose : Internal
3190 // =======================================================================
3191 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3192 const Standard_Real theDXv,
3193 const Standard_Real theDYv) const
3195 const gp_Pnt& aCenter = theCamera->Center();
3196 const gp_Dir& aDir = theCamera->Direction();
3197 const gp_Dir& anUp = theCamera->Up();
3198 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3200 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3201 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3202 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3204 aPanTrsf.SetTranslation (aCameraPan);
3206 theCamera->Transform (aPanTrsf);
3209 // =======================================================================
3210 // function : IsCullingEnabled
3212 // =======================================================================
3213 Standard_Boolean V3d_View::IsCullingEnabled() const
3215 Graphic3d_CView* aView = (Graphic3d_CView* )MyView->CView();
3216 return aView->IsCullingEnabled;
3219 // =======================================================================
3220 // function : SetFrustumCulling
3222 // =======================================================================
3223 void V3d_View::SetFrustumCulling (const Standard_Boolean theToClip)
3225 Graphic3d_CView* aView = (Graphic3d_CView* )MyView->CView();
3226 aView->IsCullingEnabled = theToClip;