0032590: Visualization, V3d_View - improve API for setting Image Based Lighting
[occt.git] / src / V3d / V3d_View.cxx
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 #include <V3d_View.hxx>
15
16 #include <Aspect_CircularGrid.hxx>
17 #include <Aspect_GradientBackground.hxx>
18 #include <Aspect_Grid.hxx>
19 #include <Aspect_RectangularGrid.hxx>
20 #include <Aspect_Window.hxx>
21 #include <Bnd_Box.hxx>
22 #include <gp_Ax3.hxx>
23 #include <gp_Dir.hxx>
24 #include <gp_Pln.hxx>
25 #include <Graphic3d_AspectMarker3d.hxx>
26 #include <Graphic3d_GraphicDriver.hxx>
27 #include <Graphic3d_Group.hxx>
28 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
29 #include <Graphic3d_MapOfStructure.hxx>
30 #include <Graphic3d_Structure.hxx>
31 #include <Graphic3d_TextureEnv.hxx>
32 #include <Image_AlienPixMap.hxx>
33 #include <Message.hxx>
34 #include <Message_Messenger.hxx>
35 #include <NCollection_Array1.hxx>
36 #include <Precision.hxx>
37 #include <Quantity_Color.hxx>
38 #include <Standard_Assert.hxx>
39 #include <Standard_DivideByZero.hxx>
40 #include <Standard_ErrorHandler.hxx>
41 #include <Standard_MultiplyDefined.hxx>
42 #include <Standard_ShortReal.hxx>
43 #include <Standard_Type.hxx>
44 #include <Standard_TypeMismatch.hxx>
45 #include <TColgp_Array1OfPnt.hxx>
46 #include <TColStd_Array2OfReal.hxx>
47 #include <TColStd_HSequenceOfInteger.hxx>
48 #include <V3d.hxx>
49 #include <V3d_BadValue.hxx>
50 #include <V3d_Light.hxx>
51 #include <V3d_StereoDumpOptions.hxx>
52 #include <V3d_UnMapped.hxx>
53 #include <V3d_Viewer.hxx>
54
55 IMPLEMENT_STANDARD_RTTIEXT(V3d_View,Standard_Transient)
56
57 #define DEUXPI (2. * M_PI)
58
59 namespace
60 {
61   static const Standard_Integer THE_NB_BOUND_POINTS = 8;
62 }
63
64 //=============================================================================
65 //function : Constructor
66 //purpose  :
67 //=============================================================================
68 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfView theType)
69 : myIsInvalidatedImmediate (Standard_True),
70   MyViewer (theViewer.operator->()),
71   SwitchSetFront (Standard_False),
72   myZRotation (Standard_False),
73   MyTrsf (1, 4, 1, 4)
74 {
75   myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
76
77   myView->SetBackground         (theViewer->GetBackgroundColor());
78   myView->SetGradientBackground (theViewer->GetGradientBackground());
79
80   ChangeRenderingParams() = theViewer->DefaultRenderingParams();
81
82   // camera init
83   Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera();
84   aCamera->SetFOVy (45.0);
85   aCamera->SetIOD (Graphic3d_Camera::IODType_Relative, 0.05);
86   aCamera->SetZFocus (Graphic3d_Camera::FocusType_Relative, 1.0);
87   aCamera->SetProjectionType ((theType == V3d_ORTHOGRAPHIC)
88     ? Graphic3d_Camera::Projection_Orthographic
89     : Graphic3d_Camera::Projection_Perspective);
90
91   myDefaultCamera = new Graphic3d_Camera();
92
93   myImmediateUpdate = Standard_False;
94   SetAutoZFitMode (Standard_True, 1.0);
95   SetBackFacingModel (V3d_TOBM_AUTOMATIC);
96   SetCamera (aCamera);
97   SetAxis (0.,0.,0.,1.,1.,1.);
98   SetVisualization (theViewer->DefaultVisualization());
99   SetTwist (0.);
100   SetAt (0.,0.,0.);
101   SetProj (theViewer->DefaultViewProj());
102   SetSize (theViewer->DefaultViewSize());
103   Standard_Real zsize = theViewer->DefaultViewSize();
104   SetZSize (2.*zsize);
105   SetDepth (theViewer->DefaultViewSize() / 2.0);
106   SetViewMappingDefault();
107   SetViewOrientationDefault();
108   theViewer->AddView (this);
109   Init();
110   myImmediateUpdate = Standard_True;
111 }
112
113 //=============================================================================
114 //function : Constructor
115 //purpose  :
116 //=============================================================================
117 V3d_View::V3d_View (const Handle(V3d_Viewer)& theViewer, const Handle(V3d_View)& theView)
118 : myIsInvalidatedImmediate (Standard_True),
119   MyViewer (theViewer.operator->()),
120   SwitchSetFront(Standard_False),
121   myZRotation (Standard_False),
122   MyTrsf (1, 4, 1, 4)
123 {
124   myView = theViewer->Driver()->CreateView (theViewer->StructureManager());
125
126   myView->CopySettings (theView->View());
127   myDefaultViewPoint = theView->myDefaultViewPoint;
128   myDefaultViewAxis  = theView->myDefaultViewAxis;
129
130   myDefaultCamera = new Graphic3d_Camera (theView->DefaultCamera());
131
132   myImmediateUpdate = Standard_False;
133   SetAutoZFitMode (theView->AutoZFitMode(), theView->AutoZFitScaleFactor());
134   theViewer->AddView (this);
135   Init();
136   myImmediateUpdate = Standard_True;
137 }
138
139 //=============================================================================
140 //function : Destructor
141 //purpose  :
142 //=============================================================================
143 V3d_View::~V3d_View()
144 {
145   if (!myView->IsRemoved())
146   {
147     myView->Remove();
148   }
149 }
150
151 //=============================================================================
152 //function : SetMagnify
153 //purpose  :
154 //=============================================================================
155 void V3d_View::SetMagnify (const Handle(Aspect_Window)& theWindow,
156                            const Handle(V3d_View)& thePreviousView,
157                            const Standard_Integer theX1,
158                            const Standard_Integer theY1,
159                            const Standard_Integer theX2,
160                            const Standard_Integer theY2)
161 {
162   if (!myView->IsRemoved() && !myView->IsDefined())
163   {
164     Standard_Real aU1, aV1, aU2, aV2;
165     thePreviousView->Convert (theX1, theY1, aU1, aV1);
166     thePreviousView->Convert (theX2, theY2, aU2, aV2);
167     myView->SetWindow (theWindow);
168     FitAll (aU1, aV1, aU2, aV2);
169     MyViewer->SetViewOn (this);
170     MyWindow = theWindow;
171     SetRatio();
172     Redraw();
173     SetViewMappingDefault();
174   }
175 }
176
177 //=============================================================================
178 //function : SetWindow
179 //purpose  :
180 //=============================================================================
181 void V3d_View::SetWindow (const Handle(Aspect_Window)&  theWindow,
182                           const Aspect_RenderingContext theContext)
183 {
184   if (myView->IsRemoved())
185   {
186     return;
187   }
188
189   // method V3d_View::SetWindow() should assign the field MyWindow before calling Redraw()
190   MyWindow = theWindow;
191   myView->SetWindow (theWindow, theContext);
192   MyViewer->SetViewOn (this);
193   SetRatio();
194   if (myImmediateUpdate)
195   {
196     Redraw();
197   }
198 }
199
200 //=============================================================================
201 //function : Remove
202 //purpose  :
203 //=============================================================================
204 void V3d_View::Remove()
205 {
206   if (!MyGrid.IsNull())
207   {
208     MyGrid->Erase();
209   }
210   if (!myTrihedron.IsNull())
211   {
212     myTrihedron->Erase();
213   }
214
215   MyViewer->DelView (this);
216   myView->Remove();
217   Handle(Aspect_Window)& aWin = const_cast<Handle(Aspect_Window)&> (MyWindow);
218   aWin.Nullify();
219 }
220
221 //=============================================================================
222 //function : Update
223 //purpose  :
224 //=============================================================================
225 void V3d_View::Update() const
226 {
227   if (!myView->IsDefined()
228    || !myView->IsActive())
229   {
230     return;
231   }
232
233   myIsInvalidatedImmediate = Standard_False;
234   myView->Update();
235   myView->Compute();
236   AutoZFit();
237   myView->Redraw();
238 }
239
240 //=============================================================================
241 //function : Redraw
242 //purpose  :
243 //=============================================================================
244 void V3d_View::Redraw() const
245 {
246   if (!myView->IsDefined()
247    || !myView->IsActive())
248   {
249     return;
250   }
251
252   myIsInvalidatedImmediate = Standard_False;
253   Handle(Graphic3d_StructureManager) aStructureMgr  = MyViewer->StructureManager();
254   for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
255   {
256     if (aStructureMgr->IsDeviceLost())
257     {
258       aStructureMgr->RecomputeStructures();
259     }
260
261     AutoZFit();
262
263     myView->Redraw();
264
265     if (!aStructureMgr->IsDeviceLost())
266     {
267       return;
268     }
269   }
270 }
271
272 //=============================================================================
273 //function : RedrawImmediate
274 //purpose  :
275 //=============================================================================
276 void V3d_View::RedrawImmediate() const
277 {
278   if (!myView->IsDefined()
279    || !myView->IsActive())
280   {
281     return;
282   }
283
284   myIsInvalidatedImmediate = Standard_False;
285   myView->RedrawImmediate();
286 }
287
288 //=============================================================================
289 //function : Invalidate
290 //purpose  :
291 //=============================================================================
292 void V3d_View::Invalidate() const
293 {
294   if (!myView->IsDefined())
295   {
296     return;
297   }
298
299   myView->Invalidate();
300 }
301
302 //=============================================================================
303 //function : IsInvalidated
304 //purpose  :
305 //=============================================================================
306 Standard_Boolean V3d_View::IsInvalidated() const
307 {
308   return !myView->IsDefined()
309        || myView->IsInvalidated();
310 }
311
312 // ========================================================================
313 // function : SetAutoZFitMode
314 // purpose  :
315 // ========================================================================
316 void V3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn,
317                                 const Standard_Real    theScaleFactor)
318 {
319   Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
320   myAutoZFitScaleFactor = theScaleFactor;
321   myAutoZFitIsOn = theIsOn;
322 }
323
324 //=============================================================================
325 //function : AutoZFit
326 //purpose  :
327 //=============================================================================
328 void V3d_View::AutoZFit() const
329 {
330   if (!AutoZFitMode())
331   {
332     return;
333   }
334
335   ZFitAll (myAutoZFitScaleFactor);
336 }
337
338 //=============================================================================
339 //function : ZFitAll
340 //purpose  :
341 //=============================================================================
342 void V3d_View::ZFitAll (const Standard_Real theScaleFactor) const
343 {
344   Bnd_Box aMinMaxBox   = myView->MinMaxValues (Standard_False); // applicative min max boundaries
345   Bnd_Box aGraphicBox  = myView->MinMaxValues (Standard_True);  // real graphical boundaries (not accounting infinite flag).
346
347   myView->Camera()->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
348 }
349
350 //=============================================================================
351 //function : IsEmpty
352 //purpose  :
353 //=============================================================================
354 Standard_Boolean V3d_View::IsEmpty() const
355 {
356   Standard_Boolean TheStatus = Standard_True ;
357   if( myView->IsDefined() ) {
358     Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
359     if( Nstruct > 0 ) TheStatus = Standard_False ;
360   }
361   return (TheStatus) ;
362 }
363
364 //=============================================================================
365 //function : UpdateLights
366 //purpose  :
367 //=============================================================================
368 void V3d_View::UpdateLights() const
369 {
370   Handle(Graphic3d_LightSet) aLights = new Graphic3d_LightSet();
371   for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
372   {
373     aLights->Add (anActiveLightIter.Value());
374   }
375   myView->SetLights (aLights);
376 }
377
378 //=============================================================================
379 //function : DoMapping
380 //purpose  :
381 //=============================================================================
382 void V3d_View::DoMapping()
383 {
384   if (!myView->IsDefined())
385   {
386     return;
387   }
388
389   myView->Window()->DoMapping();
390 }
391
392 //=============================================================================
393 //function : MustBeResized
394 //purpose  :
395 //=============================================================================
396 void V3d_View::MustBeResized()
397 {
398   if (!myView->IsDefined())
399   {
400     return;
401   }
402
403   myView->Resized();
404
405   SetRatio();
406   if (myImmediateUpdate)
407   {
408     Redraw();
409   }
410 }
411
412 //=============================================================================
413 //function : SetBackgroundColor
414 //purpose  :
415 //=============================================================================
416 void V3d_View::SetBackgroundColor (const Quantity_TypeOfColor theType,
417                                    const Standard_Real theV1,
418                                    const Standard_Real theV2,
419                                    const Standard_Real theV3)
420 {
421   Standard_Real aV1 = Max (Min (theV1, 1.0), 0.0);
422   Standard_Real aV2 = Max (Min (theV2, 1.0), 0.0);
423   Standard_Real aV3 = Max (Min (theV3, 1.0), 0.0);
424
425   SetBackgroundColor (Quantity_Color (aV1, aV2, aV3, theType));
426 }
427
428 //=============================================================================
429 //function : SetBackgroundColor
430 //purpose  :
431 //=============================================================================
432 void V3d_View::SetBackgroundColor (const Quantity_Color& theColor)
433 {
434   myView->SetBackground (Aspect_Background (theColor));
435
436   if (myImmediateUpdate)
437   {
438     Redraw();
439   }
440 }
441
442 //=============================================================================
443 //function : SetBgGradientColors
444 //purpose  :
445 //=============================================================================
446 void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
447                                     const Quantity_Color& theColor2,
448                                     const Aspect_GradientFillMethod theFillStyle,
449                                     const Standard_Boolean theToUpdate)
450 {
451   Aspect_GradientBackground aGradientBg (theColor1, theColor2, theFillStyle);
452
453   myView->SetGradientBackground (aGradientBg);
454
455   if (myImmediateUpdate || theToUpdate)
456   {
457     Redraw();
458   }
459 }
460
461 //=============================================================================
462 //function : SetBgGradientStyle
463 //purpose  :
464 //=============================================================================
465 void V3d_View::SetBgGradientStyle (const Aspect_GradientFillMethod theFillStyle, const Standard_Boolean theToUpdate)
466 {
467   Quantity_Color aColor1;
468   Quantity_Color aColor2;
469   GradientBackground().Colors (aColor1, aColor2);
470
471   SetBgGradientColors (aColor1, aColor2, theFillStyle, theToUpdate);
472 }
473
474 //=============================================================================
475 //function : SetBackgroundImage
476 //purpose  :
477 //=============================================================================
478 void V3d_View::SetBackgroundImage (const Standard_CString theFileName,
479                                    const Aspect_FillMethod theFillStyle,
480                                    const Standard_Boolean theToUpdate)
481 {
482   Handle(Graphic3d_Texture2D) aTextureMap = new Graphic3d_Texture2Dmanual (theFileName);
483   aTextureMap->DisableModulate();
484   SetBackgroundImage (aTextureMap, theFillStyle, theToUpdate);
485 }
486
487 //=============================================================================
488 //function : SetBackgroundImage
489 //purpose  :
490 //=============================================================================
491 void V3d_View::SetBackgroundImage (const Handle(Graphic3d_Texture2D)& theTexture,
492                                    const Aspect_FillMethod theFillStyle,
493                                    const Standard_Boolean theToUpdate)
494 {
495   myView->SetBackgroundImage (theTexture);
496   myView->SetBackgroundImageStyle (theFillStyle);
497   if (myImmediateUpdate || theToUpdate)
498   {
499     Redraw();
500   }
501 }
502
503 //=============================================================================
504 //function : SetBgImageStyle
505 //purpose  :
506 //=============================================================================
507 void V3d_View::SetBgImageStyle (const Aspect_FillMethod theFillStyle, const Standard_Boolean theToUpdate)
508 {
509   myView->SetBackgroundImageStyle (theFillStyle);
510
511   if (myImmediateUpdate || theToUpdate)
512   {
513     Redraw();
514   }
515 }
516
517 //=============================================================================
518 //function : SetBackgroundCubeMap
519 //purpose  :
520 //=============================================================================
521 void V3d_View::SetBackgroundCubeMap (const Handle(Graphic3d_CubeMap)& theCubeMap,
522                                      Standard_Boolean                 theToUpdatePBREnv,
523                                      Standard_Boolean                 theToUpdate)
524 {
525   myView->SetBackgroundImage (theCubeMap, theToUpdatePBREnv);
526   if (myImmediateUpdate || theToUpdate)
527   {
528     Redraw();
529   }
530 }
531
532 //=============================================================================
533 //function : IsImageBasedLighting
534 //purpose  :
535 //=============================================================================
536 Standard_Boolean V3d_View::IsImageBasedLighting() const
537 {
538   return !myView->IBLCubeMap().IsNull();
539 }
540
541 //=============================================================================
542 //function : SetImageBasedLighting
543 //purpose  :
544 //=============================================================================
545 void V3d_View::SetImageBasedLighting (Standard_Boolean theToEnableIBL,
546                                       Standard_Boolean theToUpdate)
547 {
548   myView->SetImageBasedLighting (theToEnableIBL);
549   if (myImmediateUpdate || theToUpdate)
550   {
551     Redraw();
552   }
553 }
554
555 //=============================================================================
556 //function : SetAxis
557 //purpose  :
558 //=============================================================================
559 void V3d_View::SetAxis (const Standard_Real theX,  const Standard_Real theY,  const Standard_Real theZ,
560                         const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
561 {
562   myDefaultViewPoint.SetCoord (theX, theY, theZ);
563   myDefaultViewAxis.SetCoord (theVx, theVy, theVz);
564 }
565
566 //=============================================================================
567 //function : SetShadingModel
568 //purpose  :
569 //=============================================================================
570 void V3d_View::SetShadingModel (const Graphic3d_TypeOfShadingModel theShadingModel)
571 {
572   myView->SetShadingModel (theShadingModel);
573 }
574
575 //=============================================================================
576 //function : SetTextureEnv
577 //purpose  :
578 //=============================================================================
579 void V3d_View::SetTextureEnv (const Handle(Graphic3d_TextureEnv)& theTexture)
580 {
581   myView->SetTextureEnv (theTexture);
582
583   if (myImmediateUpdate)
584   {
585     Redraw();
586   }
587 }
588
589 //=============================================================================
590 //function : SetVisualization
591 //purpose  :
592 //=============================================================================
593 void V3d_View::SetVisualization (const V3d_TypeOfVisualization theType)
594 {
595   myView->SetVisualizationType (static_cast <Graphic3d_TypeOfVisualization> (theType));
596
597   if (myImmediateUpdate)
598   {
599     Redraw();
600   }
601 }
602
603 //=============================================================================
604 //function : SetFront
605 //purpose  :
606 //=============================================================================
607 void V3d_View::SetFront()
608 {
609   gp_Ax3 a = MyViewer->PrivilegedPlane();
610   Standard_Real xo, yo, zo, vx, vy, vz, xu, yu, zu;
611
612   a.Direction().Coord(vx,vy,vz);
613   a.YDirection().Coord(xu,yu,zu);
614   a.Location().Coord(xo,yo,zo);
615
616   Handle(Graphic3d_Camera) aCamera = Camera();
617
618   aCamera->SetCenter (gp_Pnt (xo, yo, zo));
619
620   if(SwitchSetFront)
621   {
622     aCamera->SetDirection (gp_Dir (vx, vy, vz));
623   }
624   else
625   {
626     aCamera->SetDirection (gp_Dir (vx, vy, vz).Reversed());
627   }
628
629   aCamera->SetUp (gp_Dir (xu, yu, zu));
630
631   SwitchSetFront = !SwitchSetFront;
632
633   ImmediateUpdate();
634 }
635
636 //=============================================================================
637 //function : Rotate
638 //purpose  :
639 //=============================================================================
640 void V3d_View::Rotate (const Standard_Real ax, 
641                        const Standard_Real ay, 
642                        const Standard_Real az, 
643                        const Standard_Boolean Start)
644 {
645   Standard_Real Ax = ax;
646   Standard_Real Ay = ay;
647   Standard_Real Az = az;
648
649   if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI;
650   else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI;
651   if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI;
652   else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI;
653   if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI;
654   else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI;
655
656   Handle(Graphic3d_Camera) aCamera = Camera();
657
658   if (Start)
659   {
660     myCamStartOpUp     = aCamera->Up();
661     myCamStartOpDir    = aCamera->Direction();
662     myCamStartOpEye    = aCamera->Eye();
663     myCamStartOpCenter = aCamera->Center();
664   }
665
666   aCamera->SetUp (myCamStartOpUp);
667   aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
668   aCamera->SetDirectionFromEye (myCamStartOpDir);
669
670   // rotate camera around 3 initial axes
671   gp_Dir aBackDir = -myCamStartOpDir;
672   gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir));
673   gp_Dir aYAxis (aBackDir.Crossed (aXAxis));
674   gp_Dir aZAxis (aXAxis.Crossed (aYAxis));
675
676   gp_Trsf aRot[3], aTrsf;
677   aRot[0].SetRotation (gp_Ax1 (myCamStartOpCenter, aYAxis), -Ax);
678   aRot[1].SetRotation (gp_Ax1 (myCamStartOpCenter, aXAxis), Ay);
679   aRot[2].SetRotation (gp_Ax1 (myCamStartOpCenter, aZAxis), Az);
680   aTrsf.Multiply (aRot[0]);
681   aTrsf.Multiply (aRot[1]);
682   aTrsf.Multiply (aRot[2]);
683
684   aCamera->Transform (aTrsf);
685
686   ImmediateUpdate();
687 }
688
689 //=============================================================================
690 //function : Rotate
691 //purpose  :
692 //=============================================================================
693 void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Standard_Real az,
694                       const Standard_Real X, const Standard_Real Y, const Standard_Real Z, const Standard_Boolean Start)
695 {
696
697   Standard_Real Ax = ax ;
698   Standard_Real Ay = ay ;
699   Standard_Real Az = az ;
700
701   if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
702   else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
703   if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
704   else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
705   if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
706   else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
707
708   Handle(Graphic3d_Camera) aCamera = Camera();
709
710   if (Start)
711   {
712     myGravityReferencePoint.SetCoord (X, Y, Z);
713     myCamStartOpUp     = aCamera->Up();
714     myCamStartOpDir    = aCamera->Direction();
715     myCamStartOpEye    = aCamera->Eye();
716     myCamStartOpCenter = aCamera->Center();
717   }
718
719   const Graphic3d_Vertex& aVref = myGravityReferencePoint;
720
721   aCamera->SetUp (myCamStartOpUp);
722   aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
723   aCamera->SetDirectionFromEye (myCamStartOpDir);
724
725   // rotate camera around 3 initial axes
726   gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
727
728   gp_Dir aZAxis (aCamera->Direction().Reversed());
729   gp_Dir aYAxis (aCamera->Up());
730   gp_Dir aXAxis (aYAxis.Crossed (aZAxis)); 
731
732   gp_Trsf aRot[3], aTrsf;
733   aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
734   aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
735   aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
736   aTrsf.Multiply (aRot[0]);
737   aTrsf.Multiply (aRot[1]);
738   aTrsf.Multiply (aRot[2]);
739
740   aCamera->Transform (aTrsf);
741
742   ImmediateUpdate();
743 }
744
745 //=============================================================================
746 //function : Rotate
747 //purpose  :
748 //=============================================================================
749 void V3d_View::Rotate(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
750 {
751   switch (Axe) {
752   case V3d_X :
753     Rotate(angle,0.,0.,Start);
754     break ;
755   case V3d_Y :
756     Rotate(0.,angle,0.,Start);
757     break ;
758   case V3d_Z :
759     Rotate(0.,0.,angle,Start);
760     break ;
761   }
762 }
763
764 //=============================================================================
765 //function : Rotate
766 //purpose  :
767 //=============================================================================
768 void V3d_View::Rotate (const V3d_TypeOfAxe theAxe, const Standard_Real theAngle,
769                        const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ, const Standard_Boolean theStart)
770 {
771   Standard_Real anAngle = theAngle;
772
773   if (anAngle > 0.0) while (anAngle > DEUXPI) anAngle -= DEUXPI;
774   else if (anAngle < 0.0) while (anAngle < -DEUXPI) anAngle += DEUXPI;
775
776   Handle(Graphic3d_Camera) aCamera = Camera();
777
778   if (theStart)
779   {
780     myGravityReferencePoint.SetCoord (theX, theY, theZ);
781     myCamStartOpUp     = aCamera->Up();
782     myCamStartOpDir    = aCamera->Direction();
783     myCamStartOpEye    = aCamera->Eye();
784     myCamStartOpCenter = aCamera->Center();
785     switch (theAxe)
786     {
787       case V3d_X: myViewAxis = gp::DX(); break;
788       case V3d_Y: myViewAxis = gp::DY(); break;
789       case V3d_Z: myViewAxis = gp::DZ(); break;
790     }
791   }
792
793   const Graphic3d_Vertex& aVref = myGravityReferencePoint;
794
795   aCamera->SetUp (myCamStartOpUp);
796   aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
797   aCamera->SetDirectionFromEye (myCamStartOpDir);
798
799   // rotate camera around passed axis
800   gp_Trsf aRotation;
801   gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z());
802   gp_Dir aRAxis ((theAxe == V3d_X) ? 1.0 : 0.0,
803                  (theAxe == V3d_Y) ? 1.0 : 0.0,
804                  (theAxe == V3d_Z) ? 1.0 : 0.0);
805
806   aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), anAngle);
807
808   aCamera->Transform (aRotation);
809
810   ImmediateUpdate();
811 }
812
813 //=============================================================================
814 //function : Rotate
815 //purpose  :
816 //=============================================================================
817 void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start)
818 {
819   Standard_Real Angle = angle;
820
821   if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
822   else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
823
824   Handle(Graphic3d_Camera) aCamera = Camera();
825
826   if (Start)
827   {
828     myCamStartOpUp     = aCamera->Up();
829     myCamStartOpDir    = aCamera->Direction();
830     myCamStartOpEye    = aCamera->Eye();
831     myCamStartOpCenter = aCamera->Center();
832   }
833
834   aCamera->SetUp (myCamStartOpUp);
835   aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
836   aCamera->SetDirectionFromEye (myCamStartOpDir);
837
838   gp_Trsf aRotation;
839   gp_Pnt aRCenter (myDefaultViewPoint);
840   gp_Dir aRAxis (myDefaultViewAxis);
841   aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
842
843   aCamera->Transform (aRotation);
844
845   ImmediateUpdate();
846 }
847
848 //=============================================================================
849 //function : Turn
850 //purpose  :
851 //=============================================================================
852 void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standard_Real az, const Standard_Boolean Start)
853 {
854   Standard_Real Ax = ax;
855   Standard_Real Ay = ay;
856   Standard_Real Az = az;
857
858   if( Ax > 0. ) while ( Ax > DEUXPI ) Ax -= DEUXPI ;
859   else if( Ax < 0. ) while ( Ax < -DEUXPI ) Ax += DEUXPI ;
860   if( Ay > 0. ) while ( Ay > DEUXPI ) Ay -= DEUXPI ;
861   else if( Ay < 0. ) while ( Ay < -DEUXPI ) Ay += DEUXPI ;
862   if( Az > 0. ) while ( Az > DEUXPI ) Az -= DEUXPI ;
863   else if( Az < 0. ) while ( Az < -DEUXPI ) Az += DEUXPI ;
864
865   Handle(Graphic3d_Camera) aCamera = Camera();
866
867   if (Start)
868   {
869     myCamStartOpUp     = aCamera->Up();
870     myCamStartOpDir    = aCamera->Direction();
871     myCamStartOpEye    = aCamera->Eye();
872     myCamStartOpCenter = aCamera->Center();
873   }
874
875   aCamera->SetUp (myCamStartOpUp);
876   aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
877   aCamera->SetDirectionFromEye (myCamStartOpDir);
878
879   // rotate camera around 3 initial axes
880   gp_Pnt aRCenter = aCamera->Eye();
881   gp_Dir aZAxis (aCamera->Direction().Reversed());
882   gp_Dir aYAxis (aCamera->Up());
883   gp_Dir aXAxis (aYAxis.Crossed (aZAxis)); 
884
885   gp_Trsf aRot[3], aTrsf;
886   aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -Ax);
887   aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), Ay);
888   aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), Az);
889   aTrsf.Multiply (aRot[0]);
890   aTrsf.Multiply (aRot[1]);
891   aTrsf.Multiply (aRot[2]);
892
893   aCamera->Transform (aTrsf);
894
895   ImmediateUpdate();
896 }
897
898 //=============================================================================
899 //function : Turn
900 //purpose  :
901 //=============================================================================
902 void V3d_View::Turn(const V3d_TypeOfAxe Axe, const Standard_Real angle, const Standard_Boolean Start)
903 {
904   switch (Axe) {
905   case V3d_X :
906     Turn(angle,0.,0.,Start);
907     break ;
908   case V3d_Y :
909     Turn(0.,angle,0.,Start);
910     break ;
911   case V3d_Z :
912     Turn(0.,0.,angle,Start);
913     break ;
914   }
915 }
916
917 //=============================================================================
918 //function : Turn
919 //purpose  :
920 //=============================================================================
921 void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start)
922 {
923   Standard_Real Angle = angle ;
924
925   if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
926   else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
927
928   Handle(Graphic3d_Camera) aCamera = Camera();
929
930   if (Start)
931   {
932     myCamStartOpUp     = aCamera->Up();
933     myCamStartOpDir    = aCamera->Direction();
934     myCamStartOpEye    = aCamera->Eye();
935     myCamStartOpCenter = aCamera->Center();
936   }
937
938   aCamera->SetUp (myCamStartOpUp);
939   aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
940   aCamera->SetDirectionFromEye (myCamStartOpDir);
941
942   gp_Trsf aRotation;
943   gp_Pnt aRCenter = aCamera->Eye();
944   gp_Dir aRAxis (myDefaultViewAxis);
945   aRotation.SetRotation (gp_Ax1 (aRCenter, aRAxis), Angle);
946
947   aCamera->Transform (aRotation);
948
949   ImmediateUpdate();
950 }
951
952 //=============================================================================
953 //function : SetTwist
954 //purpose  :
955 //=============================================================================
956 void V3d_View::SetTwist(const Standard_Real angle)
957 {
958   Standard_Real Angle = angle ;
959
960   if( Angle > 0. ) while ( Angle > DEUXPI ) Angle -= DEUXPI ;
961   else if( Angle < 0. ) while ( Angle < -DEUXPI ) Angle += DEUXPI ;
962
963   Handle(Graphic3d_Camera) aCamera = Camera();
964
965   const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
966   if (!screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
967    && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
968    && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
969   {
970     throw V3d_BadValue ("V3d_ViewSetTwist, alignment of Eye,At,Up,");
971   }
972   
973   gp_Pnt aRCenter = aCamera->Center();
974   gp_Dir aZAxis (aCamera->Direction().Reversed());
975
976   gp_Trsf aTrsf;
977   aTrsf.SetRotation (gp_Ax1 (aRCenter, aZAxis), Angle);
978
979   aCamera->SetUp (gp_Dir (myYscreenAxis));
980   aCamera->Transform (aTrsf);
981
982   ImmediateUpdate();
983 }
984
985 //=============================================================================
986 //function : SetEye
987 //purpose  :
988 //=============================================================================
989 void V3d_View::SetEye(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
990 {
991   Standard_Real aTwistBefore = Twist();
992
993   Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
994
995   Handle(Graphic3d_Camera) aCamera = Camera();
996
997   aCamera->SetEye (gp_Pnt (X, Y, Z));
998
999   SetTwist (aTwistBefore);
1000
1001   SetImmediateUpdate (wasUpdateEnabled);
1002
1003   ImmediateUpdate();
1004 }
1005
1006 //=============================================================================
1007 //function : SetDepth
1008 //purpose  :
1009 //=============================================================================
1010 void V3d_View::SetDepth(const Standard_Real Depth)
1011 {
1012   V3d_BadValue_Raise_if (Depth == 0. ,"V3d_View::SetDepth, bad depth");
1013
1014   Handle(Graphic3d_Camera) aCamera = Camera();
1015
1016   if( Depth > 0. )
1017   {
1018     // Move eye using center (target) as anchor.
1019     aCamera->SetDistance (Depth);
1020   }
1021   else
1022   {
1023     // Move the view ref point instead of the eye.
1024     gp_Vec aDir (aCamera->Direction());
1025     gp_Pnt aCameraEye = aCamera->Eye();
1026     gp_Pnt aCameraCenter = aCameraEye.Translated (aDir.Multiplied (Abs (Depth)));
1027
1028     aCamera->SetCenter (aCameraCenter);
1029   }
1030
1031   ImmediateUpdate();
1032 }
1033
1034 //=============================================================================
1035 //function : SetProj
1036 //purpose  :
1037 //=============================================================================
1038 void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Standard_Real Vz )
1039 {
1040   V3d_BadValue_Raise_if( Sqrt(Vx*Vx + Vy*Vy + Vz*Vz) <= 0.,
1041     "V3d_View::SetProj, null projection vector");
1042
1043   Standard_Real aTwistBefore = Twist();
1044
1045   Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1046
1047   Camera()->SetDirection (gp_Dir (Vx, Vy, Vz).Reversed());
1048
1049   SetTwist(aTwistBefore);
1050
1051   SetImmediateUpdate (wasUpdateEnabled);
1052
1053   ImmediateUpdate();
1054 }
1055
1056 //=============================================================================
1057 //function : SetProj
1058 //purpose  :
1059 //=============================================================================
1060 void V3d_View::SetProj (const V3d_TypeOfOrientation theOrientation,
1061                         const Standard_Boolean theIsYup)
1062 {
1063   Graphic3d_Vec3d anUp = theIsYup ? Graphic3d_Vec3d (0.0, 1.0, 0.0) : Graphic3d_Vec3d (0.0, 0.0, 1.0);
1064   if (theIsYup)
1065   {
1066     if (theOrientation == V3d_Ypos
1067      || theOrientation == V3d_Yneg)
1068     {
1069       anUp.SetValues (0.0, 0.0, -1.0);
1070     }
1071   }
1072   else
1073   {
1074     if (theOrientation == V3d_Zpos)
1075     {
1076       anUp.SetValues (0.0, 1.0, 0.0);
1077     }
1078     else if (theOrientation == V3d_Zneg)
1079     {
1080       anUp.SetValues (0.0, -1.0, 0.0);
1081     }
1082   }
1083
1084   const gp_Dir aBck = V3d::GetProjAxis (theOrientation);
1085
1086   // retain camera panning from origin when switching projection
1087   const Handle(Graphic3d_Camera)& aCamera = Camera();
1088   const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
1089
1090   const Standard_Real aNewDist = aCamera->Eye().Distance (gp_Pnt (0, 0, 0));
1091   aCamera->SetEyeAndCenter (gp_XYZ (0, 0, 0) + aBck.XYZ() * aNewDist,
1092                             gp_XYZ (0, 0, 0));
1093   aCamera->SetDirectionFromEye (-aBck);
1094   aCamera->SetUp (gp_Dir (anUp.x(), anUp.y(), anUp.z()));
1095   aCamera->OrthogonalizeUp();
1096
1097   Panning (anOriginVCS.X(), anOriginVCS.Y());
1098
1099   ImmediateUpdate();
1100 }
1101
1102 //=============================================================================
1103 //function : SetAt
1104 //purpose  :
1105 //=============================================================================
1106 void V3d_View::SetAt(const Standard_Real X,const Standard_Real Y,const Standard_Real Z)
1107 {
1108   Standard_Real aTwistBefore = Twist();
1109
1110   Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1111
1112   Camera()->SetCenter (gp_Pnt (X, Y, Z));
1113
1114   SetTwist (aTwistBefore);
1115
1116   SetImmediateUpdate (wasUpdateEnabled);
1117
1118   ImmediateUpdate();
1119 }
1120
1121 //=============================================================================
1122 //function : SetUp
1123 //purpose  :
1124 //=============================================================================
1125 void V3d_View::SetUp (const Standard_Real theVx, const Standard_Real theVy, const Standard_Real theVz)
1126 {
1127   Handle(Graphic3d_Camera) aCamera = Camera();
1128
1129   const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1130   const gp_Dir anUp (theVx, theVy, theVz);
1131   if (!screenAxis (aReferencePlane, anUp,     myXscreenAxis, myYscreenAxis, myZscreenAxis)
1132    && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1133    && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1134    && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1135   {
1136     throw V3d_BadValue ("V3d_View::Setup, alignment of Eye,At,Up");
1137   }
1138
1139   aCamera->SetUp (gp_Dir (myYscreenAxis));
1140
1141   ImmediateUpdate();
1142 }
1143
1144 //=============================================================================
1145 //function : SetUp
1146 //purpose  :
1147 //=============================================================================
1148 void V3d_View::SetUp (const V3d_TypeOfOrientation theOrientation)
1149 {
1150   Handle(Graphic3d_Camera) aCamera = Camera();
1151
1152   const gp_Dir aReferencePlane (aCamera->Direction().Reversed());
1153   const gp_Dir anUp = V3d::GetProjAxis (theOrientation);
1154   if (!screenAxis (aReferencePlane, anUp,     myXscreenAxis, myYscreenAxis, myZscreenAxis)
1155    && !screenAxis (aReferencePlane, gp::DZ(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1156    && !screenAxis (aReferencePlane, gp::DY(), myXscreenAxis, myYscreenAxis, myZscreenAxis)
1157    && !screenAxis (aReferencePlane, gp::DX(), myXscreenAxis, myYscreenAxis, myZscreenAxis))
1158   {
1159     throw V3d_BadValue ("V3d_View::SetUp, alignment of Eye,At,Up");
1160   }
1161
1162   aCamera->SetUp (gp_Dir (myYscreenAxis));
1163
1164   ImmediateUpdate();
1165 }
1166
1167 //=============================================================================
1168 //function : SetViewOrientationDefault
1169 //purpose  :
1170 //=============================================================================
1171 void V3d_View::SetViewOrientationDefault()
1172 {
1173   myDefaultCamera->CopyOrientationData (Camera());
1174 }
1175
1176 //=======================================================================
1177 //function : SetViewMappingDefault
1178 //purpose  :
1179 //=======================================================================
1180 void V3d_View::SetViewMappingDefault()
1181 {
1182   myDefaultCamera->CopyMappingData (Camera());
1183 }
1184
1185 //=============================================================================
1186 //function : ResetViewOrientation
1187 //purpose  :
1188 //=============================================================================
1189 void V3d_View::ResetViewOrientation()
1190 {
1191   Camera()->CopyOrientationData (myDefaultCamera);
1192   ImmediateUpdate();
1193 }
1194
1195 //=======================================================================
1196 //function : ResetViewMapping
1197 //purpose  :
1198 //=======================================================================
1199 void V3d_View::ResetViewMapping()
1200 {
1201   Camera()->CopyMappingData (myDefaultCamera);
1202   ImmediateUpdate();
1203 }
1204
1205 //=============================================================================
1206 //function : Reset
1207 //purpose  :
1208 //=============================================================================
1209 void V3d_View::Reset (const Standard_Boolean theToUpdate)
1210 {
1211   Camera()->Copy (myDefaultCamera);
1212
1213   SwitchSetFront = Standard_False;
1214
1215   if (myImmediateUpdate || theToUpdate)
1216   {
1217     Update();
1218   }
1219 }
1220
1221 //=======================================================================
1222 //function : SetCenter
1223 //purpose  :
1224 //=======================================================================
1225 void V3d_View::SetCenter (const Standard_Integer theXp,
1226                           const Standard_Integer theYp)
1227 {
1228   Standard_Real aXv, aYv;
1229   Convert (theXp, theYp, aXv, aYv);
1230   Translate (Camera(), aXv, aYv);
1231
1232   ImmediateUpdate();
1233 }
1234
1235 //=============================================================================
1236 //function : SetSize
1237 //purpose  :
1238 //=============================================================================
1239 void V3d_View::SetSize (const Standard_Real theSize)
1240 {
1241   V3d_BadValue_Raise_if (theSize <= 0.0, "V3d_View::SetSize, Window Size is NULL");
1242
1243   Handle(Graphic3d_Camera) aCamera = Camera();
1244
1245   aCamera->SetScale (aCamera->Aspect() >= 1.0 ? theSize / aCamera->Aspect() : theSize);
1246
1247   ImmediateUpdate();
1248 }
1249
1250 //=============================================================================
1251 //function : SetZSize
1252 //purpose  :
1253 //=============================================================================
1254 void V3d_View::SetZSize (const Standard_Real theSize)
1255 {
1256   Handle(Graphic3d_Camera) aCamera = Camera();
1257
1258   Standard_Real Zmax = theSize / 2.;
1259
1260   Standard_Real aDistance = aCamera->Distance();
1261
1262   if (theSize <= 0.)
1263   {
1264     Zmax = aDistance;
1265   }
1266
1267   // ShortReal precision factor used to add meaningful tolerance to
1268   // ZNear, ZFar values in order to avoid equality after type conversion
1269   // to ShortReal matrices type.
1270   const Standard_Real aPrecision = 1.0 / Pow (10.0, ShortRealDigits() - 1);
1271
1272   Standard_Real aZFar  =  Zmax  + aDistance * 2.0;
1273   Standard_Real aZNear = -Zmax  + aDistance;
1274   aZNear              -= Abs (aZNear) * aPrecision;
1275   aZFar               += Abs (aZFar)  * aPrecision;
1276
1277   if (!aCamera->IsOrthographic())
1278   {
1279     if (aZFar < aPrecision)
1280     {
1281       // Invalid case when both values are negative
1282       aZNear = aPrecision;
1283       aZFar  = aPrecision * 2.0;
1284     }
1285     else if (aZNear < Abs (aZFar) * aPrecision)
1286     {
1287       // Z is less than 0.0, try to fix it using any appropriate z-scale
1288       aZNear = Abs (aZFar) * aPrecision;
1289     }
1290   }
1291
1292   // If range is too small
1293   if (aZFar < (aZNear + Abs (aZFar) * aPrecision))
1294   {
1295     aZFar = aZNear + Abs (aZFar) * aPrecision;
1296   }
1297
1298   aCamera->SetZRange (aZNear, aZFar);
1299
1300   if (myImmediateUpdate)
1301   {
1302     Redraw();
1303   }
1304 }
1305
1306 //=============================================================================
1307 //function : SetZoom
1308 //purpose  :
1309 //=============================================================================
1310 void V3d_View::SetZoom (const Standard_Real theCoef,const Standard_Boolean theToStart)
1311 {
1312   V3d_BadValue_Raise_if (theCoef <= 0., "V3d_View::SetZoom, bad coefficient");
1313
1314   Handle(Graphic3d_Camera) aCamera = Camera();
1315
1316   if (theToStart)
1317   {
1318     myCamStartOpEye    = aCamera->Eye();
1319     myCamStartOpCenter = aCamera->Center();
1320   }
1321
1322   Standard_Real aViewWidth  = aCamera->ViewDimensions().X();
1323   Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
1324
1325   // ensure that zoom will not be too small or too big
1326   Standard_Real aCoef = theCoef;
1327   if (aViewWidth < aCoef * Precision::Confusion())
1328   {
1329     aCoef = aViewWidth / Precision::Confusion();
1330   }
1331   else if (aViewWidth > aCoef * 1e12)
1332   {
1333     aCoef = aViewWidth / 1e12;
1334   }
1335   if (aViewHeight < aCoef * Precision::Confusion())
1336   {
1337     aCoef = aViewHeight / Precision::Confusion();
1338   }
1339   else if (aViewHeight > aCoef * 1e12)
1340   {
1341     aCoef = aViewHeight / 1e12;
1342   }
1343
1344   aCamera->SetEye (myCamStartOpEye);
1345   aCamera->SetCenter (myCamStartOpCenter);
1346   aCamera->SetScale (aCamera->Scale() / aCoef);
1347
1348   ImmediateUpdate();
1349 }
1350
1351 //=============================================================================
1352 //function : SetScale
1353 //purpose  :
1354 //=============================================================================
1355 void V3d_View::SetScale( const Standard_Real Coef )
1356 {
1357   V3d_BadValue_Raise_if( Coef <= 0. ,"V3d_View::SetScale, bad coefficient");
1358
1359   Handle(Graphic3d_Camera) aCamera = Camera();
1360
1361   Standard_Real aDefaultScale = myDefaultCamera->Scale();
1362   aCamera->SetAspect (myDefaultCamera->Aspect());
1363   aCamera->SetScale (aDefaultScale / Coef);
1364
1365   ImmediateUpdate();
1366 }
1367
1368 //=============================================================================
1369 //function : SetAxialScale
1370 //purpose  :
1371 //=============================================================================
1372 void V3d_View::SetAxialScale( const Standard_Real Sx, const Standard_Real Sy, const Standard_Real Sz )
1373 {
1374   V3d_BadValue_Raise_if( Sx <= 0. || Sy <= 0. || Sz <= 0.,"V3d_View::SetAxialScale, bad coefficient");
1375
1376   Camera()->SetAxialScale (gp_XYZ (Sx, Sy, Sz));
1377 }
1378
1379 //=============================================================================
1380 //function : SetRatio
1381 //purpose  :
1382 //=============================================================================
1383 void V3d_View::SetRatio()
1384 {
1385   if (MyWindow.IsNull())
1386   {
1387     return;
1388   }
1389
1390   Standard_Integer aWidth  = 0;
1391   Standard_Integer aHeight = 0;
1392   MyWindow->Size (aWidth, aHeight);
1393   if (aWidth > 0 && aHeight > 0)
1394   {
1395     Standard_Real aRatio = static_cast<Standard_Real> (aWidth) /
1396                            static_cast<Standard_Real> (aHeight);
1397
1398     Camera()       ->SetAspect (aRatio);
1399     myDefaultCamera->SetAspect (aRatio);
1400   }
1401 }
1402
1403 //=============================================================================
1404 //function : FitAll
1405 //purpose  :
1406 //=============================================================================
1407 void V3d_View::FitAll (const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1408 {
1409   FitAll (myView->MinMaxValues(), theMargin, theToUpdate);
1410 }
1411
1412 //=============================================================================
1413 //function : FitAll
1414 //purpose  :
1415 //=============================================================================
1416 void V3d_View::FitAll (const Bnd_Box& theBox, const Standard_Real theMargin, const Standard_Boolean theToUpdate)
1417 {
1418   Standard_ASSERT_RAISE(theMargin >= 0.0 && theMargin < 1.0, "Invalid margin coefficient");
1419
1420   if (myView->NumberOfDisplayedStructures() == 0)
1421   {
1422     return;
1423   }
1424
1425   if (!FitMinMax (Camera(), theBox, theMargin, 10.0 * Precision::Confusion()))
1426   {
1427     return;
1428   }
1429
1430   if (myImmediateUpdate || theToUpdate)
1431   {
1432     Update();
1433   }
1434 }
1435
1436 //=============================================================================
1437 //function : DepthFitAll
1438 //purpose  :
1439 //=============================================================================
1440 void V3d_View::DepthFitAll(const Standard_Real Aspect,
1441                            const Standard_Real Margin)
1442 {
1443   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W,U1,V1,W1 ;
1444   Standard_Real Umin,Vmin,Wmin,Umax,Vmax,Wmax ;
1445   Standard_Real Dx,Dy,Dz,Size;
1446
1447   Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1448
1449   if((Nstruct <= 0) || (Aspect < 0.) || (Margin < 0.) || (Margin > 1.)) {
1450     ImmediateUpdate();
1451     return ;
1452   }
1453
1454   Bnd_Box aBox = myView->MinMaxValues();
1455   if (aBox.IsVoid())
1456   {
1457     ImmediateUpdate();
1458     return ;
1459   }
1460     aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1461     Project (Xmin,Ymin,Zmin,U,V,W) ;
1462     Project (Xmax,Ymax,Zmax,U1,V1,W1) ;
1463     Umin = Min(U,U1) ; Umax = Max(U,U1) ;
1464     Vmin = Min(V,V1) ; Vmax = Max(V,V1) ;
1465     Wmin = Min(W,W1) ; Wmax = Max(W,W1) ;
1466     Project (Xmin,Ymin,Zmax,U,V,W) ;
1467     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1468     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1469     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1470     Project (Xmax,Ymin,Zmax,U,V,W) ;
1471     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1472     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1473     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1474     Project (Xmax,Ymin,Zmin,U,V,W) ;
1475     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1476     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1477     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1478     Project (Xmax,Ymax,Zmin,U,V,W) ;
1479     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1480     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1481     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1482     Project (Xmin,Ymax,Zmax,U,V,W) ;
1483     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1484     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1485     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1486     Project (Xmin,Ymax,Zmin,U,V,W) ;
1487     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1488     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1489     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1490
1491     // Adjust Z size
1492     Wmax = Max(Abs(Wmin),Abs(Wmax)) ;
1493     Dz = 2.*Wmax + Margin * Wmax;
1494
1495     // Compute depth value
1496     Dx = Abs(Umax - Umin) ; Dy = Abs(Vmax - Vmin) ; // Dz = Abs(Wmax - Wmin);
1497     Dx += Margin * Dx; Dy += Margin * Dy;
1498     Size = Sqrt(Dx*Dx + Dy*Dy + Dz*Dz);
1499     if( Size > 0. ) {
1500       SetZSize(Size) ;
1501       SetDepth( Aspect * Size / 2.);
1502     }
1503
1504     ImmediateUpdate();
1505 }
1506
1507 //=======================================================================
1508 //function : WindowFit
1509 //purpose  :
1510 //=======================================================================
1511 void V3d_View::WindowFit (const Standard_Integer theMinXp,
1512                           const Standard_Integer theMinYp,
1513                           const Standard_Integer theMaxXp,
1514                           const Standard_Integer theMaxYp)
1515 {
1516   Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
1517
1518   Handle(Graphic3d_Camera) aCamera = Camera();
1519
1520   if (!aCamera->IsOrthographic())
1521   {
1522     // normalize view coordinates
1523     Standard_Integer aWinWidth, aWinHeight;
1524     MyWindow->Size (aWinWidth, aWinHeight);
1525
1526     // z coordinate of camera center
1527     Standard_Real aDepth = aCamera->Project (aCamera->Center()).Z();
1528
1529     // camera projection coordinate are in NDC which are normalized [-1, 1]
1530     Standard_Real aUMin = (2.0 / aWinWidth) * theMinXp  - 1.0;
1531     Standard_Real aUMax = (2.0 / aWinWidth) * theMaxXp  - 1.0;
1532     Standard_Real aVMin = (2.0 / aWinHeight) * theMinYp - 1.0;
1533     Standard_Real aVMax = (2.0 / aWinHeight) * theMaxYp - 1.0;
1534
1535     // compute camera panning
1536     gp_Pnt aScreenCenter (0.0, 0.0, aDepth);
1537     gp_Pnt aFitCenter ((aUMin + aUMax) * 0.5, (aVMin + aVMax) * 0.5, aDepth);
1538     gp_Pnt aPanTo = aCamera->ConvertProj2View (aFitCenter);
1539     gp_Pnt aPanFrom = aCamera->ConvertProj2View (aScreenCenter);
1540     gp_Vec aPanVec (aPanFrom, aPanTo);
1541
1542     // compute section size
1543     gp_Pnt aFitTopRight (aUMax, aVMax, aDepth);
1544     gp_Pnt aFitBotLeft (aUMin, aVMin, aDepth);
1545     gp_Pnt aViewBotLeft = aCamera->ConvertProj2View (aFitBotLeft);
1546     gp_Pnt aViewTopRight = aCamera->ConvertProj2View (aFitTopRight);
1547
1548     Standard_Real aUSize = aViewTopRight.X() - aViewBotLeft.X();
1549     Standard_Real aVSize = aViewTopRight.Y() - aViewBotLeft.Y();
1550
1551     Translate (aCamera, aPanVec.X(), -aPanVec.Y());
1552     Scale (aCamera, aUSize, aVSize);
1553   }
1554   else
1555   {
1556     Standard_Real aX1, aY1, aX2, aY2;
1557     Convert (theMinXp, theMinYp, aX1, aY1);
1558     Convert (theMaxXp, theMaxYp, aX2, aY2);
1559     FitAll (aX1, aY1, aX2, aY2);
1560   }
1561
1562   SetImmediateUpdate (wasUpdateEnabled);
1563
1564   ImmediateUpdate();
1565 }
1566
1567 //=======================================================================
1568 //function : ConvertToGrid
1569 //purpose  :
1570 //=======================================================================
1571 void V3d_View::ConvertToGrid(const Standard_Integer theXp,
1572                              const Standard_Integer theYp,
1573                              Standard_Real& theXg,
1574                              Standard_Real& theYg,
1575                              Standard_Real& theZg) const
1576 {
1577   Graphic3d_Vec3d anXYZ;
1578   Convert (theXp, theYp, anXYZ.x(), anXYZ.y(), anXYZ.z());
1579
1580   Graphic3d_Vertex aVrp;
1581   aVrp.SetCoord (anXYZ.x(), anXYZ.y(), anXYZ.z());
1582   if (MyViewer->IsGridActive())
1583   {
1584     Graphic3d_Vertex aNewVrp = Compute (aVrp);
1585     aNewVrp.Coord (theXg, theYg, theZg);
1586   }
1587   else
1588   {
1589     aVrp.Coord (theXg, theYg, theZg);
1590   }
1591 }
1592
1593 //=======================================================================
1594 //function : ConvertToGrid
1595 //purpose  :
1596 //=======================================================================
1597 void V3d_View::ConvertToGrid(const Standard_Real theX,
1598                              const Standard_Real theY,
1599                              const Standard_Real theZ,
1600                              Standard_Real& theXg,
1601                              Standard_Real& theYg,
1602                              Standard_Real& theZg) const
1603 {
1604   if (MyViewer->IsGridActive())
1605   {
1606     Graphic3d_Vertex aVrp (theX, theY, theZ);
1607     Graphic3d_Vertex aNewVrp = Compute (aVrp);
1608     aNewVrp.Coord (theXg, theYg, theZg);
1609   }
1610   else
1611   {
1612     theXg = theX; theYg = theY; theZg = theZ;
1613   }
1614 }
1615
1616 //=======================================================================
1617 //function : Convert
1618 //purpose  :
1619 //=======================================================================
1620 Standard_Real V3d_View::Convert(const Standard_Integer Vp) const
1621 {
1622   Standard_Integer aDxw, aDyw ;
1623
1624   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1625
1626   MyWindow->Size (aDxw, aDyw);
1627   Standard_Real aValue;
1628
1629   gp_Pnt aViewDims = Camera()->ViewDimensions();
1630   aValue = aViewDims.X() * (Standard_Real)Vp / (Standard_Real)aDxw;
1631
1632   return aValue;
1633 }
1634
1635 //=======================================================================
1636 //function : Convert
1637 //purpose  :
1638 //=======================================================================
1639 void V3d_View::Convert(const Standard_Integer Xp,
1640                        const Standard_Integer Yp,
1641                        Standard_Real& Xv,
1642                        Standard_Real& Yv) const
1643 {
1644   Standard_Integer aDxw, aDyw;
1645
1646   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1647
1648   MyWindow->Size (aDxw, aDyw);
1649
1650   gp_Pnt aPoint (Xp * 2.0 / aDxw - 1.0, (aDyw - Yp) * 2.0 / aDyw - 1.0, 0.0);
1651   aPoint = Camera()->ConvertProj2View (aPoint);
1652
1653   Xv = aPoint.X();
1654   Yv = aPoint.Y();
1655 }
1656
1657 //=======================================================================
1658 //function : Convert
1659 //purpose  :
1660 //=======================================================================
1661 Standard_Integer V3d_View::Convert(const Standard_Real Vv) const
1662 {
1663   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1664
1665   Standard_Integer aDxw, aDyw;
1666   MyWindow->Size (aDxw, aDyw);
1667
1668   gp_Pnt aViewDims = Camera()->ViewDimensions();
1669   Standard_Integer aValue = RealToInt (aDxw * Vv / (aViewDims.X()));
1670
1671   return aValue;
1672 }
1673
1674 //=======================================================================
1675 //function : Convert
1676 //purpose  :
1677 //=======================================================================
1678 void V3d_View::Convert(const Standard_Real Xv,
1679                        const Standard_Real Yv,
1680                        Standard_Integer& Xp,
1681                        Standard_Integer& Yp) const
1682 {
1683   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1684
1685   Standard_Integer aDxw, aDyw;
1686   MyWindow->Size (aDxw, aDyw);
1687
1688   gp_Pnt aPoint (Xv, Yv, 0.0);
1689   aPoint = Camera()->ConvertView2Proj (aPoint);
1690   aPoint = gp_Pnt ((aPoint.X() + 1.0) * aDxw / 2.0, aDyw - (aPoint.Y() + 1.0) * aDyw / 2.0, 0.0);
1691
1692   Xp = RealToInt (aPoint.X());
1693   Yp = RealToInt (aPoint.Y());
1694 }
1695
1696 //=======================================================================
1697 //function : Convert
1698 //purpose  :
1699 //=======================================================================
1700 void V3d_View::Convert(const Standard_Integer theXp,
1701                        const Standard_Integer theYp,
1702                        Standard_Real& theX,
1703                        Standard_Real& theY,
1704                        Standard_Real& theZ) const
1705 {
1706   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1707   Standard_Integer aHeight = 0, aWidth = 0;
1708   MyWindow->Size (aWidth, aHeight);
1709
1710   const gp_Pnt anXYZ (2.0 * theXp / aWidth - 1.0,
1711                       2.0 * (aHeight - 1 - theYp) / aHeight - 1.0,
1712                       Camera()->IsZeroToOneDepth() ? 0.0 : -1.0);
1713   const gp_Pnt aResult = Camera()->UnProject (anXYZ);
1714   theX = aResult.X();
1715   theY = aResult.Y();
1716   theZ = aResult.Z();
1717 }
1718
1719 //=======================================================================
1720 //function : ConvertWithProj
1721 //purpose  :
1722 //=======================================================================
1723 void V3d_View::ConvertWithProj(const Standard_Integer theXp,
1724                                const Standard_Integer theYp,
1725                                Standard_Real& theX,
1726                                Standard_Real& theY,
1727                                Standard_Real& theZ,
1728                                Standard_Real& theDx,
1729                                Standard_Real& theDy,
1730                                Standard_Real& theDz) const
1731 {
1732   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1733   Standard_Integer aHeight = 0, aWidth = 0;
1734   MyWindow->Size (aWidth, aHeight);
1735
1736   const Standard_Real anX = 2.0 * theXp / aWidth - 1.0;
1737   const Standard_Real anY = 2.0 * (aHeight - 1 - theYp) / aHeight - 1.0;
1738   const Standard_Real  aZ = 2.0 * 0.0 - 1.0;
1739
1740   const Handle(Graphic3d_Camera)& aCamera = Camera();
1741   const gp_Pnt aResult1 = aCamera->UnProject (gp_Pnt (anX, anY, aZ));
1742   const gp_Pnt aResult2 = aCamera->UnProject (gp_Pnt (anX, anY, aZ - 10.0));
1743
1744   theX = aResult1.X();
1745   theY = aResult1.Y();
1746   theZ = aResult1.Z();
1747   Graphic3d_Vec3d aNormDir (theX - aResult2.X(),
1748                             theY - aResult2.Y(),
1749                             theZ - aResult2.Z());
1750   aNormDir.Normalize();
1751
1752   theDx = aNormDir.x();
1753   theDy = aNormDir.y();
1754   theDz = aNormDir.z();
1755 }
1756
1757 //=======================================================================
1758 //function : Convert
1759 //purpose  :
1760 //=======================================================================
1761 void V3d_View::Convert(const Standard_Real X,
1762                        const Standard_Real Y,
1763                        const Standard_Real Z,
1764                        Standard_Integer& Xp,
1765                        Standard_Integer& Yp) const
1766 {
1767   V3d_UnMapped_Raise_if (!myView->IsDefined(), "view has no window");
1768   Standard_Integer aHeight, aWidth;
1769   MyWindow->Size (aWidth, aHeight);
1770
1771   gp_Pnt aPoint = Camera()->Project (gp_Pnt (X, Y, Z));
1772
1773   Xp = RealToInt ((aPoint.X() + 1) * 0.5 * aWidth);
1774   Yp = RealToInt (aHeight - 1 - (aPoint.Y() + 1) * 0.5 * aHeight);
1775 }
1776
1777 //=======================================================================
1778 //function : Project
1779 //purpose  :
1780 //=======================================================================
1781 void V3d_View::Project (const Standard_Real theX,
1782                         const Standard_Real theY,
1783                         const Standard_Real theZ,
1784                         Standard_Real& theXp,
1785                         Standard_Real& theYp) const
1786 {
1787   Standard_Real aZp;
1788   Project (theX, theY, theZ, theXp, theYp, aZp);
1789 }
1790
1791 //=======================================================================
1792 //function : Project
1793 //purpose  :
1794 //=======================================================================
1795 void V3d_View::Project (const Standard_Real theX,
1796                         const Standard_Real theY,
1797                         const Standard_Real theZ,
1798                         Standard_Real& theXp,
1799                         Standard_Real& theYp,
1800                         Standard_Real& theZp) const
1801 {
1802   Handle(Graphic3d_Camera) aCamera = Camera();
1803
1804   gp_XYZ aViewSpaceDimensions = aCamera->ViewDimensions();
1805   Standard_Real aXSize = aViewSpaceDimensions.X();
1806   Standard_Real aYSize = aViewSpaceDimensions.Y();
1807   Standard_Real aZSize = aViewSpaceDimensions.Z();
1808
1809   gp_Pnt aPoint = aCamera->Project (gp_Pnt (theX, theY, theZ));
1810
1811   // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
1812   theXp = aPoint.X() * aXSize * 0.5;
1813   theYp = aPoint.Y() * aYSize * 0.5;
1814   theZp = Camera()->IsZeroToOneDepth()
1815         ? aPoint.Z() * aZSize
1816         : aPoint.Z() * aZSize * 0.5;
1817 }
1818
1819 //=======================================================================
1820 //function : BackgroundColor
1821 //purpose  :
1822 //=======================================================================
1823 void V3d_View::BackgroundColor(const Quantity_TypeOfColor Type,
1824                                Standard_Real& V1,
1825                                Standard_Real& V2,
1826                                Standard_Real& V3) const
1827 {
1828   Quantity_Color C = BackgroundColor() ;
1829   C.Values(V1,V2,V3,Type) ;
1830 }
1831
1832 //=======================================================================
1833 //function : BackgroundColor
1834 //purpose  :
1835 //=======================================================================
1836 Quantity_Color V3d_View::BackgroundColor() const
1837 {
1838   return myView->Background().Color() ;
1839 }
1840
1841 //=======================================================================
1842 //function : GradientBackgroundColors
1843 //purpose  :
1844 //=======================================================================
1845 void V3d_View::GradientBackgroundColors (Quantity_Color& theColor1, Quantity_Color& theColor2) const
1846 {
1847   myView->GradientBackground().Colors (theColor1, theColor2);
1848 }
1849
1850 //=======================================================================
1851 //function : GradientBackground
1852 //purpose  :
1853 //=======================================================================
1854 Aspect_GradientBackground V3d_View::GradientBackground() const
1855 {
1856   return myView->GradientBackground();
1857 }
1858
1859 //=======================================================================
1860 //function : Scale
1861 //purpose  :
1862 //=======================================================================
1863 Standard_Real V3d_View::Scale() const
1864 {
1865   return myDefaultCamera->Scale() / Camera()->Scale();
1866 }
1867
1868 //=======================================================================
1869 //function : AxialScale
1870 //purpose  :
1871 //=======================================================================
1872 void V3d_View::AxialScale(Standard_Real& Sx, Standard_Real& Sy, Standard_Real& Sz) const
1873 {
1874   gp_Pnt anAxialScale = Camera()->AxialScale();
1875   Sx = anAxialScale.X();
1876   Sy = anAxialScale.Y();
1877   Sz = anAxialScale.Z();
1878 }
1879
1880 //=======================================================================
1881 //function : Size
1882 //purpose  :
1883 //=======================================================================
1884 void V3d_View::Size(Standard_Real& Width, Standard_Real& Height) const
1885 {
1886   gp_Pnt aViewDims = Camera()->ViewDimensions();
1887
1888   Width = aViewDims.X();
1889   Height = aViewDims.Y();
1890 }
1891
1892 //=======================================================================
1893 //function : ZSize
1894 //purpose  :
1895 //=======================================================================
1896 Standard_Real V3d_View::ZSize() const
1897 {
1898   gp_Pnt aViewDims = Camera()->ViewDimensions();
1899
1900   return aViewDims.Z();
1901 }
1902
1903 //=======================================================================
1904 //function : MinMax
1905 //purpose  :
1906 //=======================================================================
1907 Standard_Integer V3d_View::MinMax(Standard_Real& Umin,
1908                                   Standard_Real& Vmin,
1909                                   Standard_Real& Umax,
1910                                   Standard_Real& Vmax) const
1911 {
1912   Standard_Real Wmin,Wmax,U,V,W ;
1913   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax ;
1914   // CAL 6/11/98
1915   Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1916
1917   if( Nstruct ) {
1918     Bnd_Box aBox = myView->MinMaxValues();
1919     aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1920     Project (Xmin,Ymin,Zmin,Umin,Vmin,Wmin) ;
1921     Project (Xmax,Ymax,Zmax,Umax,Vmax,Wmax) ;
1922     Project (Xmin,Ymin,Zmax,U,V,W) ;
1923     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1924     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1925     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1926     Project (Xmax,Ymin,Zmax,U,V,W) ;
1927     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1928     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1929     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1930     Project (Xmax,Ymin,Zmin,U,V,W) ;
1931     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1932     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1933     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1934     Project (Xmax,Ymax,Zmin,U,V,W) ;
1935     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1936     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1937     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1938     Project (Xmin,Ymax,Zmax,U,V,W) ;
1939     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1940     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1941     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1942     Project (Xmin,Ymax,Zmin,U,V,W) ;
1943     Umin = Min(U,Umin) ; Umax = Max(U,Umax) ;
1944     Vmin = Min(V,Vmin) ; Vmax = Max(V,Vmax) ;
1945     Wmin = Min(W,Wmin) ; Wmax = Max(W,Wmax) ;
1946   }
1947   return Nstruct ;
1948 }
1949
1950 //=======================================================================
1951 //function : MinMax
1952 //purpose  :
1953 //=======================================================================
1954 Standard_Integer V3d_View::MinMax(Standard_Real& Xmin,
1955                                   Standard_Real& Ymin,
1956                                   Standard_Real& Zmin,
1957                                   Standard_Real& Xmax,
1958                                   Standard_Real& Ymax,
1959                                   Standard_Real& Zmax) const
1960 {
1961   // CAL 6/11/98
1962   // Standard_Integer Nstruct = (MyView->DisplayedStructures())->Extent() ;
1963   Standard_Integer Nstruct = myView->NumberOfDisplayedStructures() ;
1964
1965   if( Nstruct ) {
1966     Bnd_Box aBox = myView->MinMaxValues();
1967     aBox.Get (Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
1968   }
1969   return Nstruct ;
1970 }
1971
1972 //=======================================================================
1973 //function : GravityPoint
1974 //purpose  :
1975 //=======================================================================
1976 gp_Pnt V3d_View::GravityPoint() const
1977 {
1978   Graphic3d_MapOfStructure aSetOfStructures;
1979   myView->DisplayedStructures (aSetOfStructures);
1980
1981   Standard_Boolean hasSelection = Standard_False;
1982   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
1983        aStructIter.More(); aStructIter.Next())
1984   {
1985     if (aStructIter.Key()->IsHighlighted()
1986      && aStructIter.Key()->IsVisible())
1987     {
1988       hasSelection = Standard_True;
1989       break;
1990     }
1991   }
1992
1993   Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
1994   Standard_Integer aNbPoints = 0;
1995   gp_XYZ aResult (0.0, 0.0, 0.0);
1996   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures);
1997        aStructIter.More(); aStructIter.Next())
1998   {
1999     const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
2000     if (!aStruct->IsVisible()
2001       || aStruct->IsInfinite()
2002       || (hasSelection && !aStruct->IsHighlighted()))
2003     {
2004       continue;
2005     }
2006
2007     const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox();
2008     if (!aBox.IsValid())
2009     {
2010       continue;
2011     }
2012
2013     // skip transformation-persistent objects
2014     if (!aStruct->TransformPersistence().IsNull())
2015     {
2016       continue;
2017     }
2018
2019     // use camera projection to find gravity point
2020     Xmin = aBox.CornerMin().x();
2021     Ymin = aBox.CornerMin().y();
2022     Zmin = aBox.CornerMin().z();
2023     Xmax = aBox.CornerMax().x();
2024     Ymax = aBox.CornerMax().y();
2025     Zmax = aBox.CornerMax().z();
2026     gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2027     {
2028       gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2029       gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2030       gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2031       gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2032     };
2033
2034     for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2035     {
2036       const gp_Pnt& aBndPnt    = aPnts[aPntIt];
2037       const gp_Pnt  aProjected = Camera()->Project (aBndPnt);
2038       if (Abs (aProjected.X()) <= 1.0
2039        && Abs (aProjected.Y()) <= 1.0)
2040       {
2041         aResult += aBndPnt.XYZ();
2042         ++aNbPoints;
2043       }
2044     }
2045   }
2046
2047   if (aNbPoints == 0)
2048   {
2049     // fallback - just use bounding box of entire scene
2050     Bnd_Box aBox = myView->MinMaxValues();
2051     if (!aBox.IsVoid())
2052     {
2053       aBox.Get (Xmin, Ymin, Zmin,
2054                 Xmax, Ymax, Zmax);
2055       gp_Pnt aPnts[THE_NB_BOUND_POINTS] =
2056       {
2057         gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax),
2058         gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax),
2059         gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax),
2060         gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax)
2061       };
2062
2063       for (Standard_Integer aPntIt = 0; aPntIt < THE_NB_BOUND_POINTS; ++aPntIt)
2064       {
2065         const gp_Pnt& aBndPnt = aPnts[aPntIt];
2066         aResult += aBndPnt.XYZ();
2067         ++aNbPoints;
2068       }
2069     }
2070   }
2071
2072   if (aNbPoints > 0)
2073   {
2074     aResult /= aNbPoints;
2075   }
2076
2077   return aResult;
2078 }
2079
2080 //=======================================================================
2081 //function : Eye
2082 //purpose  :
2083 //=======================================================================
2084 void V3d_View::Eye(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2085 {
2086   gp_Pnt aCameraEye = Camera()->Eye();
2087   X = aCameraEye.X();
2088   Y = aCameraEye.Y();
2089   Z = aCameraEye.Z();
2090 }
2091
2092 //=============================================================================
2093 //function : ProjReferenceAxe
2094 //purpose  :
2095 //=============================================================================
2096 void V3d_View::ProjReferenceAxe(const Standard_Integer Xpix,
2097                                 const Standard_Integer Ypix,
2098                                 Standard_Real& XP,
2099                                 Standard_Real& YP,
2100                                 Standard_Real& ZP,
2101                                 Standard_Real& VX,
2102                                 Standard_Real& VY,
2103                                 Standard_Real& VZ) const
2104 {
2105   Standard_Real Xo,Yo,Zo;
2106
2107   Convert (Xpix, Ypix, XP, YP, ZP);
2108   if ( Type() == V3d_PERSPECTIVE ) 
2109   {
2110     FocalReferencePoint (Xo,Yo,Zo);
2111     VX = Xo - XP;
2112     VY = Yo - YP;
2113     VZ = Zo - ZP;
2114   }
2115   else 
2116   {
2117     Proj (VX,VY,VZ);
2118   }
2119 }
2120
2121 //=============================================================================
2122 //function : Depth
2123 //purpose  :
2124 //=============================================================================
2125 Standard_Real V3d_View::Depth() const
2126 {
2127   return Camera()->Distance();
2128 }
2129
2130 //=============================================================================
2131 //function : Proj
2132 //purpose  :
2133 //=============================================================================
2134 void V3d_View::Proj(Standard_Real& Dx, Standard_Real& Dy, Standard_Real& Dz) const
2135 {
2136   gp_Dir aCameraDir = Camera()->Direction().Reversed();
2137   Dx = aCameraDir.X();
2138   Dy = aCameraDir.Y();
2139   Dz = aCameraDir.Z();
2140 }
2141
2142 //=============================================================================
2143 //function : At
2144 //purpose  :
2145 //=============================================================================
2146 void V3d_View::At(Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
2147 {
2148   gp_Pnt aCameraCenter = Camera()->Center();
2149   X = aCameraCenter.X();
2150   Y = aCameraCenter.Y();
2151   Z = aCameraCenter.Z();
2152 }
2153
2154 //=============================================================================
2155 //function : Up
2156 //purpose  :
2157 //=============================================================================
2158 void V3d_View::Up(Standard_Real& Vx, Standard_Real& Vy, Standard_Real& Vz) const
2159 {
2160   gp_Dir aCameraUp = Camera()->Up();
2161   Vx = aCameraUp.X();
2162   Vy = aCameraUp.Y();
2163   Vz = aCameraUp.Z();
2164 }
2165
2166 //=============================================================================
2167 //function : Twist
2168 //purpose  :
2169 //=============================================================================
2170 Standard_Real V3d_View::Twist() const
2171 {
2172   gp_Vec Xaxis, Yaxis, Zaxis;
2173   const gp_Dir aReferencePlane (Camera()->Direction().Reversed());
2174   if (!screenAxis (aReferencePlane, gp::DZ(), Xaxis, Yaxis, Zaxis)
2175    && !screenAxis (aReferencePlane, gp::DY(), Xaxis, Yaxis, Zaxis)
2176    && !screenAxis (aReferencePlane, gp::DX(), Xaxis, Yaxis, Zaxis))
2177   {
2178     //
2179   }
2180
2181   // Compute Cross Vector From Up & Origin
2182   const gp_Dir aCameraUp = Camera()->Up();
2183   const gp_XYZ aP = Yaxis.XYZ().Crossed (aCameraUp.XYZ());
2184
2185   // compute Angle
2186   Standard_Real anAngle = ASin (Max (Min (aP.Modulus(), 1.0), -1.0));
2187   if (Yaxis.Dot (aCameraUp.XYZ()) < 0.0)
2188   {
2189     anAngle = M_PI - anAngle;
2190   }
2191   if (anAngle > 0.0
2192    && anAngle < M_PI)
2193   {
2194     const gp_Dir aProjDir = Camera()->Direction().Reversed();
2195     if (aP.Dot (aProjDir.XYZ()) < 0.0)
2196     {
2197       anAngle = DEUXPI - anAngle;
2198     }
2199   }
2200   return anAngle;
2201 }
2202
2203 //=============================================================================
2204 //function : ShadingModel
2205 //purpose  :
2206 //=============================================================================
2207 Graphic3d_TypeOfShadingModel V3d_View::ShadingModel() const
2208 {
2209   return myView->ShadingModel();
2210 }
2211
2212 //=============================================================================
2213 //function : TextureEnv
2214 //purpose  :
2215 //=============================================================================
2216 Handle(Graphic3d_TextureEnv) V3d_View::TextureEnv() const
2217 {
2218   return myView->TextureEnv();
2219 }
2220
2221 //=============================================================================
2222 //function : Visualization
2223 //purpose  :
2224 //=============================================================================
2225 V3d_TypeOfVisualization V3d_View::Visualization() const
2226 {
2227   return static_cast<V3d_TypeOfVisualization> (myView->VisualizationType());
2228 }
2229
2230 //=============================================================================
2231 //function : IfWindow
2232 //purpose  :
2233 //=============================================================================
2234 Standard_Boolean V3d_View::IfWindow() const
2235 {
2236   return myView->IsDefined();
2237 }
2238
2239 //=============================================================================
2240 //function : Type
2241 //purpose  :
2242 //=============================================================================
2243 V3d_TypeOfView V3d_View::Type() const
2244 {
2245   return Camera()->IsOrthographic() ? V3d_ORTHOGRAPHIC : V3d_PERSPECTIVE;
2246 }
2247
2248 //=============================================================================
2249 //function : SetFocale
2250 //purpose  :
2251 //=============================================================================
2252 void V3d_View::SetFocale( const Standard_Real focale )
2253 {
2254   Handle(Graphic3d_Camera) aCamera = Camera();
2255
2256   if (aCamera->IsOrthographic())
2257   {
2258     return;
2259   }
2260
2261   Standard_Real aFOVyRad = ATan (focale / (aCamera->Distance() * 2.0));
2262
2263   aCamera->SetFOVy (aFOVyRad * (360 / M_PI));
2264
2265   ImmediateUpdate();
2266 }
2267
2268 //=============================================================================
2269 //function : Focale
2270 //purpose  :
2271 //=============================================================================
2272 Standard_Real V3d_View::Focale() const
2273 {
2274   Handle(Graphic3d_Camera) aCamera = Camera();
2275
2276   if (aCamera->IsOrthographic())
2277   {
2278     return 0.0;
2279   }
2280
2281   return aCamera->Distance() * 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
2282 }
2283
2284 //=============================================================================
2285 //function : screenAxis
2286 //purpose  :
2287 //=============================================================================
2288 Standard_Boolean V3d_View::screenAxis (const gp_Dir& theVpn, const gp_Dir& theVup,
2289                                        gp_Vec& theXaxe, gp_Vec& theYaxe, gp_Vec& theZaxe)
2290 {
2291   theXaxe = theVup.XYZ().Crossed (theVpn.XYZ());
2292   if (theXaxe.Magnitude() <= gp::Resolution())
2293   {
2294     return Standard_False;
2295   }
2296   theXaxe.Normalize();
2297
2298   theYaxe = theVpn.XYZ().Crossed (theXaxe.XYZ());
2299   if (theYaxe.Magnitude() <= gp::Resolution())
2300   {
2301     return Standard_False;
2302   }
2303   theYaxe.Normalize();
2304
2305   theZaxe = theVpn.XYZ();
2306   theZaxe.Normalize();
2307   return Standard_True;
2308 }
2309
2310 //=============================================================================
2311 //function : TrsPoint
2312 //purpose  :
2313 //=============================================================================
2314 gp_XYZ V3d_View::TrsPoint (const Graphic3d_Vertex& thePnt, const TColStd_Array2OfReal& theMat)
2315 {
2316   // CAL. S3892
2317   const Standard_Integer lr = theMat.LowerRow();
2318   const Standard_Integer ur = theMat.UpperRow();
2319   const Standard_Integer lc = theMat.LowerCol();
2320   const Standard_Integer uc = theMat.UpperCol();
2321   if ((ur - lr + 1 != 4) || (uc - lc + 1 != 4))
2322   {
2323     return gp_XYZ (thePnt.X(), thePnt.Y(), thePnt.Z());
2324   }
2325
2326   Standard_Real X, Y, Z;
2327   thePnt.Coord (X,Y,Z);
2328   const Standard_Real XX = (theMat(lr,lc+3)   + X*theMat(lr,lc)   + Y*theMat(lr,lc+1)   + Z*theMat(lr,lc+2)) / theMat(lr+3,lc+3);
2329   const Standard_Real YY = (theMat(lr+1,lc+3) + X*theMat(lr+1,lc) + Y*theMat(lr+1,lc+1) + Z*theMat(lr+1,lc+2))/theMat(lr+3,lc+3);
2330   const Standard_Real ZZ = (theMat(lr+2,lc+3) + X*theMat(lr+2,lc) + Y*theMat(lr+2,lc+1) + Z*theMat(lr+2,lc+2))/theMat(lr+3,lc+3);
2331   return gp_XYZ (XX, YY, ZZ);
2332 }
2333
2334 //=======================================================================
2335 //function : Pan
2336 //purpose  :
2337 //=======================================================================
2338 void V3d_View::Pan (const Standard_Integer theDXp,
2339                     const Standard_Integer theDYp,
2340                     const Standard_Real    theZoomFactor,
2341                     const Standard_Boolean theToStart)
2342 {
2343   Panning (Convert (theDXp), Convert (theDYp), theZoomFactor, theToStart);
2344 }
2345
2346 //=======================================================================
2347 //function : Panning
2348 //purpose  :
2349 //=======================================================================
2350 void V3d_View::Panning (const Standard_Real theDXv,
2351                         const Standard_Real theDYv,
2352                         const Standard_Real theZoomFactor,
2353                         const Standard_Boolean theToStart)
2354 {
2355   Standard_ASSERT_RAISE (theZoomFactor > 0.0, "Bad zoom factor");
2356
2357   Handle(Graphic3d_Camera) aCamera = Camera();
2358
2359   if (theToStart)
2360   {
2361     myCamStartOpDir    = aCamera->Direction();
2362     myCamStartOpEye    = aCamera->Eye();
2363     myCamStartOpCenter = aCamera->Center();
2364   }
2365
2366   Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2367
2368   gp_Pnt aViewDims = aCamera->ViewDimensions();
2369
2370   aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter);
2371   aCamera->SetDirectionFromEye (myCamStartOpDir);
2372   Translate (aCamera, -theDXv, -theDYv);
2373   Scale (aCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor);
2374
2375   SetImmediateUpdate (wasUpdateEnabled);
2376
2377   ImmediateUpdate();
2378 }
2379
2380 //=======================================================================
2381 //function : Zoom
2382 //purpose  :
2383 //=======================================================================
2384 void V3d_View::Zoom (const Standard_Integer theXp1,
2385                      const Standard_Integer theYp1,
2386                      const Standard_Integer theXp2,
2387                      const Standard_Integer theYp2)
2388 {
2389   Standard_Integer aDx = theXp2 - theXp1;
2390   Standard_Integer aDy = theYp2 - theYp1;
2391   if (aDx != 0 || aDy != 0)
2392   {
2393     Standard_Real aCoeff = Sqrt( (Standard_Real)(aDx * aDx + aDy * aDy) ) / 100.0 + 1.0;
2394     aCoeff = (aDx > 0) ? aCoeff : 1.0 / aCoeff;
2395     SetZoom (aCoeff, Standard_True);
2396   }
2397 }
2398
2399 //=======================================================================
2400 //function : StartZoomAtPoint
2401 //purpose  :
2402 //=======================================================================
2403 void V3d_View::StartZoomAtPoint (const Standard_Integer theXp,
2404                                  const Standard_Integer theYp)
2405 {
2406   MyZoomAtPointX = theXp;
2407   MyZoomAtPointY = theYp;
2408 }
2409
2410 //=======================================================================
2411 //function : ZoomAtPoint
2412 //purpose  :
2413 //=======================================================================
2414 void V3d_View::ZoomAtPoint (const Standard_Integer theMouseStartX,
2415                             const Standard_Integer theMouseStartY,
2416                             const Standard_Integer theMouseEndX,
2417                             const Standard_Integer theMouseEndY)
2418 {
2419   Standard_Boolean wasUpdateEnabled = SetImmediateUpdate (Standard_False);
2420
2421   // zoom
2422   Standard_Real aDxy = Standard_Real ((theMouseEndX + theMouseEndY) - (theMouseStartX + theMouseStartY));
2423   Standard_Real aDZoom = Abs (aDxy) / 100.0 + 1.0;
2424   aDZoom = (aDxy > 0.0) ?  aDZoom : 1.0 / aDZoom;
2425
2426   V3d_BadValue_Raise_if (aDZoom <= 0.0, "V3d_View::ZoomAtPoint, bad coefficient");
2427
2428   Handle(Graphic3d_Camera) aCamera = Camera();
2429
2430   Standard_Real aViewWidth  = aCamera->ViewDimensions().X();
2431   Standard_Real aViewHeight = aCamera->ViewDimensions().Y();
2432
2433   // ensure that zoom will not be too small or too big.
2434   Standard_Real aCoef = aDZoom;
2435   if (aViewWidth < aCoef * Precision::Confusion())
2436   {
2437     aCoef = aViewWidth / Precision::Confusion();
2438   }
2439   else if (aViewWidth > aCoef * 1e12)
2440   {
2441     aCoef = aViewWidth / 1e12;
2442   }
2443   if (aViewHeight < aCoef * Precision::Confusion())
2444   {
2445     aCoef = aViewHeight / Precision::Confusion();
2446   }
2447   else if (aViewHeight > aCoef * 1e12)
2448   {
2449     aCoef = aViewHeight / 1e12;
2450   }
2451
2452   Standard_Real aZoomAtPointXv = 0.0;
2453   Standard_Real aZoomAtPointYv = 0.0;
2454   Convert (MyZoomAtPointX, MyZoomAtPointY, aZoomAtPointXv, aZoomAtPointYv);
2455
2456   Standard_Real aDxv = aZoomAtPointXv / aCoef;
2457   Standard_Real aDyv = aZoomAtPointYv / aCoef;
2458
2459   aCamera->SetScale (aCamera->Scale() / aCoef);
2460   Translate (aCamera, aZoomAtPointXv - aDxv, aZoomAtPointYv - aDyv);
2461
2462   SetImmediateUpdate (wasUpdateEnabled);
2463
2464   ImmediateUpdate();
2465 }
2466
2467 //=============================================================================
2468 //function : AxialScale
2469 //purpose  :
2470 //=============================================================================
2471 void V3d_View::AxialScale (const Standard_Integer Dx,
2472                            const Standard_Integer Dy,
2473                            const V3d_TypeOfAxe Axis)
2474 {
2475   if( Dx != 0. || Dy != 0. ) {
2476     Standard_Real Sx, Sy, Sz;
2477     AxialScale( Sx, Sy, Sz );
2478     Standard_Real dscale = Sqrt(Dx*Dx + Dy*Dy) / 100. + 1;
2479     dscale = (Dx > 0) ?  dscale : 1./dscale;
2480     if( Axis == V3d_X ) Sx = dscale;
2481     if( Axis == V3d_Y ) Sy = dscale;
2482     if( Axis == V3d_Z ) Sz = dscale;
2483     SetAxialScale( Sx, Sy, Sz );
2484   }
2485 }
2486
2487 //=============================================================================
2488 //function : FitAll
2489 //purpose  :
2490 //=============================================================================
2491 void V3d_View::FitAll(const Standard_Real theXmin,
2492                       const Standard_Real theYmin,
2493                       const Standard_Real theXmax,
2494                       const Standard_Real theYmax)
2495 {
2496   Handle(Graphic3d_Camera) aCamera = Camera();
2497   Standard_Real anAspect = aCamera->Aspect();
2498
2499   Standard_Real aFitSizeU  = Abs (theXmax - theXmin);
2500   Standard_Real aFitSizeV  = Abs (theYmax - theYmin);
2501   Standard_Real aFitAspect = aFitSizeU / aFitSizeV;
2502   if (aFitAspect >= anAspect)
2503   {
2504     aFitSizeV = aFitSizeU / anAspect;
2505   }
2506   else
2507   {
2508     aFitSizeU = aFitSizeV * anAspect;
2509   }
2510
2511   Translate (aCamera, (theXmin + theXmax) * 0.5, (theYmin + theYmax) * 0.5);
2512   Scale (aCamera, aFitSizeU, aFitSizeV);
2513
2514   ImmediateUpdate();
2515 }
2516
2517 //=============================================================================
2518 //function : StartRotation
2519 //purpose  :
2520 //=============================================================================
2521 void V3d_View::StartRotation(const Standard_Integer X,
2522                              const Standard_Integer Y,
2523                              const Standard_Real zRotationThreshold)
2524 {
2525   sx = X; sy = Y;
2526   Standard_Real x,y;
2527   Size(x,y);
2528   rx = Standard_Real(Convert(x));
2529   ry = Standard_Real(Convert(y));
2530   myRotateGravity = GravityPoint();
2531   Rotate (0.0, 0.0, 0.0,
2532           myRotateGravity.X(), myRotateGravity.Y(), myRotateGravity.Z(),
2533           Standard_True);
2534   myZRotation = Standard_False;
2535   if( zRotationThreshold > 0. ) {
2536     Standard_Real dx = Abs(sx - rx/2.);
2537     Standard_Real dy = Abs(sy - ry/2.);
2538     //  if( dx > rx/3. || dy > ry/3. ) myZRotation = Standard_True;
2539     Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
2540     if( dx > dd || dy > dd ) myZRotation = Standard_True;
2541   }
2542
2543 }
2544
2545 //=============================================================================
2546 //function : Rotation
2547 //purpose  :
2548 //=============================================================================
2549 void V3d_View::Rotation(const Standard_Integer X,
2550                         const Standard_Integer Y)
2551 {
2552   if( rx == 0. || ry == 0. ) {
2553     StartRotation(X,Y);
2554     return;
2555   }
2556   Standard_Real dx=0.,dy=0.,dz=0.;
2557   if( myZRotation ) {
2558     dz = atan2(Standard_Real(X)-rx/2., ry/2.-Standard_Real(Y)) -
2559       atan2(sx-rx/2.,ry/2.-sy);
2560   } else {
2561     dx = (Standard_Real(X) - sx) * M_PI / rx;
2562     dy = (sy - Standard_Real(Y)) * M_PI / ry;
2563   }
2564
2565   Rotate (dx, dy, dz,
2566           myRotateGravity.X(), myRotateGravity.Y(), myRotateGravity.Z(),
2567           Standard_False);
2568 }
2569
2570 //=============================================================================
2571 //function : SetComputedMode
2572 //purpose  :
2573 //=============================================================================
2574 void V3d_View::SetComputedMode (const Standard_Boolean theMode)
2575 {
2576   if (theMode)
2577   {
2578     if (myComputedMode)
2579     {
2580       myView->SetComputedMode (Standard_True);
2581     }
2582   }
2583   else
2584   {
2585     myView->SetComputedMode (Standard_False);
2586   }
2587 }
2588
2589 //=============================================================================
2590 //function : ComputedMode
2591 //purpose  :
2592 //=============================================================================
2593 Standard_Boolean V3d_View::ComputedMode() const
2594 {
2595   return myView->ComputedMode();
2596 }
2597
2598 //=============================================================================
2599 //function : SetBackFacingModel
2600 //purpose  :
2601 //=============================================================================
2602 void V3d_View::SetBackFacingModel (const Graphic3d_TypeOfBackfacingModel theModel)
2603 {
2604   myView->SetBackfacingModel (theModel);
2605   Redraw();
2606 }
2607
2608 //=============================================================================
2609 //function : BackFacingModel
2610 //purpose  :
2611 //=============================================================================
2612 Graphic3d_TypeOfBackfacingModel V3d_View::BackFacingModel() const
2613 {
2614   return myView->BackfacingModel();
2615 }
2616
2617 //=============================================================================
2618 //function : Init
2619 //purpose  :
2620 //=============================================================================
2621 void V3d_View::Init()
2622 {
2623   myComputedMode = MyViewer->ComputedMode();
2624   if (!myComputedMode || !MyViewer->DefaultComputedMode())
2625   {
2626     SetComputedMode (Standard_False);
2627   }
2628 }
2629
2630 //=============================================================================
2631 //function : Dump
2632 //purpose  :
2633 //=============================================================================
2634 Standard_Boolean V3d_View::Dump (const Standard_CString      theFile,
2635                                  const Graphic3d_BufferType& theBufferType)
2636 {
2637   Standard_Integer aWinWidth, aWinHeight;
2638   MyWindow->Size (aWinWidth, aWinHeight);
2639   Image_AlienPixMap anImage;
2640
2641   return ToPixMap (anImage, aWinWidth, aWinHeight, theBufferType) && anImage.Save (theFile);
2642 }
2643
2644 //=============================================================================
2645 //function : ToPixMap
2646 //purpose  :
2647 //=============================================================================
2648 Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
2649                                      const V3d_ImageDumpOptions& theParams)
2650 {
2651   Graphic3d_Vec2i aTargetSize (theParams.Width, theParams.Height);
2652   if (aTargetSize.x() != 0
2653    && aTargetSize.y() != 0)
2654   {
2655     // allocate image buffer for dumping
2656     if (theImage.IsEmpty()
2657      || theImage.SizeX() != Standard_Size(aTargetSize.x())
2658      || theImage.SizeY() != Standard_Size(aTargetSize.y()))
2659     {
2660       Image_Format aFormat = Image_Format_UNKNOWN;
2661       switch (theParams.BufferType)
2662       {
2663         case Graphic3d_BT_RGB:                 aFormat = Image_Format_RGB;   break;
2664         case Graphic3d_BT_RGBA:                aFormat = Image_Format_RGBA;  break;
2665         case Graphic3d_BT_Depth:               aFormat = Image_Format_GrayF; break;
2666         case Graphic3d_BT_RGB_RayTraceHdrLeft: aFormat = Image_Format_RGBF;  break;
2667         case Graphic3d_BT_Red:                 aFormat = Image_Format_Gray;  break;
2668       }
2669
2670       if (!theImage.InitZero (aFormat, Standard_Size(aTargetSize.x()), Standard_Size(aTargetSize.y())))
2671       {
2672         Message::SendFail (TCollection_AsciiString ("Fail to allocate an image ") + aTargetSize.x() + "x" + aTargetSize.y() + " for view dump");
2673         return Standard_False;
2674       }
2675     }
2676   }
2677   if (theImage.IsEmpty())
2678   {
2679     Message::SendFail ("V3d_View::ToPixMap() has been called without image dimensions");
2680     return Standard_False;
2681   }
2682   aTargetSize.x() = (Standard_Integer )theImage.SizeX();
2683   aTargetSize.y() = (Standard_Integer )theImage.SizeY();
2684
2685   Handle(Standard_Transient) aFBOPtr;
2686   Handle(Standard_Transient) aPrevFBOPtr = myView->FBO();
2687   Graphic3d_Vec2i aFBOVPSize = aTargetSize;
2688
2689   bool isTiling = false;
2690   if (theParams.TileSize > 0)
2691   {
2692     if (aFBOVPSize.x() > theParams.TileSize
2693      || aFBOVPSize.y() > theParams.TileSize)
2694     {
2695       aFBOVPSize.x() = Min (aFBOVPSize.x(), theParams.TileSize);
2696       aFBOVPSize.y() = Min (aFBOVPSize.y(), theParams.TileSize);
2697       isTiling = true;
2698     }
2699   }
2700
2701   Graphic3d_Vec2i aPrevFBOVPSize;
2702   if (!aPrevFBOPtr.IsNull())
2703   {
2704     Graphic3d_Vec2i aPrevFBOSizeMax;
2705     myView->FBOGetDimensions (aPrevFBOPtr,
2706                               aPrevFBOVPSize.x(),  aPrevFBOVPSize.y(),
2707                               aPrevFBOSizeMax.x(), aPrevFBOSizeMax.y());
2708     if (aFBOVPSize.x() <= aPrevFBOSizeMax.x()
2709      && aFBOVPSize.y() <= aPrevFBOSizeMax.y())
2710     {
2711       aFBOPtr = aPrevFBOPtr;
2712     }
2713   }
2714
2715   if (aFBOPtr.IsNull())
2716   {
2717     Standard_Integer aMaxTexSizeX = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeX);
2718     Standard_Integer aMaxTexSizeY = MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxViewDumpSizeY);
2719     if (theParams.TileSize > aMaxTexSizeX
2720      || theParams.TileSize > aMaxTexSizeY)
2721     {
2722       Message::SendFail (TCollection_AsciiString ("Image dump can not be performed - specified tile size (")
2723                        + theParams.TileSize + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")");
2724       return Standard_False;
2725     }
2726
2727     if (aFBOVPSize.x() > aMaxTexSizeX
2728      || aFBOVPSize.y() > aMaxTexSizeY)
2729     {
2730       if (MyViewer->Driver()->InquireLimit (Graphic3d_TypeOfLimit_IsWorkaroundFBO))
2731       {
2732         Message::SendWarning ("Warning, workaround for Intel driver problem with empty FBO for images with big width is applied");
2733       }
2734       Message::SendInfo (TCollection_AsciiString ("Info, tiling image dump is used, image size (")
2735                        + aFBOVPSize.x() + "x" + aFBOVPSize.y() + ") exceeds hardware limits (" + aMaxTexSizeX + "x" + aMaxTexSizeY + ")");
2736       aFBOVPSize.x() = Min (aFBOVPSize.x(), aMaxTexSizeX);
2737       aFBOVPSize.y() = Min (aFBOVPSize.y(), aMaxTexSizeY);
2738       isTiling = true;
2739     }
2740
2741     // Try to create hardware accelerated buffer
2742     aFBOPtr = myView->FBOCreate (aFBOVPSize.x(), aFBOVPSize.y());
2743   }
2744   myView->SetFBO (aFBOPtr);
2745
2746   if (aFBOPtr.IsNull())
2747   {
2748     // try to use on-screen buffer
2749     Graphic3d_Vec2i aWinSize;
2750     MyWindow->Size (aWinSize.x(), aWinSize.y());
2751     if (aFBOVPSize.x() != aWinSize.x()
2752      || aFBOVPSize.y() != aWinSize.y())
2753     {
2754       isTiling = true;
2755     }
2756     aFBOVPSize = aWinSize;
2757
2758     Message::SendWarning ("Warning, on screen buffer is used for image dump - content might be invalid");
2759   }
2760
2761   // backup camera parameters
2762   Handle(Graphic3d_Camera) aStoreMapping = new Graphic3d_Camera();
2763   Handle(Graphic3d_Camera) aCamera = Camera();
2764   aStoreMapping->Copy (aCamera);
2765   if (aCamera->IsStereo())
2766   {
2767     switch (theParams.StereoOptions)
2768     {
2769       case V3d_SDO_MONO:
2770       {
2771         aCamera->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2772         break;
2773       }
2774       case V3d_SDO_LEFT_EYE:
2775       {
2776         aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoLeftEye);
2777         break;
2778       }
2779       case V3d_SDO_RIGHT_EYE:
2780       {
2781         aCamera->SetProjectionType (Graphic3d_Camera::Projection_MonoRightEye);
2782         break;
2783       }
2784       case V3d_SDO_BLENDED:
2785       {
2786         break; // dump as is
2787       }
2788     }
2789   }
2790   if (theParams.ToAdjustAspect)
2791   {
2792     aCamera->SetAspect (Standard_Real(aTargetSize.x()) / Standard_Real(aTargetSize.y()));
2793   }
2794
2795   // render immediate structures into back buffer rather than front
2796   const Standard_Boolean aPrevImmediateMode = myView->SetImmediateModeDrawToFront (Standard_False);
2797
2798   Standard_Boolean isSuccess = Standard_True;
2799   if (!isTiling)
2800   {
2801     if (!aFBOPtr.IsNull())
2802     {
2803       myView->FBOChangeViewport (aFBOPtr, aTargetSize.x(), aTargetSize.y());
2804     }
2805     Redraw();
2806     isSuccess = isSuccess && myView->BufferDump (theImage, theParams.BufferType);
2807   }
2808   else
2809   {
2810     Image_PixMap aTilePixMap;
2811     aTilePixMap.SetTopDown (theImage.IsTopDown());
2812
2813     Graphic3d_Vec2i anOffset (0, 0);
2814     for (; anOffset.y() < aTargetSize.y(); anOffset.y() += aFBOVPSize.y())
2815     {
2816       anOffset.x() = 0;
2817       for (; anOffset.x() < aTargetSize.x(); anOffset.x() += aFBOVPSize.x())
2818       {
2819         Graphic3d_CameraTile aTileUncropped;
2820         aTileUncropped.Offset    = anOffset;
2821         aTileUncropped.TotalSize = aTargetSize;
2822         aTileUncropped.TileSize  = aFBOVPSize;
2823         const Graphic3d_CameraTile aTile = aTileUncropped.Cropped();
2824         if (aTile.TileSize.x() < 1
2825          || aTile.TileSize.y() < 1)
2826         {
2827           continue;
2828         }
2829
2830         const Standard_Integer aLeft   = aTile.Offset.x();
2831         Standard_Integer       aBottom = aTile.Offset.y();
2832         if (theImage.IsTopDown())
2833         {
2834           const Standard_Integer aTop = aTile.Offset.y() + aTile.TileSize.y();
2835           aBottom = aTargetSize.y() - aTop;
2836         }
2837         aTilePixMap.InitWrapper (theImage.Format(), theImage.ChangeData()
2838                                + theImage.SizeRowBytes() * aBottom + theImage.SizePixelBytes() * aLeft,
2839                                  aTile.TileSize.x(), aTile.TileSize.y(),
2840                                  theImage.SizeRowBytes());
2841
2842         if (!aFBOPtr.IsNull())
2843         {
2844           aCamera->SetTile (aTile);
2845           myView->FBOChangeViewport (aFBOPtr, aTile.TileSize.x(), aTile.TileSize.y());
2846         }
2847         else
2848         {
2849           // no API to resize viewport of on-screen buffer - render uncropped
2850           aCamera->SetTile (aTileUncropped);
2851         }
2852         Redraw();
2853         isSuccess = isSuccess && myView->BufferDump (aTilePixMap, theParams.BufferType);
2854         if (!isSuccess)
2855         {
2856           break;
2857         }
2858       }
2859       if (!isSuccess)
2860       {
2861         break;
2862       }
2863     }
2864   }
2865
2866   // restore state
2867   myView->SetImmediateModeDrawToFront (aPrevImmediateMode);
2868   aCamera->Copy (aStoreMapping);
2869   if (aFBOPtr != aPrevFBOPtr)
2870   {
2871     myView->FBORelease (aFBOPtr);
2872   }
2873   else if (!aPrevFBOPtr.IsNull())
2874   {
2875     myView->FBOChangeViewport (aPrevFBOPtr, aPrevFBOVPSize.x(), aPrevFBOVPSize.y());
2876   }
2877   myView->SetFBO (aPrevFBOPtr);
2878   return isSuccess;
2879 }
2880
2881 //=============================================================================
2882 //function : ImmediateUpdate
2883 //purpose  :
2884 //=============================================================================
2885 void V3d_View::ImmediateUpdate() const
2886 {
2887   if (myImmediateUpdate)
2888   {
2889     Update();
2890   }
2891 }
2892
2893 //=============================================================================
2894 //function : SetImmediateUpdate
2895 //purpose  :
2896 //=============================================================================
2897 Standard_Boolean V3d_View::SetImmediateUpdate (const Standard_Boolean theImmediateUpdate)
2898 {
2899   Standard_Boolean aPreviousMode = myImmediateUpdate;
2900   myImmediateUpdate = theImmediateUpdate;
2901   return aPreviousMode;
2902 }
2903
2904 // =======================================================================
2905 // function : SetCamera
2906 // purpose  :
2907 // =======================================================================
2908 void V3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
2909 {
2910   myView->SetCamera (theCamera);
2911
2912   ImmediateUpdate();
2913 }
2914
2915 // =======================================================================
2916 // function : GetCamera
2917 // purpose  :
2918 // =======================================================================
2919 const Handle(Graphic3d_Camera)& V3d_View::Camera() const
2920 {
2921   return myView->Camera();
2922 }
2923
2924 // =======================================================================
2925 // function : FitMinMax
2926 // purpose  : Internal
2927 // =======================================================================
2928 Standard_Boolean V3d_View::FitMinMax (const Handle(Graphic3d_Camera)& theCamera,
2929                                       const Bnd_Box& theBox,
2930                                       const Standard_Real theMargin,
2931                                       const Standard_Real theResolution,
2932                                       const Standard_Boolean theToEnlargeIfLine) const
2933 {
2934   if (!theCamera->FitMinMax (theBox, theResolution, theToEnlargeIfLine))
2935   {
2936     return Standard_False; // bounding box is out of bounds...
2937   }
2938
2939   const Standard_Real aZoomCoef = myView->ConsiderZoomPersistenceObjects();
2940   Scale (theCamera, theCamera->ViewDimensions().X() * (aZoomCoef + theMargin), theCamera->ViewDimensions().Y() * (aZoomCoef + theMargin));
2941   return Standard_True;
2942 }
2943
2944 // =======================================================================
2945 // function : Scale
2946 // purpose  : Internal
2947 // =======================================================================
2948 void V3d_View::Scale (const Handle(Graphic3d_Camera)& theCamera,
2949                       const Standard_Real theSizeXv,
2950                       const Standard_Real theSizeYv) const
2951 {
2952   Standard_Real anAspect = theCamera->Aspect();
2953   if (anAspect > 1.0)
2954   {
2955     theCamera->SetScale (Max (theSizeXv / anAspect, theSizeYv));
2956   }
2957   else
2958   {
2959     theCamera->SetScale (Max (theSizeXv, theSizeYv * anAspect));
2960   }
2961   Invalidate();
2962 }
2963
2964 // =======================================================================
2965 // function : Translate
2966 // purpose  : Internal
2967 // =======================================================================
2968 void V3d_View::Translate (const Handle(Graphic3d_Camera)& theCamera,
2969                           const Standard_Real theDXv,
2970                           const Standard_Real theDYv) const
2971 {
2972   const gp_Pnt& aCenter = theCamera->Center();
2973   const gp_Dir& aDir = theCamera->Direction();
2974   const gp_Dir& anUp = theCamera->Up();
2975   gp_Ax3 aCameraCS (aCenter, aDir.Reversed(), aDir ^ anUp);
2976
2977   gp_Vec aCameraPanXv = gp_Vec (aCameraCS.XDirection()) * theDXv;
2978   gp_Vec aCameraPanYv = gp_Vec (aCameraCS.YDirection()) * theDYv;
2979   gp_Vec aCameraPan = aCameraPanXv + aCameraPanYv;
2980   gp_Trsf aPanTrsf;
2981   aPanTrsf.SetTranslation (aCameraPan);
2982
2983   theCamera->Transform (aPanTrsf);
2984   Invalidate();
2985 }
2986
2987 // =======================================================================
2988 // function : DiagnosticInformation
2989 // purpose  :
2990 // =======================================================================
2991 void V3d_View::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
2992                                       Graphic3d_DiagnosticInfo theFlags) const
2993 {
2994   myView->DiagnosticInformation (theDict, theFlags);
2995 }
2996
2997 //=======================================================================
2998 //function : StatisticInformation
2999 //purpose  :
3000 //=======================================================================
3001 void V3d_View::StatisticInformation (TColStd_IndexedDataMapOfStringString& theDict) const
3002 {
3003   myView->StatisticInformation (theDict);
3004 }
3005
3006 // =======================================================================
3007 // function : StatisticInformation
3008 // purpose  :
3009 // =======================================================================
3010 TCollection_AsciiString V3d_View::StatisticInformation() const
3011 {
3012   return myView->StatisticInformation();
3013 }
3014
3015 //=============================================================================
3016 //function : RenderingParams
3017 //purpose  :
3018 //=============================================================================
3019 const Graphic3d_RenderingParams& V3d_View::RenderingParams() const
3020 {
3021   return myView->RenderingParams();
3022 }
3023
3024 //=============================================================================
3025 //function : ChangeRenderingParams
3026 //purpose  :
3027 //=============================================================================
3028 Graphic3d_RenderingParams& V3d_View::ChangeRenderingParams()
3029 {
3030   return myView->ChangeRenderingParams();
3031 }
3032
3033
3034 //=============================================================================
3035 //function : SetLightOn
3036 //purpose  :
3037 //=============================================================================
3038 void V3d_View::SetLightOn (const Handle(V3d_Light)& theLight)
3039 {
3040   if (!myActiveLights.Contains (theLight))
3041   {
3042     myActiveLights.Append (theLight);
3043     UpdateLights();
3044   }
3045 }
3046
3047 //=============================================================================
3048 //function : SetLightOff
3049 //purpose  :
3050 //=============================================================================
3051 void V3d_View::SetLightOff (const Handle(V3d_Light)& theLight)
3052 {
3053   if (MyViewer->IsGlobalLight (theLight))
3054     throw Standard_TypeMismatch("V3d_View::SetLightOff, the light is global");
3055   myActiveLights.Remove (theLight);
3056   UpdateLights();
3057 }
3058
3059 //=============================================================================
3060 //function : IsActiveLight
3061 //purpose  :
3062 //=============================================================================
3063 Standard_Boolean V3d_View::IsActiveLight (const Handle(V3d_Light)& theLight) const
3064 {
3065   return !theLight.IsNull()
3066        && myActiveLights.Contains (theLight);
3067 }
3068
3069 //=============================================================================
3070 //function : SetLightOn
3071 //purpose  :
3072 //=============================================================================
3073 void V3d_View::SetLightOn()
3074 {
3075   for (V3d_ListOfLightIterator aDefLightIter (MyViewer->DefinedLightIterator()); aDefLightIter.More(); aDefLightIter.Next())
3076   {
3077     if (!myActiveLights.Contains (aDefLightIter.Value()))
3078     {
3079       myActiveLights.Append (aDefLightIter.Value());
3080     }
3081   }
3082   UpdateLights();
3083 }
3084
3085 //=============================================================================
3086 //function : SetLightOff
3087 //purpose  :
3088 //=============================================================================
3089 void V3d_View::SetLightOff()
3090 {
3091   for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More();)
3092   {
3093     if (!MyViewer->IsGlobalLight (anActiveLightIter.Value()))
3094     {
3095       myActiveLights.Remove (anActiveLightIter);
3096     }
3097     else
3098     {
3099       anActiveLightIter.Next();
3100     }
3101   }
3102   UpdateLights();
3103 }
3104
3105 //=============================================================================
3106 //function : IfMoreLights
3107 //purpose  :
3108 //=============================================================================
3109 Standard_Boolean V3d_View::IfMoreLights() const
3110 {
3111   return myActiveLights.Extent() < LightLimit();
3112 }
3113
3114 //=======================================================================
3115 //function : LightLimit
3116 //purpose  :
3117 //=======================================================================
3118 Standard_Integer V3d_View::LightLimit() const
3119 {
3120   return Viewer()->Driver()->InquireLightLimit();
3121 }
3122
3123 //=======================================================================
3124 //function : AddClipPlane
3125 //purpose  :
3126 //=======================================================================
3127 void V3d_View::AddClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
3128 {
3129   Handle(Graphic3d_SequenceOfHClipPlane) aSeqOfPlanes = ClipPlanes();
3130   if (aSeqOfPlanes.IsNull())
3131   {
3132     aSeqOfPlanes = new Graphic3d_SequenceOfHClipPlane();
3133   }
3134   else
3135   {
3136     for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aSeqOfPlanes); aPlaneIt.More(); aPlaneIt.Next())
3137     {
3138       const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
3139       if (aPlane == thePlane)
3140       {
3141         // plane is already defined in view
3142         return;
3143       }
3144     }
3145   }
3146
3147   aSeqOfPlanes->Append (thePlane);
3148   SetClipPlanes (aSeqOfPlanes);
3149 }
3150
3151 //=======================================================================
3152 //function : RemoveClipPlane
3153 //purpose  :
3154 //=======================================================================
3155 void V3d_View::RemoveClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
3156 {
3157   Handle(Graphic3d_SequenceOfHClipPlane) aSeqOfPlanes = ClipPlanes();
3158   if (aSeqOfPlanes.IsNull())
3159   {
3160     return;
3161   }
3162
3163   for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aSeqOfPlanes); aPlaneIt.More(); aPlaneIt.Next())
3164   {
3165     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
3166     if (aPlane != thePlane)
3167     {
3168       continue;
3169     }
3170
3171     aSeqOfPlanes->Remove (aPlaneIt);
3172     SetClipPlanes (aSeqOfPlanes);
3173     return;
3174   }
3175 }
3176
3177 //=======================================================================
3178 //function : SetClipPlanes
3179 //purpose  :
3180 //=======================================================================
3181 void V3d_View::SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
3182 {
3183   myView->SetClipPlanes (thePlanes);
3184 }
3185
3186 //=======================================================================
3187 //function : ClipPlanes
3188 //purpose  :
3189 //=======================================================================
3190 const Handle(Graphic3d_SequenceOfHClipPlane)& V3d_View::ClipPlanes() const
3191 {
3192   return myView->ClipPlanes();
3193 }
3194
3195 //=======================================================================
3196 //function : PlaneLimit
3197 //purpose  :
3198 //=======================================================================
3199 Standard_Integer V3d_View::PlaneLimit() const
3200 {
3201   return Viewer()->Driver()->InquirePlaneLimit();
3202 }
3203
3204 //=============================================================================
3205 //function : Move
3206 //purpose  :
3207 //=============================================================================
3208 void V3d_View::Move (const Standard_Real theDx,
3209                      const Standard_Real theDy,
3210                      const Standard_Real theDz,
3211                      const Standard_Boolean theStart)
3212 {
3213   Handle(Graphic3d_Camera) aCamera = Camera();
3214   if (theStart)
3215   {
3216     myCamStartOpEye = aCamera->Eye();
3217
3218     gp_Dir aReferencePlane (aCamera->Direction().Reversed());
3219     gp_Dir anUp (aCamera->Up());
3220     if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis))
3221     {
3222       throw V3d_BadValue ("V3d_View::Translate, alignment of Eye,At,Up");
3223     }
3224   }
3225
3226   Standard_Real XX, XY, XZ, YX, YY, YZ, ZX, ZY, ZZ;
3227   myXscreenAxis.Coord (XX,XY,XZ);
3228   myYscreenAxis.Coord (YX,YY,YZ);
3229   myZscreenAxis.Coord (ZX,ZY,ZZ);
3230
3231   aCamera->SetEye (myCamStartOpEye);
3232
3233   aCamera->SetEye (aCamera->Eye().XYZ()
3234     + theDx * gp_Pnt (XX, XY, XZ).XYZ()
3235     + theDy * gp_Pnt (YX, YY, YZ).XYZ()
3236     + theDz * gp_Pnt (ZX, ZY, ZZ).XYZ()
3237     );
3238
3239   ImmediateUpdate();
3240 }
3241
3242 //=============================================================================
3243 //function : Move
3244 //purpose  :
3245 //=============================================================================
3246 void V3d_View::Move (const Standard_Real theLength, const Standard_Boolean theStart)
3247 {
3248   Handle(Graphic3d_Camera) aCamera = Camera();
3249   if (theStart)
3250   {
3251     myCamStartOpEye = aCamera->Eye();
3252   }
3253   aCamera->SetEye (myCamStartOpEye);
3254   aCamera->SetEye (aCamera->Eye().XYZ() + theLength * myDefaultViewAxis.XYZ());
3255
3256   ImmediateUpdate();
3257 }
3258
3259 //=============================================================================
3260 //function : Move
3261 //purpose  :
3262 //=============================================================================
3263 void V3d_View::Move (const V3d_TypeOfAxe theAxe,
3264                      const Standard_Real theLength,
3265                      const Standard_Boolean theStart)
3266 {
3267   switch (theAxe)
3268   {
3269     case V3d_X:
3270       Move (theLength,0.,0.,theStart);
3271       break;
3272     case V3d_Y:
3273       Move (0.,theLength,0.,theStart);
3274       break;
3275     case V3d_Z:
3276       Move (0.,0.,theLength,theStart);
3277       break;
3278   }
3279 }
3280
3281 //=============================================================================
3282 //function : Translate
3283 //purpose  :
3284 //=============================================================================
3285 void V3d_View::Translate (const Standard_Real theDx,
3286                           const Standard_Real theDy,
3287                           const Standard_Real theDz,
3288                           const Standard_Boolean theStart)
3289 {
3290   Handle(Graphic3d_Camera) aCamera = Camera();
3291   if (theStart)
3292   {
3293     myCamStartOpEye = aCamera->Eye();
3294     myCamStartOpCenter = aCamera->Center();
3295
3296     gp_Dir aReferencePlane (aCamera->Direction().Reversed());
3297     gp_Dir anUp (aCamera->Up());
3298     if (!screenAxis (aReferencePlane, anUp, myXscreenAxis, myYscreenAxis, myZscreenAxis))
3299     {
3300       throw V3d_BadValue ("V3d_View::Translate, alignment of Eye,At,Up");
3301     }
3302   }
3303
3304   aCamera->SetEye (myCamStartOpEye);
3305   aCamera->SetCenter (myCamStartOpCenter);
3306
3307   aCamera->SetCenter (aCamera->Center().XYZ()
3308     - theDx * myXscreenAxis.XYZ()
3309     - theDy * myYscreenAxis.XYZ()
3310     - theDz * myZscreenAxis.XYZ()
3311     );
3312
3313   aCamera->SetEye (aCamera->Eye().XYZ()
3314     - theDx * myXscreenAxis.XYZ()
3315     - theDy * myYscreenAxis.XYZ()
3316     - theDz * myZscreenAxis.XYZ()
3317     );
3318
3319   ImmediateUpdate();
3320 }
3321
3322 //=============================================================================
3323 //function : Translate
3324 //purpose  :
3325 //=============================================================================
3326 void V3d_View::Translate (const V3d_TypeOfAxe theAxe, const Standard_Real theLength,const Standard_Boolean theStart)
3327 {
3328   switch (theAxe)
3329   {
3330     case V3d_X:
3331       Translate (theLength,0.,0., theStart);
3332       break;
3333     case V3d_Y:
3334       Translate (0.,theLength,0., theStart);
3335       break;
3336     case V3d_Z:
3337       Translate (0.,0.,theLength, theStart);
3338       break;
3339   }
3340 }
3341
3342 //=======================================================================
3343 //function : Place
3344 //purpose  :
3345 //=======================================================================
3346 void V3d_View::Place (const Standard_Integer theXp,
3347                       const Standard_Integer theYp,
3348                       const Standard_Real theZoomFactor)
3349 {
3350   Standard_Integer aWinWidth  = 0;
3351   Standard_Integer aWinHeight = 0;
3352   View()->Window()->Size (aWinWidth, aWinHeight);
3353
3354   Standard_Integer aWinCXp = aWinWidth  / 2;
3355   Standard_Integer aWinCYp = aWinHeight / 2;
3356   Pan (aWinCXp - theXp, -(aWinCYp - theYp), theZoomFactor / Scale());
3357 }
3358
3359 //=======================================================================
3360 //function : Translate
3361 //purpose  :
3362 //=======================================================================
3363 void V3d_View::Translate (const Standard_Real theLength, const Standard_Boolean theStart)
3364 {
3365   Handle(Graphic3d_Camera) aCamera = Camera();
3366   if (theStart)
3367   {
3368     myCamStartOpCenter = aCamera->Center() ;
3369   }
3370
3371   gp_Pnt aNewCenter (myCamStartOpCenter.XYZ() - myDefaultViewAxis.XYZ() * theLength);
3372   aCamera->SetCenter (aNewCenter);
3373
3374   ImmediateUpdate();
3375 }
3376
3377 //=============================================================================
3378 //function : SetGrid
3379 //purpose  :
3380 //=============================================================================
3381 void V3d_View::SetGrid (const gp_Ax3& aPlane, const Handle(Aspect_Grid)& aGrid)
3382 {
3383   MyPlane       = aPlane;
3384   MyGrid        = aGrid;
3385
3386   Standard_Real xl, yl, zl;
3387   Standard_Real xdx, xdy, xdz;
3388   Standard_Real ydx, ydy, ydz;
3389   Standard_Real dx, dy, dz;
3390   aPlane.Location ().Coord (xl, yl, zl);
3391   aPlane.XDirection ().Coord (xdx, xdy, xdz);
3392   aPlane.YDirection ().Coord (ydx, ydy, ydz);
3393   aPlane.Direction ().Coord (dx, dy, dz);
3394
3395   Standard_Real CosAlpha = Cos (MyGrid->RotationAngle ());
3396   Standard_Real SinAlpha = Sin (MyGrid->RotationAngle ());
3397
3398   TColStd_Array2OfReal Trsf1 (1, 4, 1, 4);
3399   Trsf1 (4, 4) = 1.0;
3400   Trsf1 (4, 1) = Trsf1 (4, 2) = Trsf1 (4, 3) = 0.0;
3401   // Translation
3402   Trsf1 (1, 4) = xl,
3403   Trsf1 (2, 4) = yl,
3404   Trsf1 (3, 4) = zl;
3405   // Transformation change of marker
3406   Trsf1 (1, 1) = xdx,
3407   Trsf1 (2, 1) = xdy,
3408   Trsf1 (3, 1) = xdz,
3409   Trsf1 (1, 2) = ydx,
3410   Trsf1 (2, 2) = ydy,
3411   Trsf1 (3, 2) = ydz,
3412   Trsf1 (1, 3) = dx,
3413   Trsf1 (2, 3) = dy,
3414   Trsf1 (3, 3) = dz;
3415
3416   TColStd_Array2OfReal Trsf2 (1, 4, 1, 4);
3417   Trsf2 (4, 4) = 1.0;
3418   Trsf2 (4, 1) = Trsf2 (4, 2) = Trsf2 (4, 3) = 0.0;
3419   // Translation of the origin
3420   Trsf2 (1, 4) = -MyGrid->XOrigin (),
3421   Trsf2 (2, 4) = -MyGrid->YOrigin (),
3422   Trsf2 (3, 4) = 0.0;
3423   // Rotation Alpha around axis -Z
3424   Trsf2 (1, 1) = CosAlpha,
3425   Trsf2 (2, 1) = -SinAlpha,
3426   Trsf2 (3, 1) = 0.0,
3427   Trsf2 (1, 2) = SinAlpha,
3428   Trsf2 (2, 2) = CosAlpha,
3429   Trsf2 (3, 2) = 0.0,
3430   Trsf2 (1, 3) = 0.0,
3431   Trsf2 (2, 3) = 0.0,
3432   Trsf2 (3, 3) = 1.0;
3433
3434   Standard_Real valuetrsf;
3435   Standard_Real valueoldtrsf;
3436   Standard_Real valuenewtrsf;
3437   Standard_Integer i, j, k;
3438   // Calculation of the product of matrices
3439   for (i=1; i<=4; i++)
3440       for (j=1; j<=4; j++) {
3441     MyTrsf (i, j) = 0.0;
3442     for (k=1; k<=4; k++) {
3443         valueoldtrsf = Trsf1 (i, k);
3444         valuetrsf        = Trsf2 (k, j);
3445         valuenewtrsf = MyTrsf (i, j) + valueoldtrsf * valuetrsf;
3446         MyTrsf (i, j) = valuenewtrsf;
3447     }
3448      }
3449 }
3450
3451 //=============================================================================
3452 //function : SetGridActivity
3453 //purpose  :
3454 //=============================================================================
3455 void V3d_View::SetGridActivity (const Standard_Boolean AFlag)
3456 {
3457   if (AFlag) MyGrid->Activate ();
3458   else MyGrid->Deactivate ();
3459 }
3460
3461 //=============================================================================
3462 //function : toPolarCoords
3463 //purpose  :
3464 //=============================================================================
3465 void toPolarCoords (const Standard_Real theX, const Standard_Real theY,
3466                           Standard_Real& theR, Standard_Real& thePhi)
3467 {
3468   theR = Sqrt (theX * theX + theY * theY);
3469   thePhi = ATan2 (theY, theX);
3470 }
3471
3472 //=============================================================================
3473 //function : toCartesianCoords
3474 //purpose  :
3475 //=============================================================================
3476 void toCartesianCoords (const Standard_Real theR, const Standard_Real thePhi,
3477                               Standard_Real& theX, Standard_Real& theY)
3478 {
3479   theX = theR * Cos (thePhi);
3480   theY = theR * Sin (thePhi);
3481 }
3482
3483 //=============================================================================
3484 //function : Compute
3485 //purpose  :
3486 //=============================================================================
3487 Graphic3d_Vertex V3d_View::Compute (const Graphic3d_Vertex& theVertex) const
3488 {
3489   const Handle(Graphic3d_Camera)& aCamera = Camera();
3490   gp_Dir VPN = aCamera->Direction().Reversed(); // RefPlane
3491   gp_Dir GPN = MyPlane.Direction();
3492
3493   Standard_Real XPp = 0.0, YPp = 0.0;
3494   Project (theVertex.X(), theVertex.Y(), theVertex.Z(), XPp, YPp);
3495
3496   // Casw when the plane of the grid and the plane of the view
3497   // are perpendicular to MYEPSILON2 close radians
3498   #define MYEPSILON2 M_PI / 180.0 // Delta between 2 angles
3499   if (Abs (VPN.Angle (GPN) - M_PI / 2.) < MYEPSILON2)
3500   {
3501     return theVertex;
3502   }
3503
3504   const gp_XYZ aPnt0 = V3d_View::TrsPoint (Graphic3d_Vertex (0.0, 0.0, 0.0), MyTrsf);
3505
3506   // get grid axes in world space
3507   const gp_XYZ aPnt1 = V3d_View::TrsPoint (Graphic3d_Vertex (1.0, 0.0, 0.0), MyTrsf);
3508   gp_Vec aGridX (aPnt0, aPnt1);
3509   aGridX.Normalize();
3510
3511   const gp_XYZ aPnt2 = V3d_View::TrsPoint (Graphic3d_Vertex (0.0, 1.0, 0.0), MyTrsf);
3512   gp_Vec aGridY (aPnt0, aPnt2);
3513   aGridY.Normalize();
3514
3515   // project ray from camera onto grid plane
3516   const gp_Vec aProjection  = aCamera->IsOrthographic()
3517                             ? gp_Vec (aCamera->Direction())
3518                             : gp_Vec (aCamera->Eye(), gp_Pnt (theVertex.X(), theVertex.Y(), theVertex.Z())).Normalized();
3519   const gp_Vec aPointOrigin = gp_Vec (gp_Pnt (theVertex.X(), theVertex.Y(), theVertex.Z()), aPnt0);
3520   const Standard_Real aT    = aPointOrigin.Dot (MyPlane.Direction()) / aProjection.Dot (MyPlane.Direction());
3521   const gp_XYZ aPointOnPlane = gp_XYZ (theVertex.X(), theVertex.Y(), theVertex.Z()) + aProjection.XYZ() * aT;
3522
3523   if (Handle(Aspect_RectangularGrid) aRectGrid = Handle(Aspect_RectangularGrid)::DownCast (MyGrid))
3524   {
3525     // project point on plane to grid local space
3526     const gp_Vec aToPoint (aPnt0, aPointOnPlane);
3527     const Standard_Real anXSteps = Round (aGridX.Dot (aToPoint) / aRectGrid->XStep());
3528     const Standard_Real anYSteps = Round (aGridY.Dot (aToPoint) / aRectGrid->YStep());
3529
3530     // clamp point to grid
3531     const gp_Vec aResult = aGridX * anXSteps * aRectGrid->XStep()
3532                          + aGridY * anYSteps * aRectGrid->YStep()
3533                          + gp_Vec (aPnt0);
3534     return Graphic3d_Vertex (aResult.X(), aResult.Y(), aResult.Z());
3535   }
3536   else if (Handle(Aspect_CircularGrid) aCircleGrid = Handle(Aspect_CircularGrid)::DownCast (MyGrid))
3537   {
3538     const Standard_Real anAlpha = M_PI / Standard_Real (aCircleGrid->DivisionNumber());
3539
3540     // project point on plane to grid local space
3541     const gp_Vec aToPoint (aPnt0, aPointOnPlane);
3542     Standard_Real aLocalX = aGridX.Dot (aToPoint);
3543     Standard_Real aLocalY = aGridY.Dot (aToPoint);
3544     Standard_Real anR = 0.0, aPhi = 0.0;
3545     toPolarCoords (aLocalX, aLocalY, anR, aPhi);
3546
3547     // clamp point to grid
3548     const Standard_Real anRSteps  = Round (anR / aCircleGrid->RadiusStep());
3549     const Standard_Real aPhiSteps = Round (aPhi / anAlpha);
3550     toCartesianCoords (anRSteps * aCircleGrid->RadiusStep(), aPhiSteps * anAlpha, aLocalX, aLocalY);
3551
3552     const gp_Vec aResult = aGridX * aLocalX + aGridY * aLocalY + gp_Vec (aPnt0);
3553     return Graphic3d_Vertex (aResult.X(), aResult.Y(), aResult.Z());
3554   }
3555   return Graphic3d_Vertex (0.0, 0.0, 0.0);
3556 }
3557
3558 //=============================================================================
3559 //function : ZBufferTriedronSetup
3560 //purpose  :
3561 //=============================================================================
3562 void V3d_View::ZBufferTriedronSetup (const Quantity_Color&  theXColor,
3563                                      const Quantity_Color&  theYColor,
3564                                      const Quantity_Color&  theZColor,
3565                                      const Standard_Real    theSizeRatio,
3566                                      const Standard_Real    theAxisDiametr,
3567                                      const Standard_Integer theNbFacettes)
3568 {
3569   const Handle(V3d_Trihedron)& aTrihedron = Trihedron (true);
3570   aTrihedron->SetArrowsColor   (theXColor, theYColor, theZColor);
3571   aTrihedron->SetSizeRatio     (theSizeRatio);
3572   aTrihedron->SetNbFacets      (theNbFacettes);
3573   aTrihedron->SetArrowDiameter (theAxisDiametr);
3574 }
3575
3576 //=============================================================================
3577 //function : TriedronDisplay
3578 //purpose  :
3579 //=============================================================================
3580 void V3d_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition,
3581                                 const Quantity_Color& theColor,
3582                                 const Standard_Real theScale,
3583                                 const V3d_TypeOfVisualization theMode)
3584 {
3585   const Handle(V3d_Trihedron)& aTrihedron = Trihedron (true);
3586   aTrihedron->SetLabelsColor (theColor);
3587   aTrihedron->SetScale       (theScale);
3588   aTrihedron->SetPosition    (thePosition);
3589   aTrihedron->SetWireframe   (theMode == V3d_WIREFRAME);
3590
3591   aTrihedron->Display (*this);
3592 }
3593
3594 //=============================================================================
3595 //function : TriedronErase
3596 //purpose  :
3597 //=============================================================================
3598 void V3d_View::TriedronErase()
3599 {
3600   if (!myTrihedron.IsNull())
3601   {
3602     myTrihedron->Erase();
3603   }
3604 }
3605
3606 //=============================================================================
3607 //function : GetGraduatedTrihedron
3608 //purpose  :
3609 //=============================================================================
3610 const Graphic3d_GraduatedTrihedron& V3d_View::GetGraduatedTrihedron() const
3611 {
3612   return myView->GetGraduatedTrihedron();
3613 }
3614
3615 //=============================================================================
3616 //function : GraduatedTrihedronDisplay
3617 //purpose  :
3618 //=============================================================================
3619 void V3d_View::GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData)
3620 {
3621   myView->GraduatedTrihedronDisplay (theTrihedronData);
3622 }
3623
3624 //=============================================================================
3625 //function : GraduatedTrihedronErase
3626 //purpose  :
3627 //=============================================================================
3628 void V3d_View::GraduatedTrihedronErase()
3629 {
3630   myView->GraduatedTrihedronErase();
3631 }
3632
3633 // =======================================================================
3634 // function : DumpJson
3635 // purpose  :
3636 // =======================================================================
3637 void V3d_View::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
3638 {
3639   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
3640
3641   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myOldMouseX)
3642   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myOldMouseY)
3643   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCamStartOpUp)
3644   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCamStartOpDir)
3645   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCamStartOpEye)
3646   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCamStartOpCenter)
3647   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myDefaultCamera.get())
3648   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myView.get())
3649   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myImmediateUpdate)
3650   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsInvalidatedImmediate)
3651   
3652   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, MyViewer)
3653   for (V3d_ListOfLight::Iterator anIterator (myActiveLights); anIterator.More(); anIterator.Next())
3654   {
3655     class Handle(Graphic3d_CLight)& anActiveLight = anIterator.Value();
3656     OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, anActiveLight)
3657   }
3658   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myDefaultViewAxis)
3659   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myDefaultViewPoint)
3660   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, MyWindow.get())
3661   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, sx)
3662   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, sy)
3663   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, rx)
3664   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, ry)
3665   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myRotateGravity)
3666   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myComputedMode)
3667   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, SwitchSetFront)
3668   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myZRotation)
3669   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, MyZoomAtPointX)
3670   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, MyZoomAtPointY)
3671   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myTrihedron.get())
3672   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, MyGrid.get())
3673   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &MyPlane)
3674   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, MyGridEchoStructure.get())
3675   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, MyGridEchoGroup.get())
3676   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myXscreenAxis)
3677   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myYscreenAxis)
3678   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myZscreenAxis)
3679   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myViewAxis)
3680   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myGravityReferencePoint)
3681   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAutoZFitIsOn)
3682   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAutoZFitScaleFactor)
3683 }