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