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