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