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