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