0024714: Camera integration - difference in behavior of V3d_View::SetSize
[occt.git] / src / V3d / V3d_View.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 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
973c2be1 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.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
7fd59977 14/***********************************************************************
15
16FONCTION :
17----------
18Classe V3d_View :
19
20HISTORIQUE DES MODIFICATIONS :
21--------------------------------
2200-09-92 : GG ; Creation.
2302-10-96 : FMN ; Suppression appel Redraw sans MustBeResized()
2405-06-97 : FMN ; Correction FitAll()
2530-06-97 : GG ; Correction + Optimisation de Panning(...)
26On fait la translation + le zoom en une seule
27operation au lieu de 2 precedemment qui etait buggee.
2809-07-97 : FMN ; Correction FitAll() sur le Ratio
2916-07-97 : FMN ; Correction FitAll() sur le calcul de la Box
3022-07-97 : FMN ; Ajout mode RetainMode pour le Transient
3115-12-97 : FMN ; Ajout texture mapping
3217-12-97 : FMN ; CTS19129 Correction FitAll() multiple
3318-12-97 : FMN ; Ajout mode Ajout
3424-12-97 : FMN ; Remplacement de math par MathGra
3524-12-97 : CQO ; BUC50037 Xw_Window -> Aspect_Window
3631-12-97 : CAL ; Remplacement de MathGra par Array2OfReal
3707-01-98 : CAL ; Ajout de la methode DoMapping.
3807-01-98 : CAL ; Retrait de tous les "this->" inutiles
3921-01-98 : CAL ; Remplacement des Window->Position () par Window->Size ()
4027-01-98 : FMN ; PERF: OPTIMISATION LOADER (LOPTIM)
4112-02-98 : GG ; Reactivation du Redraw dans MustBeResized()
4223-02-98 : FMN ; Remplacement PI par Standard_PI
4325-02-98 : FMN ; PERF.27: Optimisation of view creation from existing view
4411-03-98 : STT ; S3558
4519-03-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
46ne marche pas.
4708-04-98 : STT ; suppr. S3558
4810-04-98 : CAL ; Ajout des methodes RefToPix et PixToRef
4913-06-98 : FMN ; Probleme dans FitAll car la methode WNT_Window::Size(Real,Real)
50ne marche pas. Contournement en appelant WNT_Window::Size(Int,Int).
5116-08-98 : CAL ; S3892. Ajout grilles 3d.
5209-09-98 : CAL ; S3892. Generalisation de TrsPoint.
5324-09-98 : CAL ; Ajout d'un parametre a V3d_View::SetPlotter.
5406-10-98 : CAL ; Ajout d'un TIMER si CSF_GraphicTimer est definie.
5516-10-98 : CAL ; Retrait d'un TIMER si CSF_GraphicTimer est definie.
5606-11-98 : CAL ; PRO ?????. Probleme dans ZFitAll si un point dans la vue.
5713-06-98 : FMN ; PRO14896: Correction sur la gestion de la perspective (cf Programming Guinde)
5829-OCT-98 : DCB : Adding ScreenCopy () method.
7fd59977 5910-11-99 : GG ; PRO19603 Add Redraw( area ) method
60IMP130100 : GG
61-> Don't increase too much the ZSize.
62-> Initialize correctly the Z clipping and D cueing
63planes.
64IMP100701 : SZV ; Add ToPixMap() method
65
66REMARQUES :
67-----------
68About FitAll() multiple. This probleme is caused by missing
69precision of transformation matrices. If it is supposed that
70projection is made in the plane (U,V), there is a difference
71after several Zoom - compared to the exact value (cf ZoomX).
72Don't forget that the matrices work in float and not in double.
73To solve the problem (for lack of a better solution) I make 2 passes.
74
75************************************************************************/
76
b8ddfc2f 77//GER61351 //GG_15/12/99 Add SetBackgroundColor() and BackgroundColor() methods
7fd59977 78
79
7fd59977 80#define IMP020300 //GG Don't use ZFitAll in during Rotation
81// for perf improvment
82
83#define IMP210600 //GG Avoid to have infinite loop when call Rotation() method
84// without call before StartRotation().
85// This problem occurs when CTRL MB3 is maintain press betwwen 2 views.
86
87#define IMP250900 //GG Enable rotation around screen Z axis when
88// rotation begin far the center of the screen.
89// Thanks to Patrick REGINSTER (SAMTECH)
90// GG 21/12/00 Due to a regression on the previous specifications
91// this new functionnality is right now deactivated
92// by default (see StartRotation(...,zRotationThreshold)
93// method.
94
95#define BUC60952 //GG Enable to rotate around the view axis
96// and the required view point
97
98#define RIC120302 //GG Add a NEW SetWindow method which enable
99// to connect a graphic widget and context to OGL.
100
101#define IMP260302 //GG To avoid conflicting in Window destructor
102// nullify this handle in Remove method
103
104#define OCC280 //SAV fix for FitAll problem in the perspective view.
105
106#define OCC1188 //SAV Added methods to set background image
107
108/*----------------------------------------------------------------------*/
109/*
110* Includes
111*/
112
113#include <Standard_TypeMismatch.hxx>
197ac94e 114#include <Standard_ShortReal.hxx>
115#include <Standard_Assert.hxx>
116#include <Standard_ErrorHandler.hxx>
117#include <Standard_DivideByZero.hxx>
118
119#include <Visual3d_TransientManager.hxx>
7fd59977 120#include <Visual3d_ViewManager.hxx>
121#include <Visual3d_Light.hxx>
197ac94e 122#include <Visual3d_Layer.hxx>
123
7fd59977 124#include <V3d.hxx>
125#include <V3d_View.ixx>
6942f04a 126#include <V3d_BadValue.hxx>
b5ac8292 127#include <V3d_StereoDumpOptions.hxx>
197ac94e 128
129#include <Image_AlienPixMap.hxx>
130
7fd59977 131#include <gp_Dir.hxx>
b5ac8292 132#include <gp_Pln.hxx>
7fd59977 133#include <TColStd_Array2OfReal.hxx>
197ac94e 134#include <TColStd_HSequenceOfInteger.hxx>
135
136#include <Bnd_Box.hxx>
137
7fd59977 138#include <Precision.hxx>
139
b5ac8292 140#include <Graphic3d_Structure.hxx>
141#include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
142#include <Graphic3d_MapOfStructure.hxx>
143#include <Graphic3d_TextureEnv.hxx>
7fd59977 144#include <Graphic3d_AspectMarker3d.hxx>
1981cb22 145#include <Graphic3d_GraphicDriver.hxx>
7fd59977 146
147// S3603
148#include <Aspect_GenericColorMap.hxx>
149#include <Aspect_TypeMap.hxx>
150#include <Aspect_WidthMap.hxx>
151#include <Aspect_MarkMap.hxx>
152#include <Aspect_FontMap.hxx>
197ac94e 153#include <Aspect.hxx>
7fd59977 154
de75ed09 155#define V3d_FLAG_COMPUTATION 0x00000004
7fd59977 156
157// Perspective
158#include <OSD_Environment.hxx>
159
160/*----------------------------------------------------------------------*/
161/*
162* Constant
163*/
164
c6541a0c 165#define DEUXPI (2. * M_PI)
7fd59977 166
197ac94e 167//=============================================================================
168//function : Constructor
169//purpose :
170//=============================================================================
7fd59977 171V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) :
b5ac8292 172 MyProjModel(V3d_TPM_SCREEN),
173 MyViewer(VM.operator->()),
174 MyActiveLights(),
175 MyViewContext (),
176 myActiveLightsIterator(),
197ac94e 177 SwitchSetFront(Standard_False),
b5ac8292 178 MyTrsf (1, 4, 1, 4),
197ac94e 179 myAutoZFitIsOn (Standard_True),
180 myAutoZFitScaleFactor (1.0)
7fd59977 181{
7fd59977 182 myImmediateUpdate = Standard_False;
183 MyView = new Visual3d_View(MyViewer->Viewer());
184
185 // { Begin to retrieve the definition from ViewContext.
186 // Step MyViewContext = MyView->Context() ;
187 // to permit MyView->SetContext to compare
188 // the old and the new context.
189 // No problem for MyViewMapping, MyViewOrientation
190 // as MyView->SetViewMapping and MyView->SetViewOrientation
191 // don't try to optimize the modifications introduced to
192 // viewmapping and vieworientation.
193
194 // Aliasing
195 if ((MyView->Context ()).AliasingIsOn ())
196 MyViewContext.SetAliasingOn ();
197 else
198 MyViewContext.SetAliasingOff ();
199
200 // DepthCueing
201 MyViewContext.SetDepthCueingBackPlane
202 ((MyView->Context ()).DepthCueingBackPlane ());
203 MyViewContext.SetDepthCueingFrontPlane
204 ((MyView->Context ()).DepthCueingFrontPlane ());
205
206 if ((MyView->Context ()).DepthCueingIsOn ())
207 MyViewContext.SetDepthCueingOn ();
208 else
209 MyViewContext.SetDepthCueingOff ();
210
211 // ZClipping
212 MyViewContext.SetZClippingBackPlane
213 ((MyView->Context ()).ZClippingBackPlane ());
214 MyViewContext.SetZClippingFrontPlane
215 ((MyView->Context ()).ZClippingFrontPlane ());
216
217 if ((MyView->Context ()).FrontZClippingIsOn ())
218 MyViewContext.SetFrontZClippingOn ();
219 else
220 MyViewContext.SetFrontZClippingOff ();
221
222 if ((MyView->Context ()).BackZClippingIsOn ())
223 MyViewContext.SetBackZClippingOn ();
224 else
225 MyViewContext.SetBackZClippingOff ();
226
b5ac8292 227 // Visualization and Shading Model
7fd59977 228 MyViewContext.SetModel ((MyView->Context ()).Model ());
229 MyViewContext.SetVisualization ((MyView->Context ()).Visualization ());
230
231 // Texture Mapping
232 MyViewContext.SetSurfaceDetail (MyView->Context ().SurfaceDetail ());
233 MyViewContext.SetTextureEnv (MyView->Context ().TextureEnv ());
234 // } End of retrieval of the definition of ViewContext.
235
7fd59977 236 MyBackground = VM->GetBackgroundColor() ;
237 MyGradientBackground = VM->GetGradientBackground() ;
238
b5ac8292 239 // camera init
240 Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
241 aCamera->SetFOVy (45.0);
242 aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
243 aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
244 SetCamera (aCamera);
245
246 SetAxis (0.,0.,0.,1.,1.,1.);
247 SetVisualization (VM->DefaultVisualization());
248 SetShadingModel (VM->DefaultShadingModel());
249 SetSurfaceDetail (VM->DefaultSurfaceDetail());
250 SetTwist (0.);
251 SetAt (0.,0.,0.);
252 SetProj (VM->DefaultViewProj());
253 SetSize (VM->DefaultViewSize());
7fd59977 254 Standard_Real zsize = VM->DefaultViewSize();
b5ac8292 255 SetZSize (2.*zsize);
256 SetZClippingDepth (0.);
257 SetZClippingWidth (zsize);
258 SetZCueingDepth (0.);
259 SetZCueingWidth (zsize);
260 SetDepth (VM->DefaultViewSize()/2.0);
7fd59977 261 SetViewMappingDefault();
b5ac8292 262 VM->AddView (this);
7fd59977 263 Init();
264 myImmediateUpdate = Standard_True;
265
b5ac8292 266 aCamera->SetProjectionType ((Type == V3d_ORTHOGRAPHIC)
267 ? Graphic3d_Camera::Projection_Orthographic
268 : Graphic3d_Camera::Projection_Perspective);
7fd59977 269
7fd59977 270 MyTransparencyFlag = Standard_False;
7fd59977 271}
272
197ac94e 273//=============================================================================
274//function : Constructor
275//purpose :
276//=============================================================================
b5ac8292 277V3d_View::V3d_View(const Handle(V3d_Viewer)& theVM,const Handle(V3d_View)& theView) :
197ac94e 278 MyProjModel(V3d_TPM_SCREEN),
279 MyViewer(theVM.operator->()),
280 MyActiveLights(),
281 MyViewContext (),
282 myActiveLightsIterator(),
283 SwitchSetFront(Standard_False),
284 MyTrsf (1, 4, 1, 4)
7fd59977 285{
b5ac8292 286 Handle(Visual3d_View) aFromView = theView->View();
7fd59977 287
288 myImmediateUpdate = Standard_False;
b5ac8292 289 MyView = new Visual3d_View (MyViewer->Viewer());
7fd59977 290
b5ac8292 291 for (theView->InitActiveLights(); theView->MoreActiveLights(); theView->NextActiveLights())
292 {
293 MyActiveLights.Append (theView->ActiveLight());
294 }
7fd59977 295
b5ac8292 296 MyViewContext = aFromView->Context() ;
7fd59977 297
b5ac8292 298 SetCamera (new Graphic3d_Camera (theView->Camera()));
197ac94e 299 myAutoZFitIsOn = theView->AutoZFitMode();
300 myAutoZFitScaleFactor = theView->AutoZFitScaleFactor();
7fd59977 301
b5ac8292 302 MyBackground = aFromView->Background() ;
303 MyGradientBackground = aFromView->GradientBackground();
304
305 MyView->SetContext (MyViewContext) ;
306
307 SetAxis (0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
308
309 theVM->AddView (this);
7fd59977 310
7fd59977 311 Init();
b5ac8292 312
7fd59977 313 myImmediateUpdate = Standard_True;
7fd59977 314}
315
197ac94e 316//=============================================================================
317//function : SetMagnify
318//purpose :
319//=============================================================================
7fd59977 320void V3d_View::SetMagnify(const Handle(Aspect_Window)& TheWindow,
321 const Handle(V3d_View)& aPreviousView,
322 const Standard_Integer x1,
323 const Standard_Integer y1,
324 const Standard_Integer x2,
325 const Standard_Integer y2)
326{
7fd59977 327 if( !MyView->IsDefined() ) {
328 Standard_Real a,b,c,d;
329 aPreviousView->Convert(x1,y1,a,b);
330 aPreviousView->Convert(x2,y2,c,d);
331 MyView->SetWindow(TheWindow) ;
332 FitAll(TheWindow,a,b,c,d);
333 MyView->SetContext(MyViewContext) ;
7fd59977 334 MyView->SetBackground(MyBackground) ;
335 MyViewer->SetViewOn(this) ;
336 MyWindow = TheWindow;
337 MyView->Redraw() ;
338 SetViewMappingDefault();
339 }
7fd59977 340}
341
197ac94e 342//=============================================================================
343//function : SetWindow
344//purpose :
345//=============================================================================
7fd59977 346void V3d_View::SetWindow(const Handle(Aspect_Window)& TheWindow)
347{
7fd59977 348 Standard_MultiplyDefined_Raise_if( MyView->IsDefined(),
349 "V3d_View::SetWindow, window of view already defined");
350
351 MyView->SetWindow(TheWindow) ;
cdc2203b
M
352 // AGV: Method V3d_View::SetWindow() should assign the field MyWindow before
353 // calling Redraw(). Otherwise it is impossible to call certain methods of
354 // V3d_View like Convert() inside the context of Redraw(),
355 // particularly in class NIS_View.
356 MyWindow = TheWindow;
7fd59977 357 // SetWindow carries out SetRatio and modifies
7fd59977 358 MyView->SetContext(MyViewContext) ;
7fd59977 359 MyView->SetBackground(MyBackground) ;
360 MyViewer->SetViewOn(this) ;
7fd59977 361 MyView->Redraw() ;
7fd59977 362}
363
197ac94e 364//=============================================================================
365//function : SetWindow
366//purpose :
367//=============================================================================
7fd59977 368void V3d_View::SetWindow(const Handle(Aspect_Window)& aWindow,
369 const Aspect_RenderingContext aContext,
370 const Aspect_GraphicCallbackProc& aDisplayCB,
371 const Standard_Address aClientData)
372{
7fd59977 373 Standard_MultiplyDefined_Raise_if( MyView->IsDefined(),
374 "V3d_View::SetWindow, "
375 "window of view already defined");
cdc2203b
M
376 // AGV: Method V3d_View::SetWindow() should assign the field MyWindow before
377 // calling Redraw(). Otherwise it is impossible to call certain methods of
378 // V3d_View like Convert() inside the context of Redraw(),
379 // particularly in class NIS_View.
380 MyWindow = aWindow;
7fd59977 381 MyView->SetWindow(aWindow, aContext, aDisplayCB, aClientData) ;
7fd59977 382 MyView->SetContext(MyViewContext) ;
7fd59977 383 MyView->SetBackground(MyBackground) ;
384 MyViewer->SetViewOn(this) ;
385 MyView->Redraw() ;
7fd59977 386}
7fd59977 387
197ac94e 388//=============================================================================
389//function : Remove
390//purpose :
391//=============================================================================
5e27df78 392void V3d_View::Remove() const
393{
394 MyViewer->DelView (this);
395 MyView->Remove();
396 Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
397 aWin.Nullify();
7fd59977 398}
399
197ac94e 400//=============================================================================
401//function : Update
402//purpose :
403//=============================================================================
b8ddfc2f 404void V3d_View::Update() const
405{
7fd59977 406 if( MyView->IsDefined() ) MyView->Update() ;
407}
408
197ac94e 409//=============================================================================
410//function : Redraw
411//purpose :
412//=============================================================================
b8ddfc2f 413void V3d_View::Redraw() const
414{
7fd59977 415 if( MyView->IsDefined() ) MyView->Redraw() ;
416}
b8ddfc2f 417
197ac94e 418//=============================================================================
419//function : Redraw
420//purpose :
421//=============================================================================
7fd59977 422void V3d_View::Redraw(const Standard_Integer xc,const Standard_Integer yc,
423 const Standard_Integer width,const Standard_Integer height) const
424{
425 if( MyView->IsDefined() ) MyView->Redraw(xc,yc,width,height) ;
426}
427
197ac94e 428//=============================================================================
429//function : IsEmpty
430//purpose :
431//=============================================================================
b8ddfc2f 432Standard_Boolean V3d_View::IsEmpty() const
433{
7fd59977 434 Standard_Boolean TheStatus = Standard_True ;
435 if( MyView->IsDefined() ) {
436 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
437 if( Nstruct > 0 ) TheStatus = Standard_False ;
438 }
439 return (TheStatus) ;
7fd59977 440}
441
197ac94e 442//=============================================================================
443//function : UpdateLights
444//purpose :
445//=============================================================================
b8ddfc2f 446void V3d_View::UpdateLights() const
447{
7fd59977 448 MyView->SetContext(MyViewContext);
449 Update();
450}
451
197ac94e 452//=============================================================================
453//function : DoMapping
454//purpose :
455//=============================================================================
b8ddfc2f 456void V3d_View::DoMapping()
457{
7fd59977 458 if( MyView->IsDefined() ) {
459 (MyView->Window())->DoMapping() ;
460 }
461}
462
197ac94e 463//=============================================================================
464//function : MustBeResized
465//purpose :
466//=============================================================================
b8ddfc2f 467void V3d_View::MustBeResized()
468{
7fd59977 469 if ( !MyLayerMgr.IsNull() )
470 MyLayerMgr->Resized();
471
472 if( MyView->IsDefined() ) {
473 MyView->Resized() ;
7fd59977 474 MyView->Redraw();
475 }
7fd59977 476}
477
197ac94e 478//=============================================================================
479//function : SetBackgroundColor
480//purpose :
481//=============================================================================
7fd59977 482void V3d_View::SetBackgroundColor(const Quantity_TypeOfColor Type, const Standard_Real v1, const Standard_Real v2, const Standard_Real v3)
483{
484 Standard_Real V1 = Max( Min( v1, 1.0 ), 0.0 );
485 Standard_Real V2 = Max( Min( v2, 1.0 ), 0.0 );
486 Standard_Real V3 = Max( Min( v3, 1.0 ), 0.0 );
487
488 Quantity_Color C( V1, V2, V3, Type );
7fd59977 489 SetBackgroundColor( C );
7fd59977 490}
491
197ac94e 492//=============================================================================
493//function : SetBackgroundColor
494//purpose :
495//=============================================================================
7fd59977 496void V3d_View::SetBackgroundColor(const Quantity_Color &Color)
497{
498 MyBackground.SetColor( Color );
499 if ( MyView->IsDefined() )
500 MyView->SetBackground( MyBackground );
501 //szv: Why?
502 if ( !MyLayerMgr.IsNull() )
503 MyLayerMgr->Resized();
504}
7fd59977 505
197ac94e 506//=============================================================================
507//function : SetBackgroundColor
508//purpose :
509//=============================================================================
7fd59977 510void V3d_View::SetBackgroundColor(const Quantity_NameOfColor Name)
511{
512 Quantity_Color C( Name );
7fd59977 513 SetBackgroundColor( C );
7fd59977 514}
515
197ac94e 516//=============================================================================
517//function : SetBgGradientColors
518//purpose :
519//=============================================================================
7fd59977 520void V3d_View::SetBgGradientColors( const Quantity_Color& Color1,
521 const Quantity_Color& Color2,
522 const Aspect_GradientFillMethod FillStyle,
523 const Standard_Boolean status)
524{
7fd59977 525 MyGradientBackground.SetColors(Color1, Color2, FillStyle);
526 if ( MyView->IsDefined() )
527 MyView->SetGradientBackground( MyGradientBackground, status );
7fd59977 528}
529
197ac94e 530//=============================================================================
531//function : SetBgGradientColors
532//purpose :
533//=============================================================================
7fd59977 534void V3d_View::SetBgGradientColors( const Quantity_NameOfColor Color1,
535 const Quantity_NameOfColor Color2,
536 const Aspect_GradientFillMethod FillStyle,
537 const Standard_Boolean status )
538{
539 Quantity_Color C1( Color1 );
540 Quantity_Color C2( Color2 );
541 MyGradientBackground.SetColors( C1, C2, FillStyle );
542 if ( MyView->IsDefined() )
543 MyView->SetGradientBackground( MyGradientBackground, status );
544}
545
197ac94e 546//=============================================================================
547//function : SetBgGradientStyle
548//purpose :
549//=============================================================================
7fd59977 550void V3d_View::SetBgGradientStyle( const Aspect_GradientFillMethod FillStyle,
f8b2ed36 551 const Standard_Boolean update)
7fd59977 552{
f8b2ed36 553 Quantity_Color Color1, Color2;
554 MyGradientBackground.Colors( Color1, Color2 );
555 MyGradientBackground.SetColors( Color1, Color2, FillStyle );
7fd59977 556 if( MyView->IsDefined() )
f8b2ed36 557 MyView->SetBgGradientStyle( FillStyle, update ) ;
7fd59977 558}
559
197ac94e 560//=============================================================================
561//function : SetBackgroundImage
562//purpose :
563//=============================================================================
7fd59977 564void V3d_View::SetBackgroundImage( const Standard_CString FileName,
565 const Aspect_FillMethod FillStyle,
566 const Standard_Boolean update )
567{
568#ifdef OCC1188
569 if( MyView->IsDefined() )
570 MyView->SetBackgroundImage( FileName, FillStyle, update ) ;
571#endif
572}
573
197ac94e 574//=============================================================================
575//function : SetBgImageStyle
576//purpose :
577//=============================================================================
7fd59977 578void V3d_View::SetBgImageStyle( const Aspect_FillMethod FillStyle,
579 const Standard_Boolean update )
580{
581#ifdef OCC1188
582 if( MyView->IsDefined() )
583 MyView->SetBgImageStyle( FillStyle, update ) ;
584#endif
585}
586
197ac94e 587//=============================================================================
588//function : SetAxis
589//purpose :
590//=============================================================================
b8ddfc2f 591void 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)
592{
7fd59977 593 Standard_Real D,Nx = Vx,Ny = Vy,Nz = Vz ;
594
595 D = Sqrt( Vx*Vx + Vy*Vy + Vz*Vz ) ;
6942f04a 596 V3d_BadValue_Raise_if ( D <= 0. , "V3d_View::SetAxis, bad axis");
7fd59977 597 Nx /= D ; Ny /= D ; Nz /= D ;
598 MyDefaultViewPoint.SetCoord(X,Y,Z) ;
599 MyDefaultViewAxis.SetCoord(Nx,Ny,Nz) ;
7fd59977 600}
601
197ac94e 602//=============================================================================
603//function : SetShadingModel
604//purpose :
605//=============================================================================
b8ddfc2f 606void V3d_View::SetShadingModel(const V3d_TypeOfShadingModel Model)
607{
7fd59977 608 MyViewContext.SetModel((Visual3d_TypeOfModel) Model) ;
609 MyView->SetContext(MyViewContext) ;
7fd59977 610}
611
197ac94e 612//=============================================================================
613//function : SetSurfaceDetail
614//purpose :
615//=============================================================================
b8ddfc2f 616void V3d_View::SetSurfaceDetail(const V3d_TypeOfSurfaceDetail Model)
617{
7fd59977 618 MyViewContext.SetSurfaceDetail((Visual3d_TypeOfSurfaceDetail) Model) ;
619 MyView->SetContext(MyViewContext) ;
7fd59977 620}
621
197ac94e 622//=============================================================================
623//function : SetTextureEnv
624//purpose :
625//=============================================================================
b8ddfc2f 626void V3d_View::SetTextureEnv(const Handle(Graphic3d_TextureEnv)& ATexture)
627{
7fd59977 628 MyViewContext.SetTextureEnv(ATexture) ;
629 MyView->SetContext(MyViewContext) ;
7fd59977 630}
631
197ac94e 632//=============================================================================
633//function : SetVisualization
634//purpose :
635//=============================================================================
b8ddfc2f 636void V3d_View::SetVisualization(const V3d_TypeOfVisualization Mode)
637{
7fd59977 638 MyViewContext.SetVisualization((Visual3d_TypeOfVisualization) Mode);
639 MyView->SetContext(MyViewContext) ;
7fd59977 640}
641
197ac94e 642//=============================================================================
643//function : SetFront
644//purpose :
645//=============================================================================
b8ddfc2f 646void V3d_View::SetFront()
647{
7fd59977 648 gp_Ax3 a = MyViewer->PrivilegedPlane();
b5ac8292 649 Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
7fd59977 650
651 a.Direction().Coord(vx,vy,vz);
652 a.YDirection().Coord(xu,yu,zu);
653 a.Location().Coord(xo,yo,zo);
654
b5ac8292 655 myCamera->SetCenter (gp_Pnt (xo, yo, zo));
7fd59977 656 if(SwitchSetFront)
b5ac8292 657 myCamera->SetDirection (gp_Dir (vx, vy, vz));
7fd59977 658 else
b5ac8292 659 myCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
660 myCamera->SetUp (gp_Dir (xu, yu, zu));
7fd59977 661
b5ac8292 662 AutoZFit();
7fd59977 663
b5ac8292 664 SwitchSetFront = !SwitchSetFront;
7fd59977 665
666 ImmediateUpdate();
7fd59977 667}
668
197ac94e 669//=============================================================================
670//function : Rotate
671//purpose :
672//=============================================================================
b5ac8292 673void V3d_View::Rotate (const Standard_Real ax,
674 const Standard_Real ay,
675 const Standard_Real az,
676 const Standard_Boolean Start)
b8ddfc2f 677{
b5ac8292 678 Standard_Real Ax = ax;
679 Standard_Real Ay = ay;
680 Standard_Real Az = az;
7fd59977 681
b5ac8292 682 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
683 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
684 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
685 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
686 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
687 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
688
689 if (Start)
690 {
691 myCamStartOpUp = myCamera->Up();
692 myCamStartOpEye = myCamera->Eye();
693 myCamStartOpCenter = myCamera->Center();
694 }
695
b5ac8292 696 myCamera->SetUp (myCamStartOpUp);
697 myCamera->SetEye (myCamStartOpEye);
698 myCamera->SetCenter (myCamStartOpCenter);
699
700 // rotate camera around 3 initial axes
701 gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye));
702 gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
703 gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
704 gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
705
706 gp_Trsf aRot[3], aTrsf;
707 aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
708 aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
709 aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
710 aTrsf.Multiply (aRot[0]);
711 aTrsf.Multiply (aRot[1]);
712 aTrsf.Multiply (aRot[2]);
713
714 myCamera->Transform (aTrsf);
715
b5ac8292 716 AutoZFit();
7fd59977 717
7fd59977 718 ImmediateUpdate();
7fd59977 719}
720
197ac94e 721//=============================================================================
722//function : Rotate
723//purpose :
724//=============================================================================
7fd59977 725void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
726 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
727{
b5ac8292 728
7fd59977 729 Standard_Real Ax = ax ;
730 Standard_Real Ay = ay ;
731 Standard_Real Az = az ;
7fd59977 732
733 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
734 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
735 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
736 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
737 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
738 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
739
b5ac8292 740 if (Start)
741 {
742 myGravityReferencePoint.SetCoord (X, Y, Z);
743 myCamStartOpUp = myCamera->Up();
744 myCamStartOpEye = myCamera->Eye();
745 myCamStartOpCenter = myCamera->Center();
746 }
747
748 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
749
b5ac8292 750 myCamera->SetUp (myCamStartOpUp);
751 myCamera->SetEye (myCamStartOpEye);
752 myCamera->SetCenter (myCamStartOpCenter);
753
754 // rotate camera around 3 initial axes
755 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
756
757 gp_Dir aZAxis (myCamera->Direction().Reversed());
758 gp_Dir aYAxis (myCamera->Up());
759 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
760
761 gp_Trsf aRot[3], aTrsf;
762 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
763 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
764 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
765 aTrsf.Multiply (aRot[0]);
766 aTrsf.Multiply (aRot[1]);
767 aTrsf.Multiply (aRot[2]);
768
769 myCamera->Transform (aTrsf);
b5ac8292 770
771 AutoZFit();
772
7fd59977 773 ImmediateUpdate();
7fd59977 774}
775
197ac94e 776//=============================================================================
777//function : Rotate
778//purpose :
779//=============================================================================
b8ddfc2f 780void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
781{
7fd59977 782 switch (Axe) {
783 case V3d_X :
784 Rotate(angle,0.,0.,Start);
785 break ;
786 case V3d_Y :
787 Rotate(0.,angle,0.,Start);
788 break ;
789 case V3d_Z :
790 Rotate(0.,0.,angle,Start);
791 break ;
792 }
7fd59977 793}
794
197ac94e 795//=============================================================================
796//function : Rotate
797//purpose :
798//=============================================================================
7fd59977 799void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle,
800 const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
801{
7fd59977 802 Standard_Real Angle = angle ;
7fd59977 803
804 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
805 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
806
b5ac8292 807 if (Start)
808 {
809 myGravityReferencePoint.SetCoord (X, Y, Z);
810 myCamStartOpUp = myCamera->Up();
811 myCamStartOpEye = myCamera->Eye();
812 myCamStartOpCenter = myCamera->Center();
813
7fd59977 814 switch (Axe) {
815 case V3d_X :
b5ac8292 816 myViewAxis.SetCoord(1.,0.,0.) ;
7fd59977 817 break ;
818 case V3d_Y :
b5ac8292 819 myViewAxis.SetCoord(0.,1.,0.) ;
7fd59977 820 break ;
821 case V3d_Z :
b5ac8292 822 myViewAxis.SetCoord(0.,0.,1.) ;
7fd59977 823 break ;
824 }
b5ac8292 825
826 myCamStartOpUp = myCamera->Up();
827 myCamStartOpEye = myCamera->Eye();
828 myCamStartOpCenter = myCamera->Center();
7fd59977 829 }
830
b5ac8292 831 const Graphic3d_Vertex& aVref = myGravityReferencePoint;
832
b5ac8292 833 myCamera->SetUp (myCamStartOpUp);
834 myCamera->SetEye (myCamStartOpEye);
835 myCamera->SetCenter (myCamStartOpCenter);
836
837 // rotate camera around passed axis
838 gp_Trsf aRotation;
839 gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
840 gp_Dir aRAxis ((Axe == V3d_X) ? 1.0 : 0.0,
841 (Axe == V3d_Y) ? 1.0 : 0.0,
842 (Axe == V3d_Z) ? 1.0 : 0.0);
843
844 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
845 myCamera->Transform (aRotation);
846
b5ac8292 847 AutoZFit();
848
7fd59977 849 ImmediateUpdate();
7fd59977 850}
851
197ac94e 852//=============================================================================
853//function : Rotate
854//purpose :
855//=============================================================================
b8ddfc2f 856void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
857{
b5ac8292 858 Standard_Real Angle = angle;
7fd59977 859
860 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
861 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
862
863 if( Start ) {
b5ac8292 864 myCamStartOpUp = myCamera->Up();
865 myCamStartOpEye = myCamera->Eye();
866 myCamStartOpCenter = myCamera->Center();
7fd59977 867 }
868
b5ac8292 869 const Graphic3d_Vertex& aPnt = MyDefaultViewPoint;
870 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
871
b5ac8292 872 myCamera->SetUp (myCamStartOpUp);
873 myCamera->SetEye (myCamStartOpEye);
874 myCamera->SetCenter (myCamStartOpCenter);
875
876 gp_Trsf aRotation;
877 gp_Pnt aRCenter (aPnt.X(), aPnt.Y(), aPnt.Z());
878 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
879 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
880 myCamera->Transform (aRotation);
881
b5ac8292 882 AutoZFit();
883
7fd59977 884 ImmediateUpdate();
7fd59977 885}
886
197ac94e 887//=============================================================================
888//function : Turn
889//purpose :
890//=============================================================================
7fd59977 891void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
892{
b5ac8292 893 Standard_Real Ax = ax;
894 Standard_Real Ay = ay;
895 Standard_Real Az = az;
7fd59977 896
897 if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
898 else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
899 if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
900 else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
901 if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
902 else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
903
904 if( Start ) {
b5ac8292 905 myCamStartOpUp = myCamera->Up();
906 myCamStartOpEye = myCamera->Eye();
907 myCamStartOpCenter = myCamera->Center();
908 }
909
b5ac8292 910 myCamera->SetUp (myCamStartOpUp);
911 myCamera->SetEye (myCamStartOpEye);
912 myCamera->SetCenter (myCamStartOpCenter);
913
914 // rotate camera around 3 initial axes
915 gp_Pnt aRCenter = myCamera->Eye();
916 gp_Dir aZAxis (myCamera->Direction().Reversed());
917 gp_Dir aYAxis (myCamera->Up());
918 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
919
920 gp_Trsf aRot[3], aTrsf;
921 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
922 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
923 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
924 aTrsf.Multiply (aRot[0]);
925 aTrsf.Multiply (aRot[1]);
926 aTrsf.Multiply (aRot[2]);
927
928 myCamera->Transform (aTrsf);
b5ac8292 929
930 AutoZFit();
931
932 ImmediateUpdate();
7fd59977 933}
934
197ac94e 935//=============================================================================
936//function : Turn
937//purpose :
938//=============================================================================
7fd59977 939void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
940{
7fd59977 941 switch (Axe) {
942 case V3d_X :
943 Turn(angle,0.,0.,Start);
944 break ;
945 case V3d_Y :
946 Turn(0.,angle,0.,Start);
947 break ;
948 case V3d_Z :
949 Turn(0.,0.,angle,Start);
950 break ;
951 }
952}
953
197ac94e 954//=============================================================================
955//function : Turn
956//purpose :
957//=============================================================================
b8ddfc2f 958void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
959{
7fd59977 960 Standard_Real Angle = angle ;
7fd59977 961
962 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
963 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
964
965 if( Start ) {
b5ac8292 966 myCamStartOpUp = myCamera->Up();
967 myCamStartOpEye = myCamera->Eye();
968 myCamStartOpCenter = myCamera->Center();
969 }
970
b5ac8292 971 myCamera->SetUp (myCamStartOpUp);
972 myCamera->SetEye (myCamStartOpEye);
973 myCamera->SetCenter (myCamStartOpCenter);
974
975 const Graphic3d_Vector& anAxis = MyDefaultViewAxis;
976
977 gp_Trsf aRotation;
978 gp_Pnt aRCenter = myCamera->Eye();
979 gp_Dir aRAxis (anAxis.X(), anAxis.Y(), anAxis.Z());
980 aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
981 myCamera->Transform (aRotation);
982
b5ac8292 983 AutoZFit();
984
985 ImmediateUpdate();
7fd59977 986}
987
197ac94e 988//=============================================================================
989//function : SetTwist
990//purpose :
991//=============================================================================
b8ddfc2f 992void V3d_View::SetTwist(const Standard_Real angle)
993{
7fd59977 994 Standard_Real Angle = angle ;
b5ac8292 995 Standard_Boolean TheStatus;
7fd59977 996
997 if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
998 else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
999
b5ac8292 1000 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1001 gp_Dir anUp;
1002
1003 anUp = gp_Dir (0.0, 0.0, 1.0);
1004
1005 TheStatus = ScreenAxis(aReferencePlane, anUp,
1006 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1007 if( !TheStatus ) {
b5ac8292 1008 anUp = gp_Dir (0.0, 1.0, 0.0);
1009 TheStatus = ScreenAxis(aReferencePlane, anUp,
1010 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1011 }
1012 if( !TheStatus ) {
b5ac8292 1013 anUp = gp_Dir (1.0, 0.0, 0.0);
1014 TheStatus = ScreenAxis(aReferencePlane, anUp,
1015 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1016 }
1017
6942f04a 1018 V3d_BadValue_Raise_if( !TheStatus,"V3d_ViewSetTwist, alignment of Eye,At,Up,");
b5ac8292 1019
1020 gp_Pnt aRCenter = myCamera->Center();
1021 gp_Dir aZAxis (myCamera->Direction().Reversed());
1022
1023 gp_Trsf aTrsf;
1024 aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
1025
1026 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1027 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
197ac94e 1028
b5ac8292 1029 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
1030 myCamera->Transform (aTrsf);
b5ac8292 1031
1032 AutoZFit();
7fd59977 1033
7fd59977 1034 ImmediateUpdate();
7fd59977 1035}
1036
197ac94e 1037//=============================================================================
1038//function : SetAutoZFitMode
1039//purpose :
1040//=============================================================================
1041void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn, const Standard_Real theScaleFactor)
7fd59977 1042{
197ac94e 1043 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
1044 myAutoZFitScaleFactor = theScaleFactor;
1045 myAutoZFitIsOn = theIsOn;
7fd59977 1046}
1047
197ac94e 1048//=============================================================================
1049//function : AutoZFitMode
1050//purpose :
1051//=============================================================================
1052Standard_Boolean V3d_View::AutoZFitMode() const
b8ddfc2f 1053{
197ac94e 1054 return myAutoZFitIsOn;
7fd59977 1055}
7fd59977 1056
197ac94e 1057//=============================================================================
1058//function : AutoZFitScaleFactor
1059//purpose :
1060//=============================================================================
1061Standard_Real V3d_View::AutoZFitScaleFactor () const
b8ddfc2f 1062{
197ac94e 1063 return myAutoZFitScaleFactor;
1064}
b5ac8292 1065
197ac94e 1066//=============================================================================
1067//function : SetEye
1068//purpose :
1069//=============================================================================
1070void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1071{
1072 Standard_Real aTwistBefore = Twist();
7fd59977 1073
197ac94e 1074 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
b5ac8292 1075
197ac94e 1076 myCamera->SetEye (gp_Pnt (X, Y, Z));
1077 SetTwist (aTwistBefore);
b5ac8292 1078
1079 AutoZFit();
1080
197ac94e 1081 SetImmediateUpdate (wasUpdateEnabled);
1082
b5ac8292 1083 ImmediateUpdate();
7fd59977 1084}
1085
197ac94e 1086//=============================================================================
1087//function : SetDepth
1088//purpose :
1089//=============================================================================
b8ddfc2f 1090void V3d_View::SetDepth(const Standard_Real Depth)
1091{
b5ac8292 1092 V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
7fd59977 1093
7fd59977 1094 if( Depth > 0. )
7fd59977 1095 {
b5ac8292 1096 // Move eye using center (target) as anchor.
1097 myCamera->SetDistance (Depth);
1098 }
1099 else
197ac94e 1100 {
b5ac8292 1101 // Move the view ref point instead of the eye.
1102 gp_Vec aDir (myCamera->Direction());
1103 gp_Pnt aCameraEye = myCamera->Eye();
197ac94e 1104 gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1105
b5ac8292 1106 myCamera->SetCenter (aCameraCenter);
7fd59977 1107 }
7fd59977 1108
b5ac8292 1109 AutoZFit();
1110
1111 ImmediateUpdate();
7fd59977 1112}
1113
197ac94e 1114//=============================================================================
1115//function : SetProj
1116//purpose :
1117//=============================================================================
7fd59977 1118void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1119{
6942f04a 1120 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
7fd59977 1121 "V3d_View::SetProj, null projection vector");
1122
197ac94e 1123 Standard_Real aTwistBefore = Twist();
b5ac8292 1124
197ac94e 1125 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
b5ac8292 1126
197ac94e 1127 myCamera->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
b5ac8292 1128
197ac94e 1129 if (MyProjModel == V3d_TPM_SCREEN)
1130 {
1131 SetTwist(aTwistBefore);
1132 }
b5ac8292 1133
1134 AutoZFit();
1135
197ac94e 1136 SetImmediateUpdate (wasUpdateEnabled);
1137
7fd59977 1138 ImmediateUpdate();
7fd59977 1139}
1140
197ac94e 1141//=============================================================================
1142//function : SetProj
1143//purpose :
1144//=============================================================================
b8ddfc2f 1145void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
1146{
7fd59977 1147 Standard_Real Xpn=0;
1148 Standard_Real Ypn=0;
1149 Standard_Real Zpn=0;
1150
1151 switch (Orientation) {
1152 case V3d_Zpos :
b5ac8292 1153 Ypn = 1.;
1154 break;
7fd59977 1155 case V3d_Zneg :
b5ac8292 1156 Ypn = -1.;
1157 break;
7fd59977 1158 default:
1159 Zpn = 1.;
1160 }
b5ac8292 1161
1162 const Graphic3d_Vector& aBck = V3d::GetProjAxis (Orientation);
197ac94e 1163
1164 // retain camera panning from origin when switching projection
1165 gp_Pnt anOriginVCS = myCamera->ConvertWorld2View (gp::Origin());
1166 Standard_Real aPanX = anOriginVCS.X();
1167 Standard_Real aPanY = anOriginVCS.Y();
1168
b5ac8292 1169 myCamera->SetCenter (gp_Pnt (0, 0, 0));
1170 myCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
1171 myCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
197ac94e 1172 myCamera->OrthogonalizeUp();
1173
1174 Panning (aPanX, aPanY);
b5ac8292 1175
1176 AutoZFit();
1177
7fd59977 1178 ImmediateUpdate();
7fd59977 1179}
1180
197ac94e 1181//=============================================================================
1182//function : SetAt
1183//purpose :
1184//=============================================================================
b8ddfc2f 1185void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1186{
197ac94e 1187 Standard_Real aTwistBefore = Twist();
b5ac8292 1188
197ac94e 1189 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
b5ac8292 1190
1191 myCamera->SetCenter (gp_Pnt (X, Y, Z));
b5ac8292 1192
197ac94e 1193 SetTwist (aTwistBefore);
b5ac8292 1194
1195 AutoZFit();
1196
197ac94e 1197 SetImmediateUpdate (wasUpdateEnabled);
1198
7fd59977 1199 ImmediateUpdate();
7fd59977 1200}
1201
197ac94e 1202//=============================================================================
1203//function : SetUp
1204//purpose :
1205//=============================================================================
b8ddfc2f 1206void V3d_View::SetUp(const Standard_Real Vx,const Standard_Real Vy,const Standard_Real Vz)
1207{
7fd59977 1208 Standard_Boolean TheStatus ;
6942f04a 1209 V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0. ,
7fd59977 1210 "V3d_View::SetUp, nullUp vector");
1211
b5ac8292 1212 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1213 gp_Dir anUp (Vx, Vy, Vz);
1214
1215 TheStatus = ScreenAxis(aReferencePlane,anUp,
1216 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1217 if( !TheStatus ) {
b5ac8292 1218 anUp = gp_Dir (0.0, 0.0, 1.0);
1219 TheStatus = ScreenAxis(aReferencePlane,anUp,
1220 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1221 }
1222 if( !TheStatus ) {
b5ac8292 1223 anUp = gp_Dir (0.0, 1.0, 0.0);
1224 TheStatus = ScreenAxis(aReferencePlane,anUp,
1225 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1226 }
1227 if( !TheStatus ) {
b5ac8292 1228 anUp = gp_Dir (1.0, 0.0, 0.0);
1229 TheStatus = ScreenAxis(aReferencePlane,anUp,
1230 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1231 }
6942f04a 1232 V3d_BadValue_Raise_if( !TheStatus,"V3d_View::Setup, alignment of Eye,At,Up");
7fd59977 1233
b5ac8292 1234 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1235 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1236
b5ac8292 1237 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
197ac94e 1238
b5ac8292 1239 AutoZFit();
b5ac8292 1240
7fd59977 1241 ImmediateUpdate();
7fd59977 1242}
1243
197ac94e 1244//=============================================================================
1245//function : SetUp
1246//purpose :
1247//=============================================================================
b8ddfc2f 1248void V3d_View::SetUp( const V3d_TypeOfOrientation Orientation )
1249{
7fd59977 1250 Standard_Boolean TheStatus ;
1251
b5ac8292 1252 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
1253 gp_Dir anUp;
1254
1255 const Graphic3d_Vector& aViewReferenceUp = V3d::GetProjAxis(Orientation) ;
1256 anUp = gp_Dir (aViewReferenceUp.X(), aViewReferenceUp.Y(), aViewReferenceUp.Z());
1257
1258 TheStatus = ScreenAxis(aReferencePlane,anUp,
1259 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1260 if( !TheStatus ) {
b5ac8292 1261 anUp = gp_Dir (0.,0.,1.);
1262 TheStatus = ScreenAxis(aReferencePlane,anUp,
1263 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1264 }
1265 if( !TheStatus ) {
b5ac8292 1266 anUp = gp_Dir (0.,1.,0.);
1267 TheStatus = ScreenAxis(aReferencePlane,anUp,
1268 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1269 }
1270 if( !TheStatus ) {
b5ac8292 1271 anUp = gp_Dir (1.,0.,0.);
1272 TheStatus = ScreenAxis(aReferencePlane,anUp,
1273 myXscreenAxis,myYscreenAxis,myZscreenAxis) ;
7fd59977 1274 }
6942f04a 1275 V3d_BadValue_Raise_if( !TheStatus, "V3d_View::SetUp, alignment of Eye,At,Up");
7fd59977 1276
b5ac8292 1277 Standard_Real myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ;
1278 myYscreenAxis.Coord (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ);
1279
b5ac8292 1280 myCamera->SetUp (gp_Dir (myYscreenAxisX, myYscreenAxisY, myYscreenAxisZ));
197ac94e 1281
b5ac8292 1282 AutoZFit();
7fd59977 1283
7fd59977 1284 ImmediateUpdate();
1285}
1286
197ac94e 1287//=============================================================================
1288//function : SetViewOrientationDefault
1289//purpose :
1290//=============================================================================
b8ddfc2f 1291void V3d_View::SetViewOrientationDefault()
1292{
7fd59977 1293 MyView->SetViewOrientationDefault() ;
b5ac8292 1294
7fd59977 1295 ImmediateUpdate();
1296}
1297
197ac94e 1298//=============================================================================
1299//function : ResetViewOrientation
1300//purpose :
1301//=============================================================================
b8ddfc2f 1302void V3d_View::ResetViewOrientation()
1303{
7fd59977 1304 MyView->ViewOrientationReset() ;
b5ac8292 1305
7fd59977 1306 ImmediateUpdate();
1307}
1308
197ac94e 1309//=============================================================================
1310//function : Reset
1311//purpose :
1312//=============================================================================
b8ddfc2f 1313void V3d_View::Reset( const Standard_Boolean update )
1314{
b5ac8292 1315 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1316
1317 if (!aDefaultCamera.IsNull())
1318 {
b5ac8292 1319 myCamera->CopyMappingData (aDefaultCamera);
1320 myCamera->CopyOrientationData (aDefaultCamera);
197ac94e 1321
1322 AutoZFit();
b5ac8292 1323 }
7fd59977 1324
7fd59977 1325 SwitchSetFront = Standard_False;
b5ac8292 1326
7fd59977 1327 if( !myImmediateUpdate && update ) Update();
7fd59977 1328}
1329
197ac94e 1330//=======================================================================
1331//function : SetCenter
1332//purpose :
1333//=======================================================================
1334void V3d_View::SetCenter (const Standard_Integer theXp,
1335 const Standard_Integer theYp)
b8ddfc2f 1336{
197ac94e 1337 Standard_Real aXv, aYv;
1338 Convert (theXp, theYp, aXv, aYv);
1339 Translate (myCamera, aXv, aYv);
7fd59977 1340
7fd59977 1341 ImmediateUpdate();
7fd59977 1342}
1343
197ac94e 1344//=============================================================================
1345//function : SetSize
1346//purpose :
1347//=============================================================================
3dfe95cd 1348void V3d_View::SetSize (const Standard_Real theSize)
7fd59977 1349{
3dfe95cd 1350 V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
7fd59977 1351
3dfe95cd 1352 myCamera->SetScale (myCamera->Aspect() >= 1.0 ? theSize / myCamera->Aspect() : theSize);
197ac94e 1353
b5ac8292 1354 AutoZFit();
7fd59977 1355
7fd59977 1356 ImmediateUpdate();
7fd59977 1357}
1358
197ac94e 1359//=============================================================================
1360//function : SetZSize
1361//purpose :
1362//=============================================================================
7fd59977 1363void V3d_View::SetZSize(const Standard_Real Size)
1364{
7fd59977 1365 Standard_Real Zmax = Size/2.;
1366
b5ac8292 1367 Standard_Real aDistance = myCamera->Distance();
1368
7fd59977 1369 if( Size <= 0. ) {
b5ac8292 1370 Zmax = aDistance;
7fd59977 1371 }
7fd59977 1372
b5ac8292 1373 Standard_Real Front = MyViewContext.ZClippingFrontPlane();
1374 Standard_Real Back = MyViewContext.ZClippingBackPlane();
7fd59977 1375
197ac94e 1376 // ShortReal precision factor used to add meaningful tolerance to
1377 // ZNear, ZFar values in order to avoid equality after type conversion
1378 // to ShortReal matrices type.
1379 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1380
1381 Standard_Real aZFar = Zmax + aDistance * 2.0;
1382 Standard_Real aZNear = -Zmax + aDistance;
1383 aZNear -= Abs (aZNear) * aPrecision;
1384 aZFar += Abs (aZFar) * aPrecision;
1385
1386 if (!myCamera->IsOrthographic())
1387 {
1388 if (aZFar < aPrecision)
1389 {
1390 // Invalid case when both values are negative
1391 aZNear = aPrecision;
1392 aZFar = aPrecision * 2.0;
1393 }
1394 else if (aZNear < Abs (aZFar) * aPrecision)
1395 {
1396 // Z is less than 0.0, try to fix it using any appropriate z-scale
1397 aZNear = Abs (aZFar) * aPrecision;
1398 }
1399 }
1400
1401 // If range is too small
1402 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1403 {
1404 aZFar = aZNear + Abs (aZFar) * aPrecision;
1405 }
1406
1407 myCamera->SetZRange (aZNear, aZFar);
7fd59977 1408
b5ac8292 1409 if (MyViewContext.FrontZClippingIsOn() ||
1410 MyViewContext.BackZClippingIsOn())
b8ddfc2f 1411 {
b5ac8292 1412 MyViewContext.SetZClippingFrontPlane (Front);
1413 MyViewContext.SetZClippingBackPlane (Back);
1414 MyView->SetContext (MyViewContext);
b8ddfc2f 1415 }
7fd59977 1416}
1417
197ac94e 1418//=============================================================================
1419//function : SetZoom
1420//purpose :
1421//=============================================================================
7fd59977 1422void V3d_View::SetZoom(const Standard_Real Coef,const Standard_Boolean Start)
1423{
6942f04a 1424 V3d_BadValue_Raise_if( Coef <= 0.,"V3d_View::SetZoom, bad coefficient");
7fd59977 1425
b5ac8292 1426 if (Start)
1427 {
1428 myCamStartOpEye = myCamera->Eye();
1429 myCamStartOpCenter = myCamera->Center();
7fd59977 1430 }
1431
b5ac8292 1432 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
1433 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
1434
7fd59977 1435 // ensure that zoom will not be too small or too big
1436 Standard_Real coef = Coef;
b5ac8292 1437 if (aViewWidth < coef * Precision::Confusion())
1438 {
1439 coef = aViewWidth / Precision::Confusion();
1440 }
1441 else if (aViewWidth > coef * 1e12)
1442 {
1443 coef = aViewWidth / 1e12;
1444 }
1445 if (aViewHeight < coef * Precision::Confusion())
1446 {
1447 coef = aViewHeight / Precision::Confusion();
1448 }
1449 else if (aViewHeight > coef * 1e12)
1450 {
1451 coef = aViewHeight / 1e12;
1452 }
1453
b5ac8292 1454 myCamera->SetEye (myCamStartOpEye);
1455 myCamera->SetCenter (myCamStartOpCenter);
1456 myCamera->SetScale (myCamera->Scale() / Coef);
1457 AutoZFit();
b5ac8292 1458
7fd59977 1459 ImmediateUpdate();
1460}
1461
197ac94e 1462//=============================================================================
1463//function : SetScale
1464//purpose :
1465//=============================================================================
b8ddfc2f 1466void V3d_View::SetScale( const Standard_Real Coef )
1467{
6942f04a 1468 V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
7fd59977 1469
b5ac8292 1470 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
1471
b5ac8292 1472 // Strange behavior for the sake of compatibility.
1473 if (!aDefaultCamera.IsNull())
1474 {
1475 myCamera->SetAspect (aDefaultCamera->Aspect());
1476 Standard_Real aDefaultScale = aDefaultCamera->Scale();
1477 myCamera->SetScale (aDefaultScale / Coef);
1478 }
1479 else
1480 {
1481 myCamera->SetScale (myCamera->Scale() / Coef);
1482 }
1483
1484 AutoZFit();
b5ac8292 1485
7fd59977 1486 ImmediateUpdate();
7fd59977 1487}
1488
197ac94e 1489//=============================================================================
1490//function : SetAxialScale
1491//purpose :
1492//=============================================================================
b8ddfc2f 1493void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1494{
6942f04a 1495 V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
7fd59977 1496
197ac94e 1497 myCamera->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
b5ac8292 1498 AutoZFit();
7fd59977 1499}
1500
197ac94e 1501//=============================================================================
1502//function : FitAll
1503//purpose :
1504//=============================================================================
1505void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
7fd59977 1506{
197ac94e 1507 Standard_ASSERT_RAISE (theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1508
1509 if (MyView->NumberOfDisplayedStructures() == 0)
1510 {
1511 return;
1512 }
35617823 1513
197ac94e 1514 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
1515 MyView->MinMaxValues (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1516 gp_XYZ aMin (aXmin, aYmin, aZmin);
1517 gp_XYZ aMax (aXmax, aYmax, aZmax);
35617823 1518
197ac94e 1519 if (!FitMinMax (myCamera, aMin, aMax, theMargin, 10.0 * Precision::Confusion()))
35617823 1520 {
35617823
K
1521 return;
1522 }
7fd59977 1523
b5ac8292 1524 AutoZFit();
b5ac8292 1525
197ac94e 1526 if (myImmediateUpdate || theToUpdate)
35617823 1527 {
b5ac8292 1528 Update();
35617823 1529 }
b5ac8292 1530}
35617823 1531
197ac94e 1532//=============================================================================
b5ac8292 1533//function : AutoZFit
1534//purpose :
197ac94e 1535//=============================================================================
b5ac8292 1536void V3d_View::AutoZFit()
1537{
197ac94e 1538 if (!AutoZFitMode())
35617823 1539 {
197ac94e 1540 return;
b5ac8292 1541 }
35617823 1542
197ac94e 1543 ZFitAll (myAutoZFitScaleFactor);
1544}
7fd59977 1545
197ac94e 1546//=============================================================================
1547//function : ZFitAll
1548//purpose :
1549//=============================================================================
1550void V3d_View::ZFitAll (const Standard_Real theScaleFactor)
1551{
1552 Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
1553
1554 // Method changes ZNear and ZFar planes of camera so as to fit the graphical structures
1555 // by their real boundaries (computed ignoring infinite flag) into the viewing volume.
1556 // In addition to the graphical boundaries, the usual min max used for fitting perspective
1557 // camera. To avoid numeric errors for perspective camera the negative ZNear values are
1558 // fixed using tolerance distance, relative to boundaries size. The tolerance distance
1559 // should be computed using information on boundaries of primary application actors,
1560 // (e.g. representing the displayed model) - to ensure that they are not unreasonably clipped.
1561
1562 Standard_Real aMinMax[6]; // applicative min max boundaries
1563 View()->MinMaxValues (aMinMax[0], aMinMax[1], aMinMax[2],
1564 aMinMax[3], aMinMax[4], aMinMax[5],
1565 Standard_False);
1566
1567 Standard_Real aGraphicBB[6]; // real graphical boundaries (not accounting infinite flag).
1568 View()->MinMaxValues (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2],
1569 aGraphicBB[3], aGraphicBB[4], aGraphicBB[5],
1570 Standard_True);
1571
1572 // Check if anything can be adjusted
b5ac8292 1573 Standard_Real aLim = (ShortRealLast() - 1.0);
197ac94e 1574 if (Abs (aGraphicBB[0]) > aLim || Abs (aGraphicBB[1]) > aLim || Abs (aGraphicBB[2]) > aLim ||
1575 Abs (aGraphicBB[3]) > aLim || Abs (aGraphicBB[4]) > aLim || Abs (aGraphicBB[5]) > aLim)
b5ac8292 1576 {
1577 SetZSize (0.0);
1578 ImmediateUpdate();
1579 return;
1580 }
7fd59977 1581
197ac94e 1582 // Measure depth of boundary points from camera eye
1583 gp_Pnt aPntsToMeasure[16] =
1584 {
1585 gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[2]),
1586 gp_Pnt (aMinMax[0], aMinMax[1], aMinMax[5]),
1587 gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[2]),
1588 gp_Pnt (aMinMax[0], aMinMax[4], aMinMax[5]),
1589 gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[2]),
1590 gp_Pnt (aMinMax[3], aMinMax[1], aMinMax[5]),
1591 gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[2]),
1592 gp_Pnt (aMinMax[3], aMinMax[4], aMinMax[5]),
1593
1594 gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[2]),
1595 gp_Pnt (aGraphicBB[0], aGraphicBB[1], aGraphicBB[5]),
1596 gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[2]),
1597 gp_Pnt (aGraphicBB[0], aGraphicBB[4], aGraphicBB[5]),
1598 gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[2]),
1599 gp_Pnt (aGraphicBB[3], aGraphicBB[1], aGraphicBB[5]),
1600 gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[2]),
1601 gp_Pnt (aGraphicBB[3], aGraphicBB[4], aGraphicBB[5])
1602 };
1603
1604 // Camera eye plane
1605 gp_Dir aCamDir = myCamera->Direction();
1606 gp_Pnt aCamEye = myCamera->Eye();
1607 gp_Pln aCamPln (aCamEye, aCamDir);
1608
1609 Standard_Real aModelMinDist = RealLast();
1610 Standard_Real aModelMaxDist = RealFirst();
1611 Standard_Real aGraphicMinDist = RealLast();
1612 Standard_Real aGraphicMaxDist = RealFirst();
1613
1614 const gp_XYZ& anAxialScale = myCamera->AxialScale();
1615
1616 // Get minimum and maximum distances to the eye plane
1617 for (Standard_Integer aPntIt = 0; aPntIt < 16; ++aPntIt)
b5ac8292 1618 {
197ac94e 1619 gp_Pnt aMeasurePnt = aPntsToMeasure[aPntIt];
1620
1621 if (Abs (aMeasurePnt.X()) > aLim || Abs (aMeasurePnt.Y()) > aLim || Abs (aMeasurePnt.Z()) > aLim)
1622 {
1623 continue;
1624 }
b5ac8292 1625
197ac94e 1626 aMeasurePnt = gp_Pnt (aMeasurePnt.X() * anAxialScale.X(),
1627 aMeasurePnt.Y() * anAxialScale.Y(),
1628 aMeasurePnt.Z() * anAxialScale.Z());
7fd59977 1629
197ac94e 1630 Standard_Real aDistance = aCamPln.Distance (aMeasurePnt);
35617823 1631
197ac94e 1632 // Check if the camera is intruded into the scene
1633 if (aCamDir.IsOpposite (gp_Vec (aCamEye, aMeasurePnt), M_PI * 0.5))
35617823 1634 {
b5ac8292 1635 aDistance *= -1;
35617823 1636 }
35617823 1637
197ac94e 1638 Standard_Real& aChangeMinDist = aPntIt >= 8 ? aGraphicMinDist : aModelMinDist;
1639 Standard_Real& aChangeMaxDist = aPntIt >= 8 ? aGraphicMaxDist : aModelMaxDist;
1640 aChangeMinDist = Min (aDistance, aChangeMinDist);
1641 aChangeMaxDist = Max (aDistance, aChangeMaxDist);
35617823 1642 }
7fd59977 1643
197ac94e 1644 // Compute depth of bounding box center
1645 Standard_Real aMidDepth = (aGraphicMinDist + aGraphicMaxDist) * 0.5;
1646 Standard_Real aHalfDepth = (aGraphicMaxDist - aGraphicMinDist) * 0.5;
7fd59977 1647
197ac94e 1648 // ShortReal precision factor used to add meaningful tolerance to
1649 // ZNear, ZFar values in order to avoid equality after type conversion
1650 // to ShortReal matrices type.
1651 const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
7fd59977 1652
197ac94e 1653 // Compute enlarged or shrank near and far z ranges
1654 Standard_Real aZNear = aMidDepth - aHalfDepth * theScaleFactor;
1655 Standard_Real aZFar = aMidDepth + aHalfDepth * theScaleFactor;
1656 aZNear -= Abs (aZNear) * aPrecision;
1657 aZFar += Abs (aZFar) * aPrecision;
7fd59977 1658
197ac94e 1659 if (!myCamera->IsOrthographic())
b5ac8292 1660 {
197ac94e 1661 if (aZFar >= aPrecision)
1662 {
1663 // To avoid numeric errors... (See comments in the beginning of the method).
1664 // Choose between model distance and graphical distance, as the model boundaries
1665 // might be infinite if all structures have infinite flag.
1666 const Standard_Real aGraphicDepth = aGraphicMaxDist >= aGraphicMinDist
1667 ? aGraphicMaxDist - aGraphicMinDist : RealLast();
7fd59977 1668
197ac94e 1669 const Standard_Real aModelDepth = aModelMaxDist >= aModelMinDist
1670 ? aModelMaxDist - aModelMinDist : RealLast();
1671
1672 const Standard_Real aMinDepth = Min (aModelDepth, aGraphicDepth);
1673 const Standard_Real aZTolerance =
1674 Max (Abs (aMinDepth) * aPrecision, aPrecision);
1675
1676 if (aZNear < aZTolerance)
1677 {
1678 aZNear = aZTolerance;
1679 }
1680 }
1681 else // aZFar < aPrecision - Invalid case when both ZNear and ZFar are negative
b5ac8292 1682 {
197ac94e 1683 aZNear = aPrecision;
1684 aZFar = aPrecision * 2.0;
7fd59977 1685 }
b5ac8292 1686 }
197ac94e 1687
1688 // If range is too small
1689 if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
b5ac8292 1690 {
197ac94e 1691 aZFar = aZNear + Abs (aZFar) * aPrecision;
b5ac8292 1692 }
7fd59977 1693
197ac94e 1694 myCamera->SetZRange (aZNear, aZFar);
b5ac8292 1695
1696 ImmediateUpdate();
7fd59977 1697}
1698
197ac94e 1699//=============================================================================
1700//function : DepthFitAll
1701//purpose :
1702//=============================================================================
7fd59977 1703void V3d_View::DepthFitAll(const Quantity_Coefficient Aspect,
1704 const Quantity_Coefficient Margin)
1705{
1706 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1707 Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
b5ac8292 1708 Standard_Real Dx,Dy,Dz,Size;
7fd59977 1709
1710 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
1711
b5ac8292 1712 if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
7fd59977 1713 ImmediateUpdate();
1714 return ;
1715 }
1716
7fd59977 1717 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
1718
1719 Standard_Real LIM = ShortRealLast() -1.;
1720 if (Abs(Xmin) > LIM || Abs(Ymin) > LIM || Abs(Zmin) > LIM
1721 || Abs(Xmax) > LIM || Abs(Ymax) > LIM || Abs(Zmax) > LIM ) {
1722 ImmediateUpdate();
1723 return ;
1724 }
1725
7fd59977 1726 if (Xmin == Xmax && Ymin == Ymax && Zmin == Zmax) {
1727 ImmediateUpdate();
1728 return ;
1729 }
1730 MyView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
1731 MyView->Projects(Xmax,Ymax,Zmax,U1,V1,W1) ;
1732 Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1733 Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1734 Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1735 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
1736 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1737 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1738 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1739 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
1740 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1741 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1742 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1743 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
1744 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1745 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1746 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1747 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
1748 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1749 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1750 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1751 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
1752 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1753 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1754 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1755 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
1756 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1757 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1758 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1759
1760 // Adjust Z size
1761 Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1762 Dz = 2.*Wmax + Margin * Wmax;
1763
1764 // Compute depth value
1765 Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1766 Dx += Margin * Dx; Dy += Margin * Dy;
1767 Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1768 if( Size > 0. ) {
1769 SetZSize(Size) ;
1770 SetDepth( Aspect * Size / 2.);
1771 }
1772
1773 ImmediateUpdate();
1774}
1775
197ac94e 1776//=============================================================================
1777//function : FitAll
1778//purpose :
1779//=============================================================================
1780void V3d_View::FitAll(const Standard_Real theMinXv,
1781 const Standard_Real theMinYv,
1782 const Standard_Real theMaxXv,
1783 const Standard_Real theMaxYv)
b8ddfc2f 1784{
197ac94e 1785 FitAll (MyWindow, theMinXv, theMinYv, theMaxXv, theMaxYv);
7fd59977 1786}
1787
197ac94e 1788//=============================================================================
1789//function : WindowFitAll
1790//purpose :
1791//=============================================================================
1792void V3d_View::WindowFitAll(const Standard_Integer Xmin,
1793 const Standard_Integer Ymin,
1794 const Standard_Integer Xmax,
1795 const Standard_Integer Ymax)
b8ddfc2f 1796{
7fd59977 1797 WindowFit(Xmin,Ymin,Xmax,Ymax);
7fd59977 1798}
b8ddfc2f 1799
197ac94e 1800//=======================================================================
1801//function : WindowFit
1802//purpose :
1803//=======================================================================
1804void V3d_View::WindowFit (const Standard_Integer theMinXp,
1805 const Standard_Integer theMinYp,
1806 const Standard_Integer theMaxXp,
1807 const Standard_Integer theMaxYp)
b8ddfc2f 1808{
197ac94e 1809 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1810
b5ac8292 1811 if (!myCamera->IsOrthographic())
1812 {
1813 // normalize view coordiantes
1814 Standard_Integer aWinWidth, aWinHeight;
1815 MyWindow->Size (aWinWidth, aWinHeight);
7fd59977 1816
b5ac8292 1817 // z coordinate of camera center
1818 Standard_Real aDepth = myCamera->Project (myCamera->Center()).Z();
1819
1820 // camera projection coordinate are in NDC which are normalized [-1, 1]
197ac94e 1821 Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp - 1.0;
1822 Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp - 1.0;
1823 Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1824 Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
b5ac8292 1825
1826 // compute camera panning
1827 gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1828 gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1829 gp_Pnt aPanTo = myCamera->ConvertProj2View (aFitCenter);
1830 gp_Pnt aPanFrom = myCamera->ConvertProj2View (aScreenCenter);
1831 gp_Vec aPanVec (aPanFrom, aPanTo);
1832
b5ac8292 1833 // compute section size
1834 gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1835 gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1836 gp_Pnt aViewBotLeft = myCamera->ConvertProj2View (aFitBotLeft);
1837 gp_Pnt aViewTopRight = myCamera->ConvertProj2View (aFitTopRight);
1838
1839 Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1840 Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1841
197ac94e 1842 Translate (myCamera, aPanVec.X(), -aPanVec.Y());
1843 Scale (myCamera, aUSize, aVSize);
b5ac8292 1844 AutoZFit();
b5ac8292 1845 }
1846 else
1847 {
197ac94e 1848 Standard_Real aX1, aY1, aX2, aY2;
1849 Convert (theMinXp, theMinYp, aX1, aY1);
1850 Convert (theMaxXp, theMaxYp, aX2, aY2);
1851 FitAll (aX1, aY1, aX2, aY2);
b5ac8292 1852 }
197ac94e 1853
1854 SetImmediateUpdate (wasUpdateEnabled);
1855
1856 ImmediateUpdate();
7fd59977 1857}
1858
197ac94e 1859//=======================================================================
1860//function : SetViewMappingDefault
1861//purpose :
1862//=======================================================================
b8ddfc2f 1863void V3d_View::SetViewMappingDefault()
1864{
7fd59977 1865 MyView->SetViewMappingDefault();
b5ac8292 1866
7fd59977 1867 ImmediateUpdate();
1868}
1869
197ac94e 1870//=======================================================================
1871//function : ResetViewMapping
1872//purpose :
1873//=======================================================================
b8ddfc2f 1874void V3d_View::ResetViewMapping()
1875{
7fd59977 1876 MyView->ViewMappingReset();
b5ac8292 1877
7fd59977 1878 Update();
7fd59977 1879}
1880
197ac94e 1881//=======================================================================
1882//function : ConvertToGrid
1883//purpose :
1884//=======================================================================
1885void V3d_View::ConvertToGrid(const Standard_Integer Xp,
1886 const Standard_Integer Yp,
1887 Standard_Real& Xg,
1888 Standard_Real& Yg,
1889 Standard_Real& Zg) const
b5ac8292 1890{
1891 Graphic3d_Vertex aVrp;
1892 Standard_Real anX, anY, aZ;
1893 Convert (Xp, Yp, anX, anY, aZ);
1894 aVrp.SetCoord (anX, anY, aZ);
1895
1896 if( MyViewer->Grid()->IsActive() ) {
1897 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1898 aNewVrp.Coord (Xg,Yg,Zg) ;
1899 } else
1900 aVrp.Coord (Xg,Yg,Zg) ;
1901}
1902
197ac94e 1903//=======================================================================
1904//function : ConvertToGrid
1905//purpose :
1906//=======================================================================
1907void V3d_View::ConvertToGrid(const Standard_Real X,
1908 const Standard_Real Y,
1909 const Standard_Real Z,
1910 Standard_Real& Xg,
1911 Standard_Real& Yg,
1912 Standard_Real& Zg) const
b5ac8292 1913{
1914 if( MyViewer->Grid()->IsActive() ) {
1915 Graphic3d_Vertex aVrp (X,Y,Z) ;
1916 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
1917 aNewVrp.Coord(Xg,Yg,Zg) ;
1918 } else {
1919 Xg = X; Yg = Y; Zg = Z;
1920 }
1921}
1922
197ac94e 1923//=======================================================================
1924//function : Convert
1925//purpose :
1926//=======================================================================
b8ddfc2f 1927Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1928{
b5ac8292 1929 Standard_Integer aDxw, aDyw ;
7fd59977 1930
b5ac8292 1931 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
7fd59977 1932
b5ac8292 1933 MyWindow->Size (aDxw, aDyw);
1934 Standard_Real aValue;
197ac94e 1935
b5ac8292 1936 gp_Pnt aViewDims = myCamera->ViewDimensions();
1937 aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
7fd59977 1938
b5ac8292 1939 return aValue;
7fd59977 1940}
1941
197ac94e 1942//=======================================================================
1943//function : Convert
1944//purpose :
1945//=======================================================================
1946void V3d_View::Convert(const Standard_Integer Xp,
1947 const Standard_Integer Yp,
1948 Standard_Real& Xv,
1949 Standard_Real& Yv) const
b8ddfc2f 1950{
b5ac8292 1951 Standard_Integer aDxw, aDyw;
7fd59977 1952
b5ac8292 1953 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1954
1955 MyWindow->Size (aDxw, aDyw);
1956
1957 gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1958 aPoint = myCamera->ConvertProj2View (aPoint);
7fd59977 1959
b5ac8292 1960 Xv = aPoint.X();
1961 Yv = aPoint.Y();
7fd59977 1962}
1963
197ac94e 1964//=======================================================================
1965//function : Convert
1966//purpose :
1967//=======================================================================
7fd59977 1968Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1969{
b5ac8292 1970 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
1971
1972 Standard_Integer aDxw, aDyw;
1973 MyWindow->Size (aDxw, aDyw);
7fd59977 1974
b5ac8292 1975 gp_Pnt aViewDims = myCamera->ViewDimensions();
1976 Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
7fd59977 1977
b5ac8292 1978 return aValue;
7fd59977 1979}
1980
197ac94e 1981//=======================================================================
1982//function : Convert
1983//purpose :
1984//=======================================================================
1985void V3d_View::Convert(const Standard_Real Xv,
1986 const Standard_Real Yv,
1987 Standard_Integer& Xp,
1988 Standard_Integer& Yp) const
7fd59977 1989{
b5ac8292 1990 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
7fd59977 1991
b5ac8292 1992 Standard_Integer aDxw, aDyw;
1993 MyWindow->Size (aDxw, aDyw);
7fd59977 1994
b5ac8292 1995 gp_Pnt aPoint (Xv, Yv, 0.0);
1996 aPoint = myCamera->ConvertView2Proj (aPoint);
1997 aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
7fd59977 1998
b5ac8292 1999 Xp = RealToInt (aPoint.X());
2000 Yp = RealToInt (aPoint.Y());
7fd59977 2001}
2002
197ac94e 2003//=======================================================================
2004//function : Convert
2005//purpose :
2006//=======================================================================
2007void V3d_View::Convert(const Standard_Integer Xp,
2008 const Standard_Integer Yp,
2009 Standard_Real& X,
2010 Standard_Real& Y,
2011 Standard_Real& Z) const
b8ddfc2f 2012{
b5ac8292 2013 V3d_UnMapped_Raise_if (!MyView->IsDefined(), "view has no window");
2014 Standard_Integer aHeight, aWidth;
2015 MyWindow->Size (aWidth, aHeight);
2016
2017 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
2018 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
2019 Standard_Real aZ = 2.0 * 0.0 - 1.0;
2020
2021 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
2022
2023 X = aResult.X();
2024 Y = aResult.Y();
2025 Z = aResult.Z();
2026
2027 Graphic3d_Vertex aVrp;
2028 aVrp.SetCoord (X, Y, Z);
2029
7fd59977 2030 if( MyViewer->Grid()->IsActive() ) {
b5ac8292 2031 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
2032 aNewVrp.Coord (X, Y, Z) ;
7fd59977 2033 }
7fd59977 2034}
2035
197ac94e 2036//=======================================================================
2037//function : ConvertWithProj
2038//purpose :
2039//=======================================================================
2040void V3d_View::ConvertWithProj(const Standard_Integer Xp,
2041 const Standard_Integer Yp,
2042 Standard_Real& X,
2043 Standard_Real& Y,
2044 Standard_Real& Z,
2045 Standard_Real& Dx,
2046 Standard_Real& Dy,
2047 Standard_Real& Dz) const
7fd59977 2048{
b5ac8292 2049 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
2050 Standard_Integer aHeight, aWidth;
2051 MyWindow->Size (aWidth, aHeight);
7fd59977 2052
b5ac8292 2053 Standard_Real anX = 2.0 * Xp / aWidth - 1.0;
2054 Standard_Real anY = 2.0 * (aHeight - 1 - Yp) / aHeight - 1.0;
2055 Standard_Real aZ = 2.0 * 0.0 - 1.0;
7fd59977 2056
b5ac8292 2057 gp_Pnt aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ));
2058
2059 X = aResult.X();
2060 Y = aResult.Y();
2061 Z = aResult.Z();
2062
2063 Graphic3d_Vertex aVrp;
2064 aVrp.SetCoord (X, Y, Z);
2065
2066 aResult = myCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
2067
2068 Dx = X - aResult.X();
2069 Dy = Y - aResult.Y();
2070 Dz = Z - aResult.Z();
7fd59977 2071
7fd59977 2072 if( MyViewer->Grid()->IsActive() ) {
b5ac8292 2073 Graphic3d_Vertex aNewVrp = Compute (aVrp) ;
2074 aNewVrp.Coord (X, Y, Z) ;
7fd59977 2075 }
2076}
7fd59977 2077
197ac94e 2078//=======================================================================
2079//function : Convert
2080//purpose :
2081//=======================================================================
2082void V3d_View::Convert(const Standard_Real X,
2083 const Standard_Real Y,
2084 const Standard_Real Z,
2085 Standard_Integer& Xp,
2086 Standard_Integer& Yp) const
b8ddfc2f 2087{
b5ac8292 2088 V3d_UnMapped_Raise_if( !MyView->IsDefined(), "view has no window");
2089 Standard_Integer aHeight, aWidth;
2090 MyWindow->Size (aWidth, aHeight);
2091
2092 gp_Pnt aPoint = myCamera->Project (gp_Pnt (X, Y, Z));
2093
2094 Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
2095 Yp = RealToInt ((aPoint.Y() + 1) * 0.5 * aHeight);
7fd59977 2096}
2097
197ac94e 2098//=======================================================================
2099//function : Project
2100//purpose :
2101//=======================================================================
2102void V3d_View::Project(const Standard_Real X,
2103 const Standard_Real Y,
2104 const Standard_Real Z,
2105 Standard_Real &Xp,
2106 Standard_Real &Yp) const
7fd59977 2107{
b5ac8292 2108 Standard_Real Zp;
2109 MyView->Projects (X, Y, Z, Xp, Yp, Zp);
7fd59977 2110}
2111
197ac94e 2112//=======================================================================
2113//function : BackgroundColor
2114//purpose :
2115//=======================================================================
2116void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
2117 Standard_Real& V1,
2118 Standard_Real& V2,
2119 Standard_Real& V3) const
b8ddfc2f 2120{
7fd59977 2121 Quantity_Color C = BackgroundColor() ;
7fd59977 2122 C.Values(V1,V2,V3,Type) ;
2123}
2124
197ac94e 2125//=======================================================================
2126//function : BackgroundColor
2127//purpose :
2128//=======================================================================
b8ddfc2f 2129Quantity_Color V3d_View::BackgroundColor() const
2130{
7fd59977 2131 return MyBackground.Color() ;
2132}
7fd59977 2133
197ac94e 2134//=======================================================================
2135//function : GradientBackgroundColors
2136//purpose :
2137//=======================================================================
b8ddfc2f 2138void V3d_View::GradientBackgroundColors(Quantity_Color& Color1,Quantity_Color& Color2) const
2139{
7fd59977 2140 MyGradientBackground.Colors(Color1, Color2);
2141}
2142
197ac94e 2143//=======================================================================
2144//function : GradientBackground
2145//purpose :
2146//=======================================================================
b8ddfc2f 2147Aspect_GradientBackground V3d_View::GradientBackground() const
2148{
7fd59977 2149 return MyGradientBackground;
2150}
2151
197ac94e 2152//=======================================================================
2153//function : Scale
2154//purpose :
2155//=======================================================================
b8ddfc2f 2156Standard_Real V3d_View::Scale() const
2157{
b5ac8292 2158 Handle(Graphic3d_Camera) aDefaultCamera = MyView->DefaultCamera();
2159
2160 Standard_Real aCameraScale;
2161
2162 // Strange behavior for the sake of compatibility.
2163 if (!aDefaultCamera.IsNull())
2164 {
2165 Standard_Real aDefaultScale = aDefaultCamera->Scale();
2166 aCameraScale = aDefaultScale / myCamera->Scale();
2167 }
2168 else
2169 {
2170 aCameraScale = myCamera->Scale();
2171 }
7fd59977 2172
b5ac8292 2173 return aCameraScale;
7fd59977 2174}
2175
197ac94e 2176//=======================================================================
2177//function : AxialScale
2178//purpose :
2179//=======================================================================
b8ddfc2f 2180void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
2181{
b5ac8292 2182 gp_Pnt anAxialScale = myCamera->AxialScale();
2183 Sx = anAxialScale.X();
2184 Sy = anAxialScale.Y();
2185 Sz = anAxialScale.Z();
7fd59977 2186}
2187
197ac94e 2188//=======================================================================
2189//function : Size
2190//purpose :
2191//=======================================================================
b8ddfc2f 2192void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
2193{
b5ac8292 2194 gp_Pnt aViewDims = myCamera->ViewDimensions();
7fd59977 2195
b5ac8292 2196 Width = aViewDims.X();
2197 Height = aViewDims.Y();
7fd59977 2198}
2199
197ac94e 2200//=======================================================================
2201//function : ZSize
2202//purpose :
2203//=======================================================================
b8ddfc2f 2204Standard_Real V3d_View::ZSize() const
2205{
b5ac8292 2206 gp_Pnt aViewDims = myCamera->ViewDimensions();
7fd59977 2207
b5ac8292 2208 return aViewDims.Z();
7fd59977 2209}
2210
197ac94e 2211//=======================================================================
2212//function : MinMax
2213//purpose :
2214//=======================================================================
2215Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
2216 Standard_Real& Vmin,
2217 Standard_Real& Umax,
2218 Standard_Real& Vmax) const
b8ddfc2f 2219{
7fd59977 2220 Standard_Real Wmin,Wmax,U,V,W ;
2221 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
2222 // CAL 6/11/98
2223 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2224
2225 if( Nstruct ) {
2226 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
2227 MyView->Projects(Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
2228 MyView->Projects(Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
2229 MyView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
2230 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2231 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2232 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2233 MyView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
2234 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2235 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2236 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2237 MyView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
2238 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2239 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2240 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2241 MyView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
2242 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2243 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2244 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2245 MyView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
2246 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2247 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2248 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2249 MyView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
2250 Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
2251 Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
2252 Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
2253 }
2254 return Nstruct ;
2255}
2256
197ac94e 2257//=======================================================================
2258//function : MinMax
2259//purpose :
2260//=======================================================================
2261Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
2262 Standard_Real& Ymin,
2263 Standard_Real& Zmin,
2264 Standard_Real& Xmax,
2265 Standard_Real& Ymax,
2266 Standard_Real& Zmax) const
b8ddfc2f 2267{
7fd59977 2268 // CAL 6/11/98
2269 // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
2270 Standard_Integer Nstruct = MyView->NumberOfDisplayedStructures() ;
2271
2272 if( Nstruct ) {
2273 MyView->MinMaxValues(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax) ;
2274 }
2275 return Nstruct ;
2276}
2277
197ac94e 2278//=======================================================================
2279//function : Gravity
2280//purpose :
2281//=======================================================================
b8ddfc2f 2282Standard_Integer V3d_View::Gravity(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2283{
b5ac8292 2284 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax;
7fd59977 2285 Standard_Integer Nstruct,Npoint ;
2286 Graphic3d_MapOfStructure MySetOfStructures;
2287
2288 MyView->DisplayedStructures (MySetOfStructures);
2289 Nstruct = MySetOfStructures.Extent() ;
2290
2291 Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ;
2292
7fd59977 2293 Npoint = 0 ; X = Y = Z = 0. ;
b5ac8292 2294 for (; MyIterator.More(); MyIterator.Next())
2295 {
2296 const Handle(Graphic3d_Structure)& aStruct = MyIterator.Key();
2297 if (!aStruct->IsEmpty())
2298 {
2299 aStruct->MinMaxValues (Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
2300
197ac94e 2301 // Check bounding box for validness
2302 Standard_Real aLim = (ShortRealLast() - 1.0);
2303 if (Abs (Xmin) > aLim || Abs (Ymin) > aLim || Abs (Zmin) > aLim ||
2304 Abs (Xmax) > aLim || Abs (Ymax) > aLim || Abs (Zmax) > aLim)
2305 {
2306 continue;
2307 }
2308
b5ac8292 2309 // use camera projection to find gravity point
2310 gp_Pnt aPnts[8] = {
2311 gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2312 gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2313 gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2314 gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax) };
2315
2316 for (Standard_Integer aPntIt = 0; aPntIt < 8; ++aPntIt)
2317 {
2318 const gp_Pnt& aBndPnt = aPnts[aPntIt];
2319
2320 gp_Pnt aProjected = myCamera->Project (aBndPnt);
2321 const Standard_Real& U = aProjected.X();
2322 const Standard_Real& V = aProjected.Y();
2323 if (Abs(U) <= 1.0 && Abs(V) <= 1.0)
2324 {
2325 Npoint++;
2326 X += aBndPnt.X();
2327 Y += aBndPnt.Y();
2328 Z += aBndPnt.Z();
7fd59977 2329 }
b5ac8292 2330 }
7fd59977 2331 }
2332 }
2333 if( Npoint > 0 ) {
2334 X /= Npoint ; Y /= Npoint ; Z /= Npoint ;
2335 }
2336
2337 return Nstruct ;
2338}
2339
197ac94e 2340//=======================================================================
2341//function : Eye
2342//purpose :
2343//=======================================================================
b8ddfc2f 2344void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2345{
b5ac8292 2346 gp_Pnt aCameraEye = myCamera->Eye();
2347 X = aCameraEye.X();
2348 Y = aCameraEye.Y();
2349 Z = aCameraEye.Z();
7fd59977 2350}
2351
197ac94e 2352//=============================================================================
2353//function : FocalReferencePoint
2354//purpose :
2355//=============================================================================
b8ddfc2f 2356void V3d_View::FocalReferencePoint(Standard_Real& X, Standard_Real& Y,Standard_Real& Z) const
2357{
b5ac8292 2358 Eye (X,Y,Z);
7fd59977 2359}
2360
197ac94e 2361//=============================================================================
2362//function : ProjReferenceAxe
2363//purpose :
2364//=============================================================================
2365void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2366 const Standard_Integer Ypix,
2367 Standard_Real& XP,
2368 Standard_Real& YP,
2369 Standard_Real& ZP,
2370 Standard_Real& VX,
2371 Standard_Real& VY,
2372 Standard_Real& VZ) const
b8ddfc2f 2373{
7fd59977 2374 Standard_Real Xo,Yo,Zo;
2375
b5ac8292 2376 Convert (Xpix, Ypix, XP, YP, ZP);
2377 if ( Type() == V3d_PERSPECTIVE )
2378 {
2379 FocalReferencePoint (Xo,Yo,Zo);
7fd59977 2380 VX = Xo - XP;
2381 VY = Yo - YP;
2382 VZ = Zo - ZP;
2383 }
b5ac8292 2384 else
2385 {
2386 Proj (VX,VY,VZ);
7fd59977 2387 }
2388}
2389
197ac94e 2390//=============================================================================
2391//function : Depth
2392//purpose :
2393//=============================================================================
b8ddfc2f 2394Standard_Real V3d_View::Depth() const
2395{
b5ac8292 2396 return myCamera->Distance();
7fd59977 2397}
2398
197ac94e 2399//=============================================================================
2400//function : Proj
2401//purpose :
2402//=============================================================================
b8ddfc2f 2403void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2404{
b5ac8292 2405 gp_Dir aCameraDir = myCamera->Direction().Reversed();
2406 Dx = aCameraDir.X();
2407 Dy = aCameraDir.Y();
2408 Dz = aCameraDir.Z();
7fd59977 2409}
2410
197ac94e 2411//=============================================================================
2412//function : At
2413//purpose :
2414//=============================================================================
b8ddfc2f 2415void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2416{
b5ac8292 2417 gp_Pnt aCameraCenter = myCamera->Center();
2418 X = aCameraCenter.X();
2419 Y = aCameraCenter.Y();
2420 Z = aCameraCenter.Z();
7fd59977 2421}
2422
197ac94e 2423//=============================================================================
2424//function : Up
2425//purpose :
2426//=============================================================================
b8ddfc2f 2427void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2428{
b5ac8292 2429 gp_Dir aCameraUp = myCamera->Up();
2430 Vx = aCameraUp.X();
2431 Vy = aCameraUp.Y();
2432 Vz = aCameraUp.Z();
7fd59977 2433}
2434
197ac94e 2435//=============================================================================
2436//function : Twist
2437//purpose :
2438//=============================================================================
b8ddfc2f 2439Standard_Real V3d_View::Twist() const
2440{
7fd59977 2441 Standard_Real Xup,Yup,Zup,Xpn,Ypn,Zpn,X0,Y0,Z0 ;
2442 Standard_Real pvx,pvy,pvz,pvn,sca,angle ;
b5ac8292 2443 Graphic3d_Vector Xaxis,Yaxis,Zaxis ;
7fd59977 2444 Standard_Boolean TheStatus ;
2445
b5ac8292 2446 gp_Dir aReferencePlane (myCamera->Direction().Reversed());
2447 gp_Dir anUp;
2448
2449 Proj(Xpn,Ypn,Zpn);
2450 anUp = gp_Dir (0.,0.,1.) ;
2451 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
7fd59977 2452 if( !TheStatus ) {
b5ac8292 2453 anUp = gp_Dir (0.,1.,0.) ;
2454 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
7fd59977 2455 }
2456 if( !TheStatus ) {
b5ac8292 2457 anUp = gp_Dir (1.,0.,0.) ;
2458 TheStatus = ScreenAxis (aReferencePlane, anUp,Xaxis,Yaxis,Zaxis) ;
7fd59977 2459 }
2460 Yaxis.Coord(X0,Y0,Z0) ;
b5ac8292 2461
2462 Up(Xup,Yup,Zup) ;
7fd59977 2463 /* Compute Cross Vector From Up & Origin */
2464 pvx = Y0*Zup - Z0*Yup ;
2465 pvy = Z0*Xup - X0*Zup ;
2466 pvz = X0*Yup - Y0*Xup ;
2467 pvn = pvx*pvx + pvy*pvy + pvz*pvz ;
2468 sca = X0*Xup + Y0*Yup + Z0*Zup ;
2469 /* Compute Angle */
2470 angle = Sqrt(pvn) ;
2471 if( angle > 1. ) angle = 1. ;
2472 else if( angle < -1. ) angle = -1. ;
2473 angle = asin(angle) ;
c6541a0c
D
2474 if( sca < 0. ) angle = M_PI - angle ;
2475 if( angle > 0. && angle < M_PI ) {
7fd59977 2476 sca = pvx*Xpn + pvy*Ypn + pvz*Zpn ;
2477 if( sca < 0. ) angle = DEUXPI - angle ;
2478 }
2479 return angle ;
2480}
2481
197ac94e 2482//=============================================================================
2483//function : ShadingModel
2484//purpose :
2485//=============================================================================
b8ddfc2f 2486V3d_TypeOfShadingModel V3d_View::ShadingModel() const
2487{
7fd59977 2488 V3d_TypeOfShadingModel SM = (V3d_TypeOfShadingModel)MyViewContext.Model() ;
2489 return SM ;
2490}
2491
197ac94e 2492//=============================================================================
2493//function : SurfaceDetail
2494//purpose :
2495//=============================================================================
b8ddfc2f 2496V3d_TypeOfSurfaceDetail V3d_View::SurfaceDetail() const
2497{
7fd59977 2498 V3d_TypeOfSurfaceDetail SM = (V3d_TypeOfSurfaceDetail)MyViewContext.SurfaceDetail() ;
2499 return SM ;
2500}
2501
197ac94e 2502//=============================================================================
2503//function : TextureEnv
2504//purpose :
2505//=============================================================================
b8ddfc2f 2506Handle_Graphic3d_TextureEnv V3d_View::TextureEnv() const
2507{
7fd59977 2508 Handle(Graphic3d_TextureEnv) SM = MyViewContext.TextureEnv() ;
2509 return SM ;
2510}
2511
197ac94e 2512//=============================================================================
2513//function : Visualization
2514//purpose :
2515//=============================================================================
b8ddfc2f 2516V3d_TypeOfVisualization V3d_View::Visualization() const
2517{
7fd59977 2518 V3d_TypeOfVisualization V =
2519 (V3d_TypeOfVisualization)MyViewContext.Visualization() ;
2520 return V ;
2521}
2522
197ac94e 2523//=============================================================================
2524//function : Antialiasing
2525//purpose :
2526//=============================================================================
b8ddfc2f 2527Standard_Boolean V3d_View::Antialiasing() const
2528{
7fd59977 2529 Standard_Boolean A = MyViewContext.AliasingIsOn() ;
2530 return A ;
2531}
2532
197ac94e 2533//=============================================================================
2534//function : Viewer
2535//purpose :
2536//=============================================================================
b8ddfc2f 2537Handle(V3d_Viewer) V3d_View::Viewer() const
2538{
7fd59977 2539 return MyViewer ;
2540}
2541
197ac94e 2542//=============================================================================
2543//function : IfWindow
2544//purpose :
2545//=============================================================================
b8ddfc2f 2546Standard_Boolean V3d_View::IfWindow() const
2547{
7fd59977 2548 Standard_Boolean TheStatus = MyView->IsDefined() ;
2549 return TheStatus ;
2550}
2551
197ac94e 2552//=============================================================================
2553//function : Window
2554//purpose :
2555//=============================================================================
b8ddfc2f 2556Handle(Aspect_Window) V3d_View::Window() const
2557{
7fd59977 2558 return MyWindow;
2559}
2560
197ac94e 2561//=============================================================================
2562//function : Type
2563//purpose :
2564//=============================================================================
b8ddfc2f 2565V3d_TypeOfView V3d_View::Type() const
2566{
b5ac8292 2567 return myCamera->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
7fd59977 2568}
2569
197ac94e 2570//=============================================================================
2571//function : SetFocale
2572//purpose :
2573//=============================================================================
b8ddfc2f 2574void V3d_View::SetFocale( const Standard_Real focale )
2575{
b5ac8292 2576 if (myCamera->IsOrthographic())
2577 {
2578 return;
7fd59977 2579 }
b5ac8292 2580
2581 Standard_Real aFOVyRad = ATan (focale / (myCamera->Distance() * 2.0));
2582
2583 myCamera->SetFOVy (aFOVyRad * (360 / M_PI));
7fd59977 2584
2585 ImmediateUpdate();
2586}
2587
197ac94e 2588//=============================================================================
2589//function : Focale
2590//purpose :
2591//=============================================================================
b5ac8292 2592Standard_Real V3d_View::Focale() const
b8ddfc2f 2593{
b5ac8292 2594 if (myCamera->IsOrthographic())
2595 {
2596 return 0.0;
7fd59977 2597 }
b5ac8292 2598
2599 return myCamera->Distance() * 2.0 * Tan(myCamera->FOVy() * M_PI / 360.0);
7fd59977 2600}
2601
197ac94e 2602//=============================================================================
2603//function : View
2604//purpose :
2605//=============================================================================
7fd59977 2606Handle(Visual3d_View) V3d_View::View() const
2607{
2608 return MyView ;
2609}
2610
197ac94e 2611//=============================================================================
2612//function : ScreenAxis
2613//purpose :
2614//=============================================================================
b5ac8292 2615Standard_Boolean V3d_View::ScreenAxis( const gp_Dir &Vpn, const gp_Dir &Vup, Graphic3d_Vector &Xaxe, Graphic3d_Vector &Yaxe, Graphic3d_Vector &Zaxe)
2616{
2617 Standard_Real Xpn, Ypn, Zpn, Xup, Yup, Zup;
2618 Standard_Real dx1, dy1, dz1, xx, yy, zz;
2619
2620 Xpn = Vpn.X(); Ypn = Vpn.Y(); Zpn = Vpn.Z();
2621 Xup = Vup.X(); Yup = Vup.Y(); Zup = Vup.Z();
2622 xx = Yup*Zpn - Zup*Ypn;
2623 yy = Zup*Xpn - Xup*Zpn;
2624 zz = Xup*Ypn - Yup*Xpn;
2625 Xaxe.SetCoord (xx, yy, zz);
2626 if (Xaxe.LengthZero()) return Standard_False;
2627 Xaxe.Normalize();
2628 Xaxe.Coord(dx1, dy1, dz1);
2629 xx = Ypn*dz1 - Zpn*dy1;
2630 yy = Zpn*dx1 - Xpn*dz1;
2631 zz = Xpn*dy1 - Ypn*dx1;
2632 Yaxe.SetCoord (xx, yy, zz) ;
2633 if (Yaxe.LengthZero()) return Standard_False;
2634 Yaxe.Normalize();
2635
2636 Zaxe.SetCoord (Xpn, Ypn, Zpn);
2637 Zaxe.Normalize();
7fd59977 2638 return Standard_True;
2639}
2640
197ac94e 2641//=============================================================================
2642//function : TrsPoint
2643//purpose :
2644//=============================================================================
b8ddfc2f 2645Graphic3d_Vertex V3d_View::TrsPoint( const Graphic3d_Vertex &P, const TColStd_Array2OfReal &Matrix )
2646{
7fd59977 2647 Graphic3d_Vertex PP ;
2648 Standard_Real X,Y,Z,XX,YY,ZZ ;
2649
2650 // CAL. S3892
2651 Standard_Integer lr, ur, lc, uc;
2652 lr = Matrix.LowerRow ();
2653 ur = Matrix.UpperRow ();
2654 lc = Matrix.LowerCol ();
2655 uc = Matrix.UpperCol ();
b5ac8292 2656 if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4) ) {
7fd59977 2657 P.Coord(X,Y,Z) ;
2658 PP.SetCoord(X,Y,Z) ;
2659 return PP ;
2660 }
2661 P.Coord(X,Y,Z) ;
2662 XX = (Matrix(lr,lc+3) + X*Matrix(lr,lc) + Y*Matrix(lr,lc+1)+
2663 Z*Matrix(lr,lc+2))/Matrix(lr+3,lc+3) ;
2664
2665 YY = (Matrix(lr+1,lc+3) + X*Matrix(lr+1,lc) + Y*Matrix(lr+1,lc+1) +
2666 Z*Matrix(lr+1,lc+2))/Matrix(lr+3,lc+3) ;
2667
2668 ZZ = (Matrix(lr+2,lc+3) + X*Matrix(lr+2,lc) + Y*Matrix(lr+2,lc+1) +
2669 Z*Matrix(lr+2,lc+2))/Matrix(lr+3,lc+3) ;
2670 PP.SetCoord(XX,YY,ZZ) ;
2671 return PP ;
2672}
2673
197ac94e 2674//=======================================================================
2675//function : Pan
2676//purpose :
2677//=======================================================================
2678void V3d_View::Pan (const Standard_Integer theDXp,
2679 const Standard_Integer theDYp,
2680 const Quantity_Factor theZoomFactor,
2681 const Standard_Boolean theToStart)
b8ddfc2f 2682{
197ac94e 2683 Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
7fd59977 2684}
2685
197ac94e 2686//=======================================================================
2687//function : Panning
2688//purpose :
2689//=======================================================================
2690void V3d_View::Panning (const Standard_Real theDXv,
2691 const Standard_Real theDYv,
2692 const Quantity_Factor theZoomFactor,
2693 const Standard_Boolean theToStart)
7fd59977 2694{
197ac94e 2695 Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
7fd59977 2696
197ac94e 2697 if (theToStart)
2698 {
2699 myCamStartOpEye = myCamera->Eye();
2700 myCamStartOpCenter = myCamera->Center();
7fd59977 2701 }
197ac94e 2702
2703 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2704
2705 gp_Pnt aViewDims = myCamera->ViewDimensions();
2706
2707 myCamera->SetEye (myCamStartOpEye);
2708 myCamera->SetCenter (myCamStartOpCenter);
2709 Translate (myCamera, -theDXv, -theDYv);
2710 Scale (myCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2711
2712 SetImmediateUpdate (wasUpdateEnabled);
2713
2714 ImmediateUpdate();
7fd59977 2715}
2716
197ac94e 2717//=======================================================================
2718//function : Zoom
2719//purpose :
2720//=======================================================================
2721void V3d_View::Zoom (const Standard_Integer theXp1,
2722 const Standard_Integer theYp1,
2723 const Standard_Integer theXp2,
2724 const Standard_Integer theYp2)
2725{
2726 Standard_Integer aDx = theXp2 - theXp1;
2727 Standard_Integer aDy = theYp2 - theYp1;
2728 if (aDx != 0 || aDy != 0)
2729 {
2730 Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2731 aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2732 SetZoom (aCoeff, Standard_True);
2733 }
7fd59977 2734}
2735
197ac94e 2736//=======================================================================
2737//function : StartZoomAtPoint
2738//purpose :
2739//=======================================================================
2740void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2741 const Standard_Integer theYp)
7fd59977 2742{
197ac94e 2743 MyZoomAtPointX = theXp;
2744 MyZoomAtPointY = theYp;
7fd59977 2745}
2746
197ac94e 2747//=======================================================================
2748//function : ZoomAtPoint
2749//purpose :
2750//=======================================================================
2751void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2752 const Standard_Integer theMouseStartY,
2753 const Standard_Integer theMouseEndX,
2754 const Standard_Integer theMouseEndY)
7fd59977 2755{
197ac94e 2756 Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
7fd59977 2757
197ac94e 2758 // zoom
2759 Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2760 Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2761 aDZoom = (aDxy > 0.0) ? aDZoom : 1.0 / aDZoom;
7fd59977 2762
197ac94e 2763 V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
7fd59977 2764
197ac94e 2765 Standard_Real aViewWidth = myCamera->ViewDimensions().X();
2766 Standard_Real aViewHeight = myCamera->ViewDimensions().Y();
7fd59977 2767
197ac94e 2768 // ensure that zoom will not be too small or too big.
2769 Standard_Real aCoef = aDZoom;
2770 if (aViewWidth < aCoef * Precision::Confusion())
2771 {
2772 aCoef = aViewWidth / Precision::Confusion();
2773 }
2774 else if (aViewWidth > aCoef * 1e12)
2775 {
2776 aCoef = aViewWidth / 1e12;
2777 }
2778 if (aViewHeight < aCoef * Precision::Confusion())
2779 {
2780 aCoef = aViewHeight / Precision::Confusion();
2781 }
2782 else if (aViewHeight > aCoef * 1e12)
2783 {
2784 aCoef = aViewHeight / 1e12;
2785 }
7fd59977 2786
197ac94e 2787 Standard_Real aZoomAtPointXv = 0.0;
2788 Standard_Real aZoomAtPointYv = 0.0;
2789 Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
7fd59977 2790
197ac94e 2791 V3d_Coordinate aDxv = aZoomAtPointXv / aCoef;
2792 V3d_Coordinate aDyv = aZoomAtPointYv / aCoef;
7fd59977 2793
197ac94e 2794 myCamera->SetScale (myCamera->Scale() / aCoef);
2795 Translate (myCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
b5ac8292 2796
197ac94e 2797 AutoZFit();
b5ac8292 2798
197ac94e 2799 SetImmediateUpdate (wasUpdateEnabled);
7fd59977 2800
197ac94e 2801 ImmediateUpdate();
7fd59977 2802}
2803
197ac94e 2804//=============================================================================
2805//function : AxialScale
2806//purpose :
2807//=============================================================================
7fd59977 2808void V3d_View::AxialScale (const Standard_Integer Dx,
2809 const Standard_Integer Dy,
2810 const V3d_TypeOfAxe Axis)
2811{
2812 if( Dx != 0. || Dy != 0. ) {
2813 Standard_Real Sx, Sy, Sz;
2814 AxialScale( Sx, Sy, Sz );
2815 Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2816 dscale = (Dx > 0) ? dscale : 1./dscale;
2817 if( Axis == V3d_X ) Sx = dscale;
2818 if( Axis == V3d_Y ) Sy = dscale;
2819 if( Axis == V3d_Z ) Sz = dscale;
2820 SetAxialScale( Sx, Sy, Sz );
2821 }
2822}
2823
197ac94e 2824//=============================================================================
2825//function : FitAll
2826//purpose :
2827//=============================================================================
7fd59977 2828void V3d_View::FitAll(const Handle(Aspect_Window)& aWindow,
2829 const Standard_Real Xmin,
2830 const Standard_Real Ymin,
2831 const Standard_Real Xmax,
2832 const Standard_Real Ymax)
2833{
b5ac8292 2834 Standard_Integer aWinWidth, aWinHeight;
2835 aWindow->Size (aWinWidth, aWinHeight);
7fd59977 2836
197ac94e 2837 Standard_Real aWinAspect = (Standard_Real)aWinWidth / aWinHeight;
2838 Standard_Real aFitSizeU = Abs (Xmax - Xmin);
2839 Standard_Real aFitSizeV = Abs (Ymax - Ymin);
2840 Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2841 if (aFitAspect >= aWinAspect)
2842 {
2843 aFitSizeV = aFitSizeU / aWinAspect;
2844 }
2845 else
2846 {
2847 aFitSizeU = aFitSizeV * aWinAspect;
2848 }
b5ac8292 2849
197ac94e 2850 myCamera->SetAspect (aWinAspect);
2851 Translate (myCamera, (Xmin + Xmax) * 0.5, (Ymin + Ymax) * 0.5);
2852 Scale (myCamera, aFitSizeU, aFitSizeV);
b5ac8292 2853 AutoZFit();
7fd59977 2854
197ac94e 2855 ImmediateUpdate();
7fd59977 2856}
2857
197ac94e 2858//=============================================================================
2859//function : StartRotation
2860//purpose :
2861//=============================================================================
7fd59977 2862#ifdef IMP250900
2863static Standard_Boolean zRotation = Standard_False;
2864#endif
2865void V3d_View::StartRotation(const Standard_Integer X,
2866 const Standard_Integer Y,
2867 const Quantity_Ratio zRotationThreshold)
2868{
7fd59977 2869 sx = X; sy = Y;
2870 Standard_Real x,y;
2871 Size(x,y);
2872 rx = Standard_Real(Convert(x));
2873 ry = Standard_Real(Convert(y));
2874 Gravity(gx,gy,gz);
2875 Rotate(0.,0.,0.,gx,gy,gz,Standard_True);
2876#ifdef IMP250900
2877 zRotation = Standard_False;
2878 if( zRotationThreshold > 0. ) {
2879 Standard_Real dx = Abs(sx - rx/2.);
2880 Standard_Real dy = Abs(sy - ry/2.);
2881 // if( dx > rx/3. || dy > ry/3. ) zRotation = Standard_True;
2882 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2883 if( dx > dd || dy > dd ) zRotation = Standard_True;
2884 }
2885#endif
2886
2887}
2888
197ac94e 2889//=============================================================================
2890//function : Rotation
2891//purpose :
2892//=============================================================================
7fd59977 2893void V3d_View::Rotation(const Standard_Integer X,
2894 const Standard_Integer Y)
2895{
7fd59977 2896#ifdef IMP210600
2897 if( rx == 0. || ry == 0. ) {
2898 StartRotation(X,Y);
2899 return;
2900 }
2901#endif
2902#ifdef IMP250900
2903 Standard_Real dx=0.,dy=0.,dz=0.;
2904 if( zRotation ) {
2905 dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2906 atan2(sx-rx/2.,ry/2.-sy);
2907 } else {
c6541a0c
D
2908 dx = (Standard_Real(X) - sx) * M_PI / rx;
2909 dy = (sy - Standard_Real(Y)) * M_PI / ry;
7fd59977 2910 }
2911 Rotate(dx, dy, dz, gx, gy, gz, Standard_False);
2912#else
c6541a0c
D
2913 Standard_Real dx = (Standard_Real(X - sx)) * M_PI;
2914 Standard_Real dy = (Standard_Real(sy - Y)) * M_PI;
7fd59977 2915 Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2916#endif
2917#ifdef IMP020300
2918 if( !myImmediateUpdate ) Update();
2919#else
2920 myImmediateUpdate = Standard_False;
2921 Rotate(dx/rx, dy/ry, 0., gx, gy, gz, Standard_False);
2922 ZFitAll (Zmargin); //Don't do that, perf improvment
2923 myImmediateUpdate = Standard_True;
2924 ImmediateUpdate();
2925#endif
2926}
2927
197ac94e 2928//=============================================================================
2929//function : SetComputedMode
2930//purpose :
2931//=============================================================================
2932void V3d_View::SetComputedMode (const Standard_Boolean aMode)
7fd59977 2933{
197ac94e 2934 if (aMode)
2935 {
2936 if (myComputedMode)
2937 {
2938 MyView->SetComputedMode (Standard_True);
2939 Update();
7fd59977 2940 }
197ac94e 2941 }
2942 else
2943 {
2944 MyView->SetComputedMode (Standard_False);
2945 Update();
7fd59977 2946 }
b8ddfc2f 2947}
7fd59977 2948
197ac94e 2949//=============================================================================
2950//function : ComputedMode
2951//purpose :
2952//=============================================================================
2953Standard_Boolean V3d_View::ComputedMode() const
7fd59977 2954{
197ac94e 2955 return MyView->ComputedMode();
b8ddfc2f 2956}
7fd59977 2957
197ac94e 2958//=============================================================================
2959//function : SetBackFacingModel
2960//purpose :
2961//=============================================================================
2962void V3d_View::SetBackFacingModel (const V3d_TypeOfBackfacingModel aModel)
7fd59977 2963{
197ac94e 2964 MyView->SetBackFacingModel (Visual3d_TypeOfBackfacingModel(aModel));
7fd59977 2965 Redraw();
b8ddfc2f 2966}
7fd59977 2967
197ac94e 2968//=============================================================================
2969//function : BackFacingModel
2970//purpose :
2971//=============================================================================
2972V3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
b8ddfc2f 2973{
7fd59977 2974 return V3d_TypeOfBackfacingModel(MyView -> BackFacingModel ());
b8ddfc2f 2975}
7fd59977 2976
197ac94e 2977//=============================================================================
2978//function : TransientManagerBeginDraw
2979//purpose :
2980//=============================================================================
b8ddfc2f 2981Standard_Boolean V3d_View::TransientManagerBeginDraw(const Standard_Boolean DoubleBuffer,const Standard_Boolean RetainMode) const
2982{
7fd59977 2983 return Visual3d_TransientManager::BeginDraw(MyView,DoubleBuffer,RetainMode);
2984}
2985
197ac94e 2986//=============================================================================
2987//function : TransientManagerClearDraw
2988//purpose :
2989//=============================================================================
b8ddfc2f 2990void V3d_View::TransientManagerClearDraw() const
2991{
7fd59977 2992 Visual3d_TransientManager::ClearDraw(MyView);
2993}
2994
197ac94e 2995//=============================================================================
2996//function : TransientManagerBeginAddDraw
2997//purpose :
2998//=============================================================================
b8ddfc2f 2999Standard_Boolean V3d_View::TransientManagerBeginAddDraw() const
3000{
7fd59977 3001 return Visual3d_TransientManager::BeginAddDraw(MyView);
3002}
3003
197ac94e 3004//=============================================================================
3005//function : Init
3006//purpose :
3007//=============================================================================
b8ddfc2f 3008void V3d_View::Init()
3009{
7fd59977 3010 myComputedMode = MyViewer->ComputedMode();
7fd59977 3011 if( !myComputedMode || !MyViewer->DefaultComputedMode() ) {
3012 SetComputedMode(Standard_False);
3013 }
7fd59977 3014}
3015
197ac94e 3016//=============================================================================
3017//function : SetPlotter
3018//purpose :
3019//=============================================================================
b8ddfc2f 3020void V3d_View::SetPlotter(const Handle(Graphic3d_Plotter)& aPlotter)
3021{
7fd59977 3022 MyPlotter = aPlotter;
3023}
3024
197ac94e 3025//=============================================================================
3026//function : Plot
3027//purpose :
3028//=============================================================================
7fd59977 3029void V3d_View::Plot()
3030{
6942f04a 3031 V3d_BadValue_Raise_if( !MyPlotter.IsNull(), "view has no plotter");
7fd59977 3032 MyView->Plot(MyPlotter);
3033}
3034
197ac94e 3035//=============================================================================
3036//function : Dump
3037//purpose :
3038//=============================================================================
692613e5 3039Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
3040 const Graphic3d_BufferType& theBufferType)
7fd59977 3041{
3042 Standard_Integer aWinWidth, aWinHeight;
3043 MyWindow->Size (aWinWidth, aWinHeight);
692613e5 3044 Image_AlienPixMap anImage;
b5ac8292 3045
692613e5 3046 return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
7fd59977 3047}
3048
197ac94e 3049//=============================================================================
3050//function : ToPixMap
3051//purpose :
3052//=============================================================================
692613e5 3053Standard_Boolean V3d_View::ToPixMap (Image_PixMap& theImage,
3054 const Standard_Integer theWidth,
3055 const Standard_Integer theHeight,
3056 const Graphic3d_BufferType& theBufferType,
197ac94e 3057 const Standard_Boolean theToKeepAspect,
b5ac8292 3058 const V3d_StereoDumpOptions theStereoOptions)
7fd59977 3059{
7fd59977 3060 Graphic3d_CView* cView = (Graphic3d_CView* )MyView->CView();
1981cb22 3061
3062 // always prefer hardware accelerated offscreen buffer
7fd59977 3063 Graphic3d_PtrFrameBuffer aFBOPtr = NULL;
3064 Graphic3d_PtrFrameBuffer aPrevFBOPtr = (Graphic3d_PtrFrameBuffer )cView->ptrFBO;
85e096c3 3065 Standard_Integer aFBOVPSizeX (theWidth), aFBOVPSizeY (theHeight), aFBOSizeXMax (0), aFBOSizeYMax (0);
7fd59977 3066 Standard_Integer aPrevFBOVPSizeX (0), aPrevFBOVPSizeY (0), aPrevFBOSizeXMax (0), aPrevFBOSizeYMax (0);
3067 if (aPrevFBOPtr != NULL)
3068 {
3069 MyView->FBOGetDimensions (aPrevFBOPtr,
3070 aPrevFBOVPSizeX, aPrevFBOVPSizeY,
3071 aPrevFBOSizeXMax, aPrevFBOSizeYMax);
85e096c3 3072 if (aFBOVPSizeX <= aPrevFBOSizeXMax && aFBOVPSizeY <= aPrevFBOSizeYMax)
7fd59977 3073 {
85e096c3 3074 MyView->FBOChangeViewport (aPrevFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
7fd59977 3075 aFBOPtr = aPrevFBOPtr;
3076 }
3077 }
3078
3079 if (aFBOPtr == NULL)
3080 {
3081 // Try to create hardware accelerated buffer
85e096c3 3082 aFBOPtr = MyView->FBOCreate (aFBOVPSizeX, aFBOVPSizeY);
3083 if (aFBOPtr != NULL)
3084 {
3085 MyView->FBOGetDimensions (aFBOPtr,
3086 aFBOVPSizeX, aFBOVPSizeY,
3087 aFBOSizeXMax, aFBOSizeYMax);
3088 // reduce viewport in case of hardware limits
3089 if (aFBOVPSizeX > aFBOSizeXMax) aFBOVPSizeX = aFBOSizeXMax;
3090 if (aFBOVPSizeY > aFBOSizeYMax) aFBOVPSizeY = aFBOSizeYMax;
3091 MyView->FBOChangeViewport (aFBOPtr, aFBOVPSizeX, aFBOVPSizeY);
3092 }
7fd59977 3093 }
3094 cView->ptrFBO = aFBOPtr;
3095
3096 // If hardware accelerated buffer - try to use onscreen buffer
3097 // Results may be bad!
3098 if (aFBOPtr == NULL)
3099 {
3100 // retrieve window sizes
3101 Standard_Integer aWinWidth, aWinHeight;
3102 MyWindow->Size (aWinWidth, aWinHeight);
3103
3104 // technically we can reduce existing viewport...
3105 // but currently allow only dumping the window itself
85e096c3 3106 if (aFBOVPSizeX != aWinWidth || aFBOVPSizeY != aWinHeight)
7fd59977 3107 {
692613e5 3108 return Standard_False;
7fd59977 3109 }
3110 }
3111
b5ac8292 3112 Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
3113
3114 aStoreMapping->Copy (myCamera);
7fd59977 3115
b5ac8292 3116 if (myCamera->IsStereo())
3117 {
3118 switch (theStereoOptions)
3119 {
3120 case V3d_SDO_MONO :
3121 myCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
3122 break;
3123
3124 case V3d_SDO_LEFT_EYE :
3125 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
3126 break;
3127
3128 case V3d_SDO_RIGHT_EYE :
3129 myCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
3130 break;
3131 }
3132 }
3133
197ac94e 3134 AutoZFit();
7fd59977 3135
197ac94e 3136 if (theToKeepAspect)
3137 {
3138 myCamera->SetAspect ((Standard_Real) aFBOVPSizeX / aFBOSizeYMax);
7fd59977 3139 }
3140
b5ac8292 3141 //workaround for rendering list of Over and Under Layers
7fd59977 3142 if (!MyLayerMgr.IsNull())
3143 {
3144 MyLayerMgr->Compute();
3145 }
1981cb22 3146
3147 // render immediate structures into back buffer rather than front
3148 Handle(Graphic3d_GraphicDriver) aDriver = Handle(Graphic3d_GraphicDriver)::DownCast (MyView->GraphicDriver());
3149 const Standard_Boolean aPrevImmediateMode = aDriver.IsNull() ? Standard_True : aDriver->SetImmediateModeDrawToFront (*cView, Standard_False);
7fd59977 3150 Redraw();
3151
1981cb22 3152 if (!aDriver.IsNull())
3153 {
3154 aDriver->SetImmediateModeDrawToFront (*cView, aPrevImmediateMode);
3155 }
3156
b5ac8292 3157 myCamera->Copy (aStoreMapping);
7fd59977 3158
692613e5 3159 Standard_Boolean isSuccess = Standard_True;
3160
7fd59977 3161 // allocate image buffer for dumping
692613e5 3162 if (theImage.IsEmpty()
3163 || (Standard_Size )aFBOVPSizeX != theImage.SizeX()
3164 || (Standard_Size )aFBOVPSizeY != theImage.SizeY())
7fd59977 3165 {
692613e5 3166 bool isBigEndian = Image_PixMap::IsBigEndianHost();
3167 Image_PixMap::ImgFormat aFormat = Image_PixMap::ImgUNKNOWN;
3168 switch (theBufferType)
3169 {
3170 case Graphic3d_BT_RGB: aFormat = isBigEndian ? Image_PixMap::ImgRGB : Image_PixMap::ImgBGR; break;
3171 case Graphic3d_BT_RGBA: aFormat = isBigEndian ? Image_PixMap::ImgRGBA : Image_PixMap::ImgBGRA; break;
3172 case Graphic3d_BT_Depth: aFormat = Image_PixMap::ImgGrayF; break;
3173 }
3174
3175 isSuccess = isSuccess && theImage.InitZero (aFormat, aFBOVPSizeX, aFBOVPSizeY);
7fd59977 3176 }
692613e5 3177 isSuccess = isSuccess && MyView->BufferDump (theImage, theBufferType);
7fd59977 3178
3179 // FBO now useless, free resources
3180 if (aFBOPtr != aPrevFBOPtr)
3181 {
3182 MyView->FBORelease (aFBOPtr);
3183 }
3184 else if (aPrevFBOPtr != NULL)
3185 {
3186 MyView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSizeX, aPrevFBOVPSizeY);
3187 }
3188 cView->ptrFBO = aPrevFBOPtr;
692613e5 3189 return isSuccess;
7fd59977 3190}
6942f04a 3191
3192void V3d_View::ImmediateUpdate() const
3193{
3194 if (myImmediateUpdate) Update();
3195}
3196
3197Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
3198{
3199 Standard_Boolean aPreviousMode = myImmediateUpdate;
3200 myImmediateUpdate = theImmediateUpdate;
3201 return aPreviousMode;
3202}
b5ac8292 3203
3204// =======================================================================
3205// function : SetCamera
3206// purpose :
3207// =======================================================================
3208void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
3209{
197ac94e 3210 Standard_ASSERT_RAISE (!theCamera.IsNull(), "Void camera is not allowed");
3211
b5ac8292 3212 myCamera = theCamera;
3213
3214 MyView->SetCamera (theCamera);
3215}
3216
3217// =======================================================================
3218// function : GetCamera
3219// purpose :
3220// =======================================================================
197ac94e 3221const Handle(Graphic3d_Camera)& V3d_View::Camera() const
b5ac8292 3222{
3223 return myCamera;
3224}
3225
3226// =======================================================================
197ac94e 3227// function : FitMinMax
3228// purpose : Internal
b5ac8292 3229// =======================================================================
197ac94e 3230Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
3231 const gp_XYZ& theMinCorner,
3232 const gp_XYZ& theMaxCorner,
3233 const Standard_Real theMargin,
3234 const Standard_Real theResolution,
3235 const Standard_Boolean theToEnlargeIfLine) const
3236{
3237 // Check bounding box for validness
b5ac8292 3238 Standard_Real aLim = (ShortRealLast() - 1.0);
197ac94e 3239 if (Abs (theMinCorner.X()) > aLim || Abs (theMinCorner.Y()) > aLim || Abs (theMinCorner.Z()) > aLim ||
3240 Abs (theMaxCorner.X()) > aLim || Abs (theMaxCorner.Y()) > aLim || Abs (theMaxCorner.Z()) > aLim)
b5ac8292 3241 {
197ac94e 3242 return Standard_False; // bounding box is out of bounds...
3243 }
3244
3245 // Apply "axial scaling" to the bounding points.
3246 // It is not the best approach to make this scaling as a part of fit all operation,
3247 // but the axial scale is integrated into camera orientation matrix and the other
3248 // option is to perform frustum plane adjustment algorithm in view camera space,
3249 // which will lead to a number of additional world-view space conversions and
3250 // loosing precision as well.
3251 Standard_Real aXmin = theMinCorner.X() * theCamera->AxialScale().X();
3252 Standard_Real aXmax = theMaxCorner.X() * theCamera->AxialScale().X();
3253 Standard_Real aYmin = theMinCorner.Y() * theCamera->AxialScale().Y();
3254 Standard_Real aYmax = theMaxCorner.Y() * theCamera->AxialScale().Y();
3255 Standard_Real aZmin = theMinCorner.Z() * theCamera->AxialScale().Z();
3256 Standard_Real aZmax = theMaxCorner.Z() * theCamera->AxialScale().Z();
3257
3258 Bnd_Box aBBox;
3259 aBBox.Update (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3260 if (aBBox.IsThin (RealEpsilon()))
b5ac8292 3261 {
197ac94e 3262 return Standard_False; // nothing to fit all
3263 }
3264
3265 gp_Pnt aBBCenter ((aXmin + aXmax) * 0.5, (aYmin + aYmax) * 0.5, (aZmin + aZmax) * 0.5);
3266
3267 gp_Pln aFrustumLeft;
3268 gp_Pln aFrustumRight;
3269 gp_Pln aFrustumBottom;
3270 gp_Pln aFrustumTop;
3271 gp_Pln aFrustumNear;
3272 gp_Pln aFrustumFar;
3273 theCamera->Frustum (aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar);
3274
3275 gp_Dir aCamUp = theCamera->OrthogonalizedUp();
3276 gp_Dir aCamDir = theCamera->Direction();
3277 gp_Dir aCamSide = aCamDir ^ aCamUp;
3278
3279 // Perspective-correct camera projection vector, matching the bounding box is determined geometrically.
3280 // Knowing the initial shape of a frustum it is possible to match it to a bounding box.
3281 // Then, knowing the relation of camera projection vector to the frustum shape it is possible to
3282 // set up perspective-correct camera projection matching the bounding box.
3283 // These steps support non-asymmetric transformations of view-projection space provided by camera.
3284 // The zooming can be done by calculating view plane size matching the bounding box at center of
3285 // the bounding box. The only limitation here is that the scale of camera should define size of
3286 // its view plane passing through the camera center, and the center of camera should be on the
3287 // same line with the center of bounding box.
3288
3289 // The following method is applied:
3290 // 1) Determine normalized asymmetry of camera projection vector by frustum planes.
3291 // 2) Determine new location of frustum planes, "matching" the bounding box.
3292 // 3) Determine new camera projection vector using the normalized asymmetry.
3293 // 4) Determine new zooming in view space.
3294
3295 // Determine normalized projection asymmetry (if any).
3296
3297 Standard_Real anAssymX = Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction()))
3298 - Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction()));
3299 Standard_Real anAssymY = Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction()))
3300 - Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction()));
3301
3302 // Determine how far should be the frustum planes placed from center
3303 // of bounding box, in order to match the bounding box closely.
3304 gp_Pln aMatchSide[6] = {aFrustumLeft, aFrustumRight, aFrustumBottom, aFrustumTop, aFrustumNear, aFrustumFar};
3305 Standard_Real aMatchDistance[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
3306 for (Standard_Integer anIt = 0; anIt < 6; ++anIt)
3307 {
3308 const gp_Dir& aPlaneN = aMatchSide[anIt].Axis().Direction();
3309
3310 gp_Trsf aPlaneTrsf;
3311 aPlaneTrsf.SetTransformation (gp_Ax3(), gp_Ax3 (aBBCenter, aPlaneN));
3312 Bnd_Box aRelativeBBox = aBBox.Transformed (aPlaneTrsf);
3313
3314 Standard_Real aDummy = 0.0;
3315 Standard_Real aZmin = 0.0;
3316 Standard_Real aZmax = 0.0;
3317 aRelativeBBox.Get (aDummy, aDummy, aZmin, aDummy, aDummy, aZmax);
3318 aMatchDistance[anIt] = -aZmin;
3319 }
3320 // The center of camera is placed on the same line with center of bounding box.
3321 // The view plane section crosses the bounding box at its center.
3322 // To compute view plane size, evaluate coefficients converting "point -> plane distance"
3323 // into view section size between the point and the frustum plane.
3324 // proj
3325 // /|\ right half of frame //
3326 // | //
3327 // point o<-- distance * coeff -->//---- (view plane section)
3328 // \ //
3329 // (distance) //
3330 // ~ //
3331 // (distance) //
3332 // \/\//
3333 // \//
3334 // //
3335 // (frustum plane)
3336
3337 aMatchDistance[0] *= Sqrt(1 + Pow (Tan ( aCamSide.Angle (aFrustumLeft.Axis().Direction())), 2.0));
3338 aMatchDistance[1] *= Sqrt(1 + Pow (Tan (-aCamSide.Angle (aFrustumRight.Axis().Direction())), 2.0));
3339 aMatchDistance[2] *= Sqrt(1 + Pow (Tan ( aCamUp.Angle (aFrustumBottom.Axis().Direction())), 2.0));
3340 aMatchDistance[3] *= Sqrt(1 + Pow (Tan (-aCamUp.Angle (aFrustumTop.Axis().Direction())), 2.0));
3341 aMatchDistance[4] *= Sqrt(1 + Pow (Tan ( aCamDir.Angle (aFrustumNear.Axis().Direction())), 2.0));
3342 aMatchDistance[5] *= Sqrt(1 + Pow (Tan (-aCamDir.Angle (aFrustumFar.Axis().Direction())), 2.0));
3343
3344 Standard_Real aViewSizeXv = aMatchDistance[0] + aMatchDistance[1];
3345 Standard_Real aViewSizeYv = aMatchDistance[2] + aMatchDistance[3];
3346 Standard_Real aViewSizeZv = aMatchDistance[4] + aMatchDistance[5];
3347
3348 // Place center of camera on the same line with center of bounding
3349 // box applying corresponding projection asymmetry (if any).
3350 Standard_Real anAssymXv = anAssymX * aViewSizeXv * 0.5;
3351 Standard_Real anAssymYv = anAssymY * aViewSizeYv * 0.5;
3352 Standard_Real anOffsetXv = (aMatchDistance[1] - aMatchDistance[0]) * 0.5 + anAssymXv;
3353 Standard_Real anOffsetYv = (aMatchDistance[3] - aMatchDistance[2]) * 0.5 + anAssymYv;
3354 gp_Vec aTranslateSide = gp_Vec (aCamSide) * anOffsetXv;
3355 gp_Vec aTranslateUp = gp_Vec (aCamUp) * anOffsetYv;
3356 gp_Pnt aNewCenter = aBBCenter.Translated (aTranslateSide).Translated (aTranslateUp);
3357
3358 gp_Trsf aCenterTrsf;
3359 aCenterTrsf.SetTranslation (theCamera->Center(), aNewCenter);
3360 theCamera->Transform (aCenterTrsf);
3361 theCamera->SetDistance (Max (aMatchDistance[5] + aMatchDistance[4], Precision::Confusion()));
3362
3363 // Bounding box collapses to a point or thin line going in depth of the screen
3364 if (aViewSizeXv < theResolution && aViewSizeYv < theResolution)
b5ac8292 3365 {
197ac94e 3366 if (aViewSizeXv < theResolution || !theToEnlargeIfLine)
3367 {
3368 return Standard_True; // This is just one point or line and zooming has no effect.
3369 }
3370
3371 // Looking along line and "theToEnlargeIfLine" is requested.
3372 // Fit view to see whole scene on rotation.
3373 aViewSizeXv = aViewSizeZv;
3374 aViewSizeYv = aViewSizeZv;
b5ac8292 3375 }
3376
197ac94e 3377 Scale (theCamera, aViewSizeXv * (1.0 + theMargin), aViewSizeYv * (1.0 + theMargin));
b5ac8292 3378
197ac94e 3379 return Standard_True;
b5ac8292 3380}
3381
3382// =======================================================================
197ac94e 3383// function : Scale
3384// purpose : Internal
b5ac8292 3385// =======================================================================
197ac94e 3386void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
3387 const Standard_Real theSizeXv,
3388 const Standard_Real theSizeYv) const
b5ac8292 3389{
197ac94e 3390 Standard_Real anAspect = theCamera->Aspect();
3391 Standard_Real aMaxSize = Max (theSizeXv / anAspect, theSizeYv);
3392 theCamera->SetScale (aMaxSize);
b5ac8292 3393}
3394
3395// =======================================================================
197ac94e 3396// function : Translate
3397// purpose : Internal
b5ac8292 3398// =======================================================================
197ac94e 3399void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
3400 const Standard_Real theDXv,
3401 const Standard_Real theDYv) const
3402{
3403 const gp_Pnt& aCenter = theCamera->Center();
3404 const gp_Dir& aDir = theCamera->Direction();
3405 const gp_Dir& anUp = theCamera->Up();
3406 gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
3407
3408 gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
3409 gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
3410 gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
3411 gp_Trsf aPanTrsf;
3412 aPanTrsf.SetTranslation (aCameraPan);
3413
3414 theCamera->Transform (aPanTrsf);
b5ac8292 3415}