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