8fcf7808ab09b775f51519a1545455a219cd4ce1
[occt.git] / src / Visual3d / Visual3d_View.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifdef _WIN32
16   #include <windows.h>
17 #endif
18
19
20 #include <Aspect_Background.hxx>
21 #include <Aspect_GradientBackground.hxx>
22 #include <Aspect_Window.hxx>
23 #include <Bnd_Box.hxx>
24 #include <Graphic3d_DataStructureManager.hxx>
25 #include <Graphic3d_GraphicDriver.hxx>
26 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
27 #include <Graphic3d_MapOfStructure.hxx>
28 #include <Graphic3d_Structure.hxx>
29 #include <Graphic3d_TextureEnv.hxx>
30 #include <Graphic3d_Vector.hxx>
31 #include <Graphic3d_Vertex.hxx>
32 #include <OSD.hxx>
33 #include <Standard_Type.hxx>
34 #include <TColStd_HArray2OfReal.hxx>
35 #include <Visual3d_ContextView.hxx>
36 #include <Visual3d_DepthCueingDefinitionError.hxx>
37 #include <Visual3d_Layer.hxx>
38 #include <Visual3d_Light.hxx>
39 #include <Visual3d_TransformError.hxx>
40 #include <Visual3d_View.hxx>
41 #include <Visual3d_ViewDefinitionError.hxx>
42 #include <Visual3d_ViewManager.hxx>
43 #include <Visual3d_ZClippingDefinitionError.hxx>
44
45 #if defined(_WIN32)
46   #include <WNT_Window.hxx>
47 #elif (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
48   #include <Cocoa_Window.hxx>
49 #else
50   #include <Xw_Window.hxx>
51 #endif
52
53 #include <float.h>
54
55 // =======================================================================
56 // function : Visual3d_View
57 // purpose  :
58 // =======================================================================
59 Visual3d_View::Visual3d_View (const Handle(Visual3d_ViewManager)& theMgr)
60 : myViewManager         (theMgr.operator->()),
61   myIsInComputedMode    (Standard_False),
62   myAutoZFitIsOn        (Standard_True),
63   myAutoZFitScaleFactor (1.0),
64   myStructuresUpdated   (Standard_True)
65 {
66   myHiddenObjects = new Graphic3d_NMapOfTransient();
67
68   MyCView.ViewId                  = theMgr->Identification (this);
69   MyCView.Active                  = 0;
70   MyCView.IsDeleted               = 0;
71   MyCView.WsId                    = -1;
72   MyCView.DefWindow.IsDefined     = 0;
73   MyCView.Context.NbActiveLight   = 0;
74
75   MyCView.Backfacing    = 0;
76   MyCView.ptrUnderLayer = 0;
77   MyCView.ptrOverLayer  = 0;
78   MyCView.GContext      = 0;
79   MyCView.GDisplayCB    = 0;
80   MyCView.GClientData   = 0;
81
82   myGraphicDriver = myViewManager->GraphicDriver();
83 }
84
85 // =======================================================================
86 // function : SetWindow
87 // purpose  :
88 // =======================================================================
89 void Visual3d_View::SetWindow (const Handle(Aspect_Window)&      theWindow,
90                                const Aspect_RenderingContext     theContext,
91                                const Aspect_GraphicCallbackProc& theDisplayCB,
92                                const Standard_Address            theClientData)
93 {
94   if (IsDeleted())
95   {
96     return;
97   }
98
99   MyCView.GContext    = theContext;
100   MyCView.GDisplayCB  = theDisplayCB;
101   MyCView.GClientData = theClientData;
102   SetWindow (theWindow);
103 }
104
105 // =======================================================================
106 // function : SetWindow
107 // purpose  :
108 // =======================================================================
109 void Visual3d_View::SetWindow (const Handle(Aspect_Window)& theWindow)
110 {
111   if (IsDeleted())
112   {
113     return;
114   }
115
116   MyWindow = theWindow;
117   MyCView.WsId = MyCView.ViewId;
118   MyCView.DefWindow.IsDefined = 1;
119   MyCView.DefWindow.XWindow       = theWindow->NativeHandle();
120   MyCView.DefWindow.XParentWindow = theWindow->NativeParentHandle();
121
122   Standard_Integer aWidth = 0, aHeight = 0, aLeft = 0, aTop = 0;
123   theWindow->Position (aLeft, aTop, aWidth, aHeight);
124   theWindow->Size (aWidth, aHeight);
125   MyCView.DefWindow.left = aLeft;
126   MyCView.DefWindow.top  = aTop;
127   MyCView.DefWindow.dx   = aWidth;
128   MyCView.DefWindow.dy   = aHeight;
129
130   Standard_Real R, G, B;
131   MyBackground = MyWindow->Background ();
132   MyBackground.Color().Values (R, G, B, Quantity_TOC_RGB);
133   MyCView.DefWindow.Background.r = float (R);
134   MyCView.DefWindow.Background.g = float (G);
135   MyCView.DefWindow.Background.b = float (B);
136
137   UpdateView();
138   if (!myGraphicDriver->View (MyCView))
139   {
140     Visual3d_ViewDefinitionError::Raise ("Association failed");
141   }
142
143   MyGradientBackground = MyWindow->GradientBackground();
144   SetGradientBackground(MyGradientBackground,1);
145
146   Standard_Boolean AWait = Standard_False; // => immediate update
147   myGraphicDriver->SetVisualisation (MyCView);
148   myGraphicDriver->AntiAliasing (MyCView, MyContext.AliasingIsOn());
149   myGraphicDriver->DepthCueing  (MyCView, MyContext.DepthCueingIsOn());
150   myGraphicDriver->ClipLimit    (MyCView, AWait);
151   myGraphicDriver->Environment  (MyCView);
152
153   // Make view manager z layer list consistent with the view's list.
154   myViewManager->InstallZLayers (this);
155
156   // Update planses of model clipping
157   UpdatePlanes();
158
159   // Update light sources
160   UpdateLights();
161
162   // Association view-window does not cause the display
163   // of structures that can be displayed in the new view.
164   // In fact, association view-window is done, but the
165   // display is produced only if the view is activated (Activate).
166   SetRatio();
167
168   // invalidate camera
169   const Handle(Graphic3d_Camera)& aCamera = MyCView.Context.Camera;
170   if (!aCamera.IsNull())
171   {
172     aCamera->InvalidateProjection();
173     aCamera->InvalidateOrientation();
174   }
175 }
176
177 // =======================================================================
178 // function : Window
179 // purpose  :
180 // =======================================================================
181 Handle(Aspect_Window) Visual3d_View::Window() const
182 {
183   if (!IsDefined())
184   {
185     Visual3d_ViewDefinitionError::Raise ("Window not defined");
186   }
187   return MyWindow;
188 }
189
190 // =======================================================================
191 // function : IsDefined
192 // purpose  :
193 // =======================================================================
194 Standard_Boolean Visual3d_View::IsDefined() const
195 {
196   return MyCView.DefWindow.IsDefined != 0;
197 }
198
199 // =======================================================================
200 // function : IsDeleted
201 // purpose  :
202 // =======================================================================
203 Standard_Boolean Visual3d_View::IsDeleted() const
204 {
205   return MyCView.IsDeleted != 0;
206 }
207
208 // =======================================================================
209 // function : Destroy
210 // purpose  :
211 // =======================================================================
212 void Visual3d_View::Destroy()
213 {
214   // Since myViewManager can be already destroyed,
215   // avoid attempts to access it in SetBackground()
216   myViewManager = NULL;
217   Remove();
218 }
219
220 // =======================================================================
221 // function : Remove
222 // purpose  :
223 // =======================================================================
224 void Visual3d_View::Remove()
225 {
226   if (IsDeleted()
227   || !IsDefined())
228   {
229     return;
230   }
231
232   myStructsToCompute.Clear();
233   myStructsComputed .Clear();
234   myStructsDisplayed.Clear();
235
236   Aspect_GradientBackground aBlackGrad;
237   SetBackground (Aspect_Background (Quantity_NOC_BLACK));
238   SetGradientBackground (aBlackGrad, Standard_False);
239
240   if (myViewManager != NULL)
241   {
242     myViewManager->UnIdentification (MyCView.ViewId);
243   }
244
245   myGraphicDriver->RemoveView (MyCView);
246
247   MyCView.WsId                = -1;
248   MyCView.IsDeleted           = 1;
249   MyCView.DefWindow.IsDefined = 0;
250
251   MyWindow.Nullify();
252 }
253
254 // =======================================================================
255 // function : Resized
256 // purpose  :
257 // =======================================================================
258 void Visual3d_View::Resized()
259 {
260   if (IsDeleted())
261   {
262     return;
263   }
264   else if (!IsDefined())
265   {
266     Visual3d_ViewDefinitionError::Raise ("Window not defined");
267   }
268   MyWindow->DoResize();
269   SetRatio();
270 }
271
272 // =======================================================================
273 // function : SetRatio
274 // purpose  :
275 // =======================================================================
276 void Visual3d_View::SetRatio()
277 {
278   if (IsDeleted())
279   {
280     return;
281   }
282
283   const Aspect_TypeOfUpdate anUpdateMode = myViewManager->UpdateMode();
284   myViewManager->SetUpdateMode (Aspect_TOU_WAIT);
285
286   Standard_Integer aWidth = 0, aHeight = 0, aLeft = 0, aTop = 0;
287   MyWindow->Position (aLeft, aTop, aWidth, aHeight);
288   MyCView.DefWindow.left = aLeft;
289   MyCView.DefWindow.top  = aTop;
290
291   MyWindow->Size (aWidth, aHeight);
292   if (aWidth > 0 && aHeight > 0)
293   {
294     Standard_Real aRatio = (Standard_Real)aWidth / (Standard_Real)aHeight;
295
296     MyCView.DefWindow.dx = aWidth;
297     MyCView.DefWindow.dy = aHeight;
298
299     myGraphicDriver->RatioWindow (MyCView);
300
301     // Update camera aspect
302     const Handle(Graphic3d_Camera)& aCamera = MyCView.Context.Camera;
303     if (!aCamera.IsNull())
304     {
305       aCamera->SetAspect (aRatio);
306     }
307
308     if (!myDefaultCamera.IsNull())
309     {
310       myDefaultCamera->SetAspect (aRatio);
311     }
312   }
313
314   myViewManager->SetUpdateMode (anUpdateMode);
315   Update (anUpdateMode);
316 }
317
318 // =======================================================================
319 // function : UpdateLights
320 // purpose  :
321 // =======================================================================
322 void Visual3d_View::UpdateLights()
323 {
324   if (IsDeleted()
325    || !IsDefined())
326   {
327     return;
328   }
329
330   if (MyContext.Model() == Visual3d_TOM_NONE)
331   {
332     // activate only a white ambient light
333     Graphic3d_CLight aCLight;
334     aCLight.Type        = Visual3d_TOLS_AMBIENT;
335     aCLight.IsHeadlight = Standard_False;
336     aCLight.Color.r() = aCLight.Color.g() = aCLight.Color.b() = 1.0f;
337
338     MyCView.Context.NbActiveLight = 1;
339     MyCView.Context.ActiveLight   = &aCLight;
340     myGraphicDriver->SetLight (MyCView);
341     MyCView.Context.ActiveLight   = NULL;
342     return;
343   }
344
345   MyCView.Context.NbActiveLight = Min (MyContext.NumberOfActivatedLights(),
346                                        myGraphicDriver->InquireLightLimit());
347   if (MyCView.Context.NbActiveLight < 1)
348   {
349     myGraphicDriver->SetLight (MyCView);
350     return;
351   }
352
353   // parcing of light sources
354   MyCView.Context.ActiveLight = new Graphic3d_CLight[MyCView.Context.NbActiveLight];
355   for (Standard_Integer aLightIter = 0; aLightIter < MyCView.Context.NbActiveLight; ++aLightIter)
356   {
357     MyCView.Context.ActiveLight[aLightIter] = MyContext.ActivatedLight (aLightIter + 1)->CLight();
358   }
359   myGraphicDriver->SetLight (MyCView);
360   delete[] MyCView.Context.ActiveLight;
361   MyCView.Context.ActiveLight = NULL;
362 }
363
364 // =======================================================================
365 // function : UpdatePlanes
366 // purpose  :
367 // =======================================================================
368 void Visual3d_View::UpdatePlanes()
369 {
370   MyCView.Context.ClipPlanes = MyContext.ClipPlanes();
371   if (IsDeleted() || !IsDefined())
372   {
373     return;
374   }
375
376   myGraphicDriver->SetClipPlanes (MyCView);
377 }
378
379 // =======================================================================
380 // function : SetBackground
381 // purpose  :
382 // =======================================================================
383 void Visual3d_View::SetBackground (const Aspect_Background& theBack)
384 {
385   if (IsDeleted())
386   {
387     return;
388   }
389   else if (!IsDefined())
390   {
391     Visual3d_ViewDefinitionError::Raise ("Window not defined");
392   }
393
394   // At this level, only GL can update the background.
395   // It is not necessary to call MyWindow->SetBackground (ABack); as
396   // this method starts update of window background by X
397   // (if the windowing is X)
398
399   Standard_Real R, G, B;
400   MyBackground = theBack;
401   MyBackground.Color().Values (R, G, B, Quantity_TOC_RGB);
402   MyCView.DefWindow.Background.r = float (R);
403   MyCView.DefWindow.Background.g = float (G);
404   MyCView.DefWindow.Background.b = float (B);
405
406   myGraphicDriver->Background (MyCView);
407
408   if (myViewManager != NULL)
409   {
410     Update (myViewManager->UpdateMode());
411   }
412 }
413
414 // =======================================================================
415 // function : SetGradientBackground
416 // purpose  :
417 // =======================================================================
418 void Visual3d_View::SetGradientBackground (const Aspect_GradientBackground& theBack,
419                                            const Standard_Boolean           theToUpdate)
420 {
421   if (IsDeleted())
422   {
423     return;
424   }
425   else if (!IsDefined())
426   {
427     Visual3d_ViewDefinitionError::Raise ("Window not defined");
428   }
429
430   MyGradientBackground = theBack;
431   Quantity_Color aCol1, aCol2;
432   MyGradientBackground.Colors (aCol1, aCol2);
433   myGraphicDriver->GradientBackground (MyCView, aCol1, aCol2, MyGradientBackground.BgGradientFillMethod());
434
435   if (theToUpdate)
436   {
437      Update (Aspect_TOU_ASAP);
438   }
439   else if (myViewManager != NULL)
440   {
441     Update (myViewManager->UpdateMode());
442   }
443 }
444
445 // =======================================================================
446 // function : SetBackgroundImage
447 // purpose  :
448 // =======================================================================
449 void Visual3d_View::SetBackgroundImage (const Standard_CString  theFileName,
450                                         const Aspect_FillMethod theFillStyle,
451                                         const Standard_Boolean  theToUpdate)
452 {
453   if (IsDeleted())
454   {
455     return;
456   }
457   if (!IsDefined())
458   {
459     Visual3d_ViewDefinitionError::Raise ("Window not defined");
460   }
461
462   myGraphicDriver->BackgroundImage (theFileName, MyCView, theFillStyle);
463
464   Update (theToUpdate ? Aspect_TOU_ASAP : myViewManager->UpdateMode());
465 }
466
467 // =======================================================================
468 // function : SetBgImageStyle
469 // purpose  :
470 // =======================================================================
471 void Visual3d_View::SetBgImageStyle (const Aspect_FillMethod theFillStyle,
472                                      const Standard_Boolean  theToUpdate)
473 {
474   if (IsDeleted())
475   {
476     return;
477   }
478   if (!IsDefined())
479   {
480     Visual3d_ViewDefinitionError::Raise ("Window not defined");
481   }
482
483   myGraphicDriver->SetBgImageStyle (MyCView, theFillStyle);
484
485   Update (theToUpdate ? Aspect_TOU_ASAP : myViewManager->UpdateMode());
486 }
487
488 // =======================================================================
489 // function : Background
490 // purpose  :
491 // =======================================================================
492 Aspect_Background Visual3d_View::Background() const
493 {
494   return MyBackground;
495 }
496
497 // =======================================================================
498 // function : SetBgGradientStyle
499 // purpose  :
500 // =======================================================================
501 void Visual3d_View::SetBgGradientStyle (const Aspect_GradientFillMethod theFillStyle,
502                                         const Standard_Boolean          theToUpdate)
503 {
504   if (IsDeleted())
505   {
506     return;
507   }
508   else if (!IsDefined())
509   {
510     Visual3d_ViewDefinitionError::Raise ("Window not defined");
511   }
512
513   myGraphicDriver->SetBgGradientStyle (MyCView, theFillStyle);
514
515   Update (theToUpdate ? Aspect_TOU_ASAP : myViewManager->UpdateMode());
516 }
517
518 // =======================================================================
519 // function : GradientBackground
520 // purpose  :
521 // =======================================================================
522 Aspect_GradientBackground Visual3d_View::GradientBackground() const
523 {
524   return MyGradientBackground;
525 }
526
527 // =======================================================================
528 // function : DefaultCamera
529 // purpose  :
530 // =======================================================================
531 const Handle(Graphic3d_Camera)& Visual3d_View::DefaultCamera() const
532 {
533   return myDefaultCamera;
534 }
535
536 // =======================================================================
537 // function : Camera
538 // purpose  :
539 // =======================================================================
540 const Handle(Graphic3d_Camera)& Visual3d_View::Camera() const
541 {
542   return MyCView.Context.Camera;
543 }
544
545 // =======================================================================
546 // function : SetCamera
547 // purpose  :
548 // =======================================================================
549 void Visual3d_View::SetCamera (const Handle(Graphic3d_Camera)& theCamera)
550 {
551   MyCView.Context.Camera = theCamera;
552
553   myGraphicDriver->SetCamera (MyCView);
554
555   Update (myViewManager->UpdateMode());
556 }
557
558 // =======================================================================
559 // function : SetViewOrientationDefault
560 // purpose  :
561 // =======================================================================
562 void Visual3d_View::SetViewOrientationDefault()
563 {
564   if (myDefaultCamera.IsNull())
565   {
566     myDefaultCamera = new Graphic3d_Camera();
567   }
568
569   myDefaultCamera->CopyOrientationData (MyCView.Context.Camera);
570 }
571
572 // =======================================================================
573 // function : ViewOrientationReset
574 // purpose  :
575 // =======================================================================
576 void Visual3d_View::ViewOrientationReset()
577 {
578   if (IsDeleted())
579   {
580     return;
581   }
582
583   if (!myDefaultCamera.IsNull())
584   {
585     MyCView.Context.Camera->CopyOrientationData (myDefaultCamera);
586   }
587
588   Update (myViewManager->UpdateMode());
589 }
590
591 // =======================================================================
592 // function : SetViewMappingDefault
593 // purpose  :
594 // =======================================================================
595 void Visual3d_View::SetViewMappingDefault()
596 {
597   if (myDefaultCamera.IsNull())
598   {
599     myDefaultCamera = new Graphic3d_Camera();
600   }
601   myDefaultCamera->CopyMappingData (MyCView.Context.Camera);
602 }
603
604 // =======================================================================
605 // function : ViewMappingReset
606 // purpose  :
607 // =======================================================================
608 void Visual3d_View::ViewMappingReset()
609 {
610   if (IsDeleted())
611   {
612     return;
613   }
614
615   if (!myDefaultCamera.IsNull())
616   {
617     MyCView.Context.Camera->CopyMappingData (myDefaultCamera);
618   }
619
620   Update (myViewManager->UpdateMode());
621 }
622
623 // =======================================================================
624 // function : SetContext
625 // purpose  :
626 // =======================================================================
627 void Visual3d_View::SetContext (const Visual3d_ContextView& theViewCtx)
628 {
629   if (IsDeleted())
630   {
631     return;
632   }
633
634   // To manage display only in case of change of visualisation mode
635   const bool isVisModeChanged = theViewCtx.Visualization() != MyContext.Visualization();
636   const bool isModelChanged   = theViewCtx.Model()         != MyContext.Model();
637
638   // To manage antialiasing only in case of change
639   const Standard_Boolean anAliasingModeOld = MyContext.AliasingIsOn();
640   const Standard_Boolean anAliasingModeNew = theViewCtx.AliasingIsOn();
641
642   // To manage the depth cueing only in case of change
643   const Standard_Boolean aDepthCueingModeOld = MyContext.DepthCueingIsOn();
644   const Standard_Boolean aDepthCueingModeNew = theViewCtx.DepthCueingIsOn();
645
646   const Standard_Real aDepthCueingFrontPlaneOld = MyContext.DepthCueingFrontPlane();
647   const Standard_Real aDepthCueingFrontPlaneNew = theViewCtx.DepthCueingFrontPlane();
648   const Standard_Real aDepthCueingBackPlaneOld  = MyContext.DepthCueingBackPlane();
649   const Standard_Real aDepthCueingBackPlaneNew  = theViewCtx.DepthCueingBackPlane();
650
651   // To manage the Zclipping only in case of change
652   const Standard_Boolean aFrontZClippingModeOld = MyContext.FrontZClippingIsOn();
653   const Standard_Boolean aFrontZClippingModeNew = theViewCtx.FrontZClippingIsOn();
654   const Standard_Boolean aBackZClippingModeOld  = MyContext.BackZClippingIsOn();
655   const Standard_Boolean aBackZClippingModeNew  = theViewCtx.BackZClippingIsOn();
656
657   const Standard_Real aZClippingFrontPlaneOld = MyContext.ZClippingFrontPlane();
658   const Standard_Real aZClippingFrontPlaneNew = theViewCtx.ZClippingFrontPlane();
659   const Standard_Real aZClippingBackPlaneOld  = MyContext.ZClippingBackPlane();
660   const Standard_Real aZClippingBackPlaneNew  = theViewCtx.ZClippingBackPlane();
661
662   const bool isTextEnvChanged    = theViewCtx.TextureEnv()    != MyContext.TextureEnv();
663   const bool isSurfDetailChanged = theViewCtx.SurfaceDetail() != MyContext.SurfaceDetail();
664
665   MyContext = theViewCtx;
666
667   UpdateView();
668
669   Standard_Boolean toWait = Standard_False; // => immediate update
670   if (IsDefined())
671   {
672     // management of visualization modes and types of shading.
673     if (isVisModeChanged
674      || isModelChanged)
675     {
676       myGraphicDriver->SetVisualisation (MyCView);
677     }
678
679     // management of antialiasing
680     if (anAliasingModeOld != anAliasingModeNew)
681     {
682       myGraphicDriver->AntiAliasing (MyCView, anAliasingModeNew);
683     }
684
685     // management of depth_cueing
686     if (aDepthCueingModeOld       != aDepthCueingModeNew
687      || aDepthCueingFrontPlaneOld != aDepthCueingFrontPlaneNew
688      || aDepthCueingBackPlaneOld  != aDepthCueingBackPlaneNew)
689     {
690       if (aDepthCueingModeNew
691       &&  aDepthCueingBackPlaneNew >= aDepthCueingFrontPlaneNew)
692       {
693         Visual3d_DepthCueingDefinitionError::Raise ("Bad value for DepthCueingPlanes position");
694       }
695       myGraphicDriver->DepthCueing (MyCView, aDepthCueingModeNew);
696     }
697
698     // management of Zclipping
699     if (aFrontZClippingModeOld  != aFrontZClippingModeNew
700      || aBackZClippingModeOld   != aBackZClippingModeNew
701      || aZClippingFrontPlaneOld != aZClippingFrontPlaneNew
702      || aZClippingBackPlaneOld  != aZClippingBackPlaneNew)
703     {
704       if (aBackZClippingModeNew
705        && aFrontZClippingModeNew
706        && aZClippingBackPlaneNew >= aZClippingFrontPlaneNew)
707       {
708         Visual3d_ZClippingDefinitionError::Raise ("Bad value for ZClippingPlanes position");
709       }
710
711       myGraphicDriver->ClipLimit (MyCView, toWait);
712     }
713
714     // management of textures
715     if (isTextEnvChanged
716      || isSurfDetailChanged)
717     {
718       myGraphicDriver->Environment (MyCView);
719     }
720
721     UpdatePlanes(); // Update of planes of model clipping
722     UpdateLights(); // Update of light sources
723   }
724
725   if (isVisModeChanged)
726   {
727     // Change of context =>
728     // Remove structures that cannot be displayed in the new visualisation mode.
729     // It is not necessary to warn ViewManager as this structure should not disappear from
730     // the list of structures displayed in it.
731     NCollection_Sequence<Handle(Graphic3d_Structure)> aStructs;
732     for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
733     {
734       const Handle(Graphic3d_Structure)& aStruct  = aStructIter.Key();
735       const Visual3d_TypeOfAnswer        anAnswer = acceptDisplay (aStruct->Visual());
736       if (anAnswer == Visual3d_TOA_NO
737        || anAnswer == Visual3d_TOA_COMPUTE)
738       {
739         aStructs.Append (aStruct);
740       }
741     }
742     for (NCollection_Sequence<Handle(Graphic3d_Structure)>::Iterator aStructIter (aStructs); aStructIter.More(); aStructIter.Next())
743     {
744       Erase (aStructIter.ChangeValue(), Aspect_TOU_WAIT);
745     }
746     aStructs.Clear();
747
748     // Change of context =>
749     // Display structures that can be displayed with the new visualisation mode.
750     // All structures with status Displayed are removed from the ViewManager
751     // and displayed in the view directly, if the structure is not already
752     // displayed and if the view accepts it in its context.
753     Graphic3d_MapOfStructure aMapDisplayed;
754     myViewManager->DisplayedStructures (aMapDisplayed);
755     for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aMapDisplayed); aStructIter.More(); aStructIter.Next())
756     {
757       const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
758       if (IsDisplayed (aStruct))
759       {
760         continue;
761       }
762
763       const Visual3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
764       if (anAnswer == Visual3d_TOA_YES
765        || anAnswer == Visual3d_TOA_COMPUTE)
766       {
767         aStructs.Append (aStruct);
768       }
769     }
770
771     for (NCollection_Sequence<Handle(Graphic3d_Structure)>::Iterator aStructIter (aStructs); aStructIter.More(); aStructIter.Next())
772     {
773       Display (aStructIter.ChangeValue(), Aspect_TOU_WAIT);
774     }
775   }
776
777   Update (myViewManager->UpdateMode());
778 }
779
780 // =======================================================================
781 // function : Context
782 // purpose  :
783 // =======================================================================
784 const Visual3d_ContextView& Visual3d_View::Context() const
785 {
786   return MyContext;
787 }
788
789 // =======================================================================
790 // function : DisplayedStructures
791 // purpose  :
792 // =======================================================================
793 void Visual3d_View::DisplayedStructures (Graphic3d_MapOfStructure& theStructures) const
794 {
795   if (IsDeleted())
796   {
797     return;
798   }
799
800   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
801   {
802     theStructures.Add (aStructIter.Key());
803   }
804 }
805
806 // =======================================================================
807 // function : Activate
808 // purpose  :
809 // =======================================================================
810 void Visual3d_View::Activate()
811 {
812   if (IsDeleted())
813   {
814     return;
815   }
816   else if (!IsDefined())
817   {
818     Visual3d_ViewDefinitionError::Raise ("Window not defined");
819   }
820
821   if (!IsActive())
822   {
823     myGraphicDriver->ActivateView (MyCView);
824     myGraphicDriver->Background   (MyCView);
825
826     MyCView.Active = 1;
827
828     // Activation of a new view =>
829     // Display structures that can be displayed in this new view.
830     // All structures with status
831     // Displayed in ViewManager are returned and displayed in
832     // the view directly, if the structure is not already
833     // displayed and if the view accepts it in its context.
834     Graphic3d_MapOfStructure aDisplayedStructs;
835     myViewManager->DisplayedStructures (aDisplayedStructs);
836     for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aDisplayedStructs); aStructIter.More(); aStructIter.Next())
837     {
838       const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
839       if (IsDisplayed (aStruct))
840       {
841         continue;
842       }
843
844       // If the structure can be displayed in the new context of the view, it is displayed.
845       const Visual3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
846       if (anAnswer == Visual3d_TOA_YES
847        || anAnswer == Visual3d_TOA_COMPUTE)
848       {
849         Display (aStruct, Aspect_TOU_WAIT);
850       }
851     }
852   }
853
854   Update (myViewManager->UpdateMode());
855 }
856
857 // =======================================================================
858 // function : IsActive
859 // purpose  :
860 // =======================================================================
861 Standard_Boolean Visual3d_View::IsActive() const
862 {
863   return !IsDeleted()
864       &&  MyCView.Active;
865 }
866
867 // =======================================================================
868 // function : Deactivate
869 // purpose  :
870 // =======================================================================
871 void Visual3d_View::Deactivate()
872 {
873   if (IsDeleted())
874   {
875     return;
876   }
877   else if (!IsDefined())
878   {
879     Visual3d_ViewDefinitionError::Raise ("Window not defined");
880   }
881
882   if (IsActive())
883   {
884     myGraphicDriver->DeactivateView (MyCView);
885
886     // Deactivation of a view =>
887     // Removal of structures displayed in this view.
888     // All structures with status
889     // Displayed in ViewManager are returned and removed from
890     // the view directly, if the structure is not already
891     // displayed and if the view accepts it in its context.
892     Graphic3d_MapOfStructure aDisplayedStructs;
893     myViewManager->DisplayedStructures (aDisplayedStructs);
894     for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aDisplayedStructs); aStructIter.More(); aStructIter.Next())
895     {
896       const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key();
897       if (IsDisplayed (aStruct))
898       {
899         continue;
900       }
901
902       const Visual3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
903       if (anAnswer == Visual3d_TOA_YES
904        || anAnswer == Visual3d_TOA_COMPUTE)
905       {
906         Erase (aStruct, Aspect_TOU_WAIT);
907       }
908     }
909
910     Update (myViewManager->UpdateMode());
911     MyCView.Active = 0; // No action currently possible in the view
912   }
913 }
914
915 // =======================================================================
916 // function : Redraw
917 // purpose  :
918 // =======================================================================
919 void Visual3d_View::Redraw()
920 {
921   Redraw (myViewManager->UnderLayer(), myViewManager->OverLayer(), 0, 0, 0, 0);
922 }
923
924 // =======================================================================
925 // function : Redraw
926 // purpose  :
927 // =======================================================================
928 void Visual3d_View::Redraw (const Standard_Integer theX,
929                             const Standard_Integer theY,
930                             const Standard_Integer theWidth,
931                             const Standard_Integer theHeight)
932 {
933   Redraw (myViewManager->UnderLayer(), myViewManager->OverLayer(),
934           theX, theY, theWidth, theHeight);
935 }
936
937 // =======================================================================
938 // function : Redraw
939 // purpose  :
940 // =======================================================================
941 void Visual3d_View::Redraw (const Handle(Visual3d_Layer)& theUnderLayer,
942                             const Handle(Visual3d_Layer)& theOverLayer)
943 {
944   Redraw (theUnderLayer, theOverLayer, 0, 0, 0, 0);
945 }
946
947 // =======================================================================
948 // function : Redraw
949 // purpose  :
950 // =======================================================================
951 void Visual3d_View::Redraw (const Handle(Visual3d_Layer)& theUnderLayer,
952                             const Handle(Visual3d_Layer)& theOverLayer,
953                             const Standard_Integer        theX,
954                             const Standard_Integer        theY,
955                             const Standard_Integer        theWidth,
956                             const Standard_Integer        theHeight)
957 {
958   if (IsDeleted()
959    || !IsDefined()
960    || !IsActive()
961    || !MyWindow->IsMapped())
962   {
963     return;
964   }
965
966   Aspect_CLayer2d anOverCLayer, anUnderCLayer;
967   anOverCLayer.ptrLayer = anUnderCLayer.ptrLayer = NULL;
968   if (!theOverLayer .IsNull()) anOverCLayer  = theOverLayer ->CLayer();
969   if (!theUnderLayer.IsNull()) anUnderCLayer = theUnderLayer->CLayer();
970
971   for (Standard_Integer aRetryIter = 0; aRetryIter < 2; ++aRetryIter)
972   {
973     if (myGraphicDriver->IsDeviceLost())
974     {
975       myViewManager->RecomputeStructures();
976       myViewManager->RecomputeStructures (myImmediateStructures);
977       myGraphicDriver->ResetDeviceLostFlag();
978     }
979
980     if (myStructuresUpdated)
981     {
982       AutoZFit();
983       myStructuresUpdated = Standard_False;
984     }
985
986     myGraphicDriver->Redraw (MyCView, anUnderCLayer, anOverCLayer, theX, theY, theWidth, theHeight);
987     if (!myGraphicDriver->IsDeviceLost())
988     {
989       return;
990     }
991   }
992 }
993
994 // =======================================================================
995 // function : RedrawImmediate
996 // purpose  :
997 // =======================================================================
998 void Visual3d_View::RedrawImmediate()
999 {
1000   RedrawImmediate (myViewManager->UnderLayer(), myViewManager->OverLayer());
1001 }
1002
1003 // =======================================================================
1004 // function : RedrawImmediate
1005 // purpose  :
1006 // =======================================================================
1007 void Visual3d_View::RedrawImmediate (const Handle(Visual3d_Layer)& theUnderLayer,
1008                                      const Handle(Visual3d_Layer)& theOverLayer)
1009 {
1010   if (IsDeleted()
1011    || !IsDefined()
1012    || !IsActive()
1013    || !MyWindow->IsMapped())
1014   {
1015     return;
1016   }
1017
1018   Aspect_CLayer2d anOverCLayer, anUnderCLayer;
1019   anOverCLayer.ptrLayer = anUnderCLayer.ptrLayer = NULL;
1020   if (!theOverLayer .IsNull()) anOverCLayer  = theOverLayer ->CLayer();
1021   if (!theUnderLayer.IsNull()) anUnderCLayer = theUnderLayer->CLayer();
1022   myGraphicDriver->RedrawImmediate (MyCView, anUnderCLayer, anOverCLayer);
1023 }
1024
1025 // =======================================================================
1026 // function : Invalidate
1027 // purpose  :
1028 // =======================================================================
1029 void Visual3d_View::Invalidate()
1030 {
1031   myGraphicDriver->Invalidate (MyCView);
1032 }
1033
1034 // =======================================================================
1035 // function : Update
1036 // purpose  :
1037 // =======================================================================
1038 void Visual3d_View::Update (Aspect_TypeOfUpdate theUpdateMode)
1039 {
1040   myStructuresUpdated = Standard_True;
1041   if (theUpdateMode == Aspect_TOU_ASAP)
1042   {
1043     Compute();
1044     Redraw (myViewManager->UnderLayer(), myViewManager->OverLayer(), 0, 0, 0, 0);
1045   }
1046 }
1047
1048 // =======================================================================
1049 // function : Update
1050 // purpose  :
1051 // =======================================================================
1052 void Visual3d_View::Update (const Handle(Visual3d_Layer)& theUnderLayer,
1053                             const Handle(Visual3d_Layer)& theOverLayer)
1054 {
1055   Compute();
1056   myStructuresUpdated = Standard_True;
1057   Redraw (theUnderLayer, theOverLayer, 0, 0, 0, 0);
1058 }
1059
1060 // ========================================================================
1061 // function : SetAutoZFitMode
1062 // purpose  :
1063 // ========================================================================
1064 void Visual3d_View::SetAutoZFitMode (const Standard_Boolean theIsOn,
1065                                      const Standard_Real    theScaleFactor)
1066 {
1067   Standard_ASSERT_RAISE (theScaleFactor > 0.0, "Zero or negative scale factor is not allowed.");
1068   myAutoZFitScaleFactor = theScaleFactor;
1069   myAutoZFitIsOn = theIsOn;
1070 }
1071
1072 // ========================================================================
1073 // function : AutoZFitMode
1074 // purpose  :
1075 // ========================================================================
1076 Standard_Boolean Visual3d_View::AutoZFitMode() const
1077 {
1078   return myAutoZFitIsOn;
1079 }
1080
1081 // ========================================================================
1082 // function : AutoZFitScaleFactor
1083 // purpose  :
1084 // ========================================================================
1085 Standard_Real Visual3d_View::AutoZFitScaleFactor() const
1086 {
1087   return myAutoZFitScaleFactor;
1088 }
1089
1090 // ========================================================================
1091 // function : AutoZFit
1092 // purpose  :
1093 // ========================================================================
1094 void Visual3d_View::AutoZFit()
1095 {
1096   if (!AutoZFitMode())
1097   {
1098     return;
1099   }
1100
1101   ZFitAll (myAutoZFitScaleFactor);
1102 }
1103
1104 // ========================================================================
1105 // function : ZFitAll
1106 // purpose  :
1107 // ========================================================================
1108 void Visual3d_View::ZFitAll (const Standard_Real theScaleFactor)
1109 {
1110   Bnd_Box aMinMaxBox = MinMaxValues (Standard_False); // applicative min max boundaries
1111   Bnd_Box aGraphicBox = MinMaxValues (Standard_True); // real graphical boundaries (not accounting infinite flag).
1112
1113   const Handle(Graphic3d_Camera)& aCamera = MyCView.Context.Camera;
1114   aCamera->ZFitAll (theScaleFactor, aMinMaxBox, aGraphicBox);
1115 }
1116
1117 // ========================================================================
1118 // function : acceptDisplay
1119 // purpose  :
1120 // ========================================================================
1121 Visual3d_TypeOfAnswer Visual3d_View::acceptDisplay (const Graphic3d_TypeOfStructure theStructType) const
1122 {
1123   const Visual3d_TypeOfVisualization aViewType = MyContext.Visualization();
1124   switch (theStructType)
1125   {
1126     case Graphic3d_TOS_ALL:
1127     {
1128       return Visual3d_TOA_YES; // The structure accepts any type of view
1129     }
1130     case Graphic3d_TOS_SHADING:
1131     {
1132       return aViewType == Visual3d_TOV_SHADING
1133            ? Visual3d_TOA_YES
1134            : Visual3d_TOA_NO;
1135     }
1136     case Graphic3d_TOS_WIREFRAME:
1137     {
1138       return aViewType == Visual3d_TOV_WIREFRAME
1139            ? Visual3d_TOA_YES
1140            : Visual3d_TOA_NO;
1141     }
1142     case Graphic3d_TOS_COMPUTED:
1143     {
1144       return (aViewType == Visual3d_TOV_SHADING || aViewType == Visual3d_TOV_WIREFRAME)
1145            ?  Visual3d_TOA_COMPUTE
1146            :  Visual3d_TOA_NO;
1147     }
1148   }
1149   return Visual3d_TOA_NO;
1150 }
1151
1152 // ========================================================================
1153 // function : ChangeDisplayPriority
1154 // purpose  :
1155 // ========================================================================
1156 void Visual3d_View::ChangeDisplayPriority (const Handle(Graphic3d_Structure)& theStruct,
1157                                            const Standard_Integer           /*theOldPriority*/,
1158                                            const Standard_Integer             theNewPriority)
1159 {
1160   if (IsDeleted()
1161   || !IsDefined()
1162   || !IsActive()
1163   || !IsDisplayed (theStruct))
1164   {
1165     return;
1166   }
1167
1168   if (!myIsInComputedMode)
1169   {
1170     myGraphicDriver->ChangePriority (*theStruct->CStructure(), MyCView, theNewPriority);
1171     return;
1172   }
1173
1174   const Standard_Integer      anIndex  = IsComputed (theStruct);
1175   const Graphic3d_CStructure& aCStruct = anIndex != 0
1176                                        ? *(myStructsComputed.Value (anIndex)->CStructure())
1177                                        : *theStruct->CStructure();
1178   myGraphicDriver->ChangePriority (aCStruct, MyCView, theNewPriority);
1179 }
1180
1181 // ========================================================================
1182 // function : Clear
1183 // purpose  :
1184 // ========================================================================
1185 void Visual3d_View::Clear (const Handle(Graphic3d_Structure)& theStruct,
1186                            const Standard_Boolean             theWithDestruction)
1187 {
1188   const Standard_Integer anIndex = IsComputed (theStruct);
1189   if (anIndex != 0)
1190   {
1191     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.Value (anIndex);
1192     aCompStruct->GraphicClear (theWithDestruction);
1193     aCompStruct->SetHLRValidation (Standard_False);
1194   }
1195 }
1196
1197 // ========================================================================
1198 // function : Connect
1199 // purpose  :
1200 // ========================================================================
1201 void Visual3d_View::Connect (const Handle(Graphic3d_Structure)& theMother,
1202                              const Handle(Graphic3d_Structure)& theDaughter)
1203 {
1204   Standard_Integer anIndexM = IsComputed (theMother);
1205   Standard_Integer anIndexD = IsComputed (theDaughter);
1206   if (anIndexM != 0
1207    && anIndexD != 0)
1208   {
1209     const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
1210     const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
1211     aStructM->GraphicConnect (aStructD);
1212   }
1213 }
1214
1215 // ========================================================================
1216 // function : Disconnect
1217 // purpose  :
1218 // ========================================================================
1219 void Visual3d_View::Disconnect (const Handle(Graphic3d_Structure)& theMother,
1220                                 const Handle(Graphic3d_Structure)& theDaughter)
1221 {
1222   Standard_Integer anIndexM = IsComputed (theMother);
1223   Standard_Integer anIndexD = IsComputed (theDaughter);
1224   if (anIndexM != 0
1225    && anIndexD != 0)
1226   {
1227     const Handle(Graphic3d_Structure)& aStructM = myStructsComputed.Value (anIndexM);
1228     const Handle(Graphic3d_Structure)& aStructD = myStructsComputed.Value (anIndexD);
1229     aStructM->GraphicDisconnect (aStructD);
1230   }
1231 }
1232
1233 // ========================================================================
1234 // function : DisplayImmediate
1235 // purpose  :
1236 // ========================================================================
1237 Standard_Boolean Visual3d_View::DisplayImmediate (const Handle(Graphic3d_Structure)& theStructure,
1238                                                   const Standard_Boolean             theIsSingleView)
1239 {
1240   if (!myImmediateStructures.Add (theStructure))
1241   {
1242     return Standard_False;
1243   }
1244
1245   if (theIsSingleView)
1246   {
1247     const Visual3d_SequenceOfView& aViews = myViewManager->DefinedViews();
1248     for (Standard_Integer aViewIter = 1; aViewIter <= aViews.Length(); ++aViewIter)
1249     {
1250       const Handle(Visual3d_View)& aView = aViews.Value (aViewIter);
1251       if (aView != this)
1252       {
1253         aView->EraseImmediate (theStructure);
1254       }
1255     }
1256   }
1257
1258   myGraphicDriver->DisplayImmediateStructure (MyCView, theStructure);
1259   return Standard_True;
1260 }
1261
1262 // ========================================================================
1263 // function : EraseImmediate
1264 // purpose  :
1265 // ========================================================================
1266 Standard_Boolean Visual3d_View::EraseImmediate (const Handle(Graphic3d_Structure)& theStructure)
1267 {
1268   const Standard_Boolean isErased = myImmediateStructures.Remove (theStructure);
1269   if (isErased)
1270   {
1271     myGraphicDriver->EraseImmediateStructure (MyCView, *theStructure->CStructure());
1272   }
1273
1274   return isErased;
1275 }
1276
1277 // ========================================================================
1278 // function : ClearImmediate
1279 // purpose  :
1280 // ========================================================================
1281 Standard_Boolean Visual3d_View::ClearImmediate()
1282 {
1283   if (myImmediateStructures.IsEmpty())
1284   {
1285     return Standard_False;
1286   }
1287
1288   for (Graphic3d_MapOfStructure::Iterator aStructIter (myImmediateStructures); aStructIter.More(); aStructIter.Next())
1289   {
1290     myGraphicDriver->EraseImmediateStructure (MyCView, *aStructIter.Key()->CStructure());
1291   }
1292   myImmediateStructures.Clear();
1293   return Standard_True;
1294 }
1295
1296 // ========================================================================
1297 // function : Display
1298 // purpose  :
1299 // ========================================================================
1300 void Visual3d_View::Display (const Handle(Graphic3d_Structure)& theStruct)
1301 {
1302   Display (theStruct, myViewManager->UpdateMode());
1303 }
1304
1305 // ========================================================================
1306 // function : Display
1307 // purpose  :
1308 // ========================================================================
1309 void Visual3d_View::Display (const Handle(Graphic3d_Structure)& theStruct,
1310                              const Aspect_TypeOfUpdate          theUpdateMode)
1311 {
1312   if (IsDeleted()
1313   || !IsDefined()
1314   || !IsActive())
1315   {
1316     return;
1317   }
1318
1319   // If Display on a structure present in the list of calculated structures while it is not
1320   // or more, of calculated type =>
1321   // - removes it as well as the associated old computed
1322   // THis happens when hlhsr becomes again of type e non computed after SetVisual.
1323   Standard_Integer anIndex = IsComputed (theStruct);
1324   if (anIndex != 0
1325    && theStruct->Visual() != Graphic3d_TOS_COMPUTED)
1326   {
1327     myStructsToCompute.Remove (anIndex);
1328     myStructsComputed .Remove (anIndex);
1329     anIndex = 0;
1330   }
1331
1332   Visual3d_TypeOfAnswer anAnswer = acceptDisplay (theStruct->Visual());
1333   if (anAnswer == Visual3d_TOA_NO)
1334   {
1335     return;
1336   }
1337
1338   if (!ComputedMode())
1339   {
1340     anAnswer = Visual3d_TOA_YES;
1341   }
1342
1343   if (anAnswer == Visual3d_TOA_YES)
1344   {
1345     if (!myStructsDisplayed.Add (theStruct))
1346     {
1347       return;
1348     }
1349
1350     theStruct->CalculateBoundBox();
1351     myGraphicDriver->DisplayStructure (MyCView, theStruct, theStruct->DisplayPriority());
1352     Update (theUpdateMode);
1353     return;
1354   }
1355   else if (anAnswer != Visual3d_TOA_COMPUTE)
1356   {
1357     return;
1358   }
1359
1360   if (anIndex != 0)
1361   {
1362     // Already computed, is COMPUTED still valid?
1363     const Handle(Graphic3d_Structure)& anOldStruct = myStructsComputed.Value (anIndex);
1364     if (anOldStruct->HLRValidation())
1365     {
1366       // Case COMPUTED valid, to be displayed
1367       if (!myStructsDisplayed.Add (theStruct))
1368       {
1369         return;
1370       }
1371
1372       myGraphicDriver->DisplayStructure (MyCView, anOldStruct, theStruct->DisplayPriority());
1373       Update (theUpdateMode);
1374       return;
1375     }
1376     else
1377     {
1378       // Case COMPUTED invalid
1379       // Is there another valid representation?
1380       // Find in the sequence of already calculated structures
1381       // 1/ Structure having the same Owner as <AStructure>
1382       // 2/ That is not <AStructure>
1383       // 3/ The COMPUTED which of is valid
1384       const Standard_Integer aNewIndex = HaveTheSameOwner (theStruct);
1385       if (aNewIndex != 0)
1386       {
1387         // Case of COMPUTED invalid, WITH a valid of replacement; to be displayed
1388         if (!myStructsDisplayed.Add (theStruct))
1389         {
1390           return;
1391         }
1392
1393         const Handle(Graphic3d_Structure)& aNewStruct = myStructsComputed.Value (aNewIndex);
1394         myStructsComputed.SetValue (anIndex, aNewStruct);
1395         myGraphicDriver->DisplayStructure (MyCView, aNewStruct, theStruct->DisplayPriority());
1396         Update (theUpdateMode);
1397         return;
1398       }
1399       else
1400       {
1401         // Case COMPUTED invalid, WITHOUT a valid of replacement
1402         // COMPUTED is removed if displayed
1403         if (myStructsDisplayed.Contains (theStruct))
1404         {
1405           myGraphicDriver->EraseStructure (MyCView, anOldStruct);
1406         }
1407       }
1408     }
1409   }
1410
1411   // Compute + Validation
1412   Handle(Graphic3d_Structure) aStruct;
1413   TColStd_Array2OfReal aTrsf (0, 3, 0, 3);
1414   theStruct->Transform (aTrsf);
1415   if (anIndex != 0)
1416   {
1417     TColStd_Array2OfReal anIdent (0, 3, 0, 3);
1418     for (Standard_Integer ii = 0; ii <= 3; ++ii)
1419     {
1420       for (Standard_Integer jj = 0; jj <= 3; ++jj)
1421       {
1422         anIdent (ii, jj) = (ii == jj ? 1.0 : 0.0);
1423       }
1424     }
1425
1426     aStruct = myStructsComputed.Value (anIndex);
1427     aStruct->SetTransform (anIdent, Graphic3d_TOC_REPLACE);
1428     if (theStruct->IsTransformed())
1429     {
1430       theStruct->Compute (this, aTrsf, aStruct);
1431     }
1432     else
1433     {
1434       theStruct->Compute (this, aStruct);
1435     }
1436   }
1437   else
1438   {
1439     aStruct = theStruct->IsTransformed()
1440             ? theStruct->Compute (this, aTrsf)
1441             : theStruct->Compute (this);
1442   }
1443
1444   aStruct->SetHLRValidation (Standard_True);
1445
1446   // TOCOMPUTE and COMPUTED associated to sequences are added
1447   myStructsToCompute.Append (theStruct);
1448   myStructsComputed .Append (aStruct);
1449
1450   // The previous are removed if necessary
1451   if (anIndex != 0)
1452   {
1453     myStructsToCompute.Remove (anIndex);
1454     myStructsComputed .Remove (anIndex);
1455   }
1456
1457   // Of which type will be the computed?
1458   const Visual3d_TypeOfVisualization aViewType = MyContext.Visualization();
1459   const Standard_Boolean toComputeWireframe = aViewType == Visual3d_TOV_WIREFRAME
1460                                            && theStruct->ComputeVisual() != Graphic3d_TOS_SHADING;
1461   const Standard_Boolean toComputeShading   = aViewType == Visual3d_TOV_SHADING
1462                                            && theStruct->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
1463   if (!toComputeShading && !toComputeWireframe)
1464   {
1465     anAnswer = Visual3d_TOA_NO;
1466   }
1467   else
1468   {
1469     aStruct->SetVisual (toComputeWireframe ? Graphic3d_TOS_WIREFRAME : Graphic3d_TOS_SHADING);
1470     anAnswer = acceptDisplay (aStruct->Visual());
1471   }
1472
1473   if (theStruct->IsHighlighted())
1474   {
1475     aStruct->Highlight (Aspect_TOHM_COLOR, theStruct->HighlightColor(), Standard_False);
1476   }
1477
1478   // It is displayed only if the calculated structure
1479   // has a proper type corresponding to the one of the view.
1480   if (anAnswer == Visual3d_TOA_NO)
1481   {
1482     return;
1483   }
1484
1485   myStructsDisplayed.Add (theStruct);
1486   myGraphicDriver->DisplayStructure (MyCView, aStruct, theStruct->DisplayPriority());
1487
1488   Update (theUpdateMode);
1489 }
1490
1491 // ========================================================================
1492 // function : Erase
1493 // purpose  :
1494 // ========================================================================
1495 void Visual3d_View::Erase (const Handle(Graphic3d_Structure)& theStruct)
1496 {
1497   if (!IsDeleted())
1498   {
1499     Erase (theStruct, myViewManager->UpdateMode());
1500   }
1501 }
1502
1503 // ========================================================================
1504 // function : Erase
1505 // purpose  :
1506 // ========================================================================
1507 void Visual3d_View::Erase (const Handle(Graphic3d_Structure)& theStruct,
1508                            const Aspect_TypeOfUpdate          theUpdateMode)
1509 {
1510   if ( IsDeleted()
1511    ||  EraseImmediate (theStruct)
1512    || !IsDisplayed (theStruct))
1513   {
1514     return;
1515   }
1516
1517   Visual3d_TypeOfAnswer anAnswer = acceptDisplay (theStruct->Visual());
1518   if (!ComputedMode())
1519   {
1520     anAnswer = Visual3d_TOA_YES;
1521   }
1522
1523   if (anAnswer != Visual3d_TOA_COMPUTE)
1524   {
1525     myGraphicDriver->EraseStructure (MyCView, theStruct);
1526   }
1527   else if (anAnswer == Visual3d_TOA_COMPUTE
1528        && myIsInComputedMode)
1529   {
1530     const Standard_Integer anIndex = IsComputed (theStruct);
1531     if (anIndex != 0)
1532     {
1533       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
1534       myGraphicDriver->EraseStructure (MyCView, aCompStruct);
1535     }
1536   }
1537   myStructsDisplayed.Remove (theStruct);
1538   Update (theUpdateMode);
1539 }
1540
1541 // ========================================================================
1542 // function : Highlight
1543 // purpose  :
1544 // ========================================================================
1545 void Visual3d_View::Highlight (const Handle(Graphic3d_Structure)& theStruct,
1546                                const Aspect_TypeOfHighlightMethod theMethod)
1547 {
1548   const Standard_Integer anIndex = IsComputed (theStruct);
1549   if (anIndex != 0)
1550   {
1551     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
1552     aCompStruct->Highlight (theMethod, theStruct->HighlightColor(), Standard_False);
1553   }
1554 }
1555
1556 // ========================================================================
1557 // function : SetTransform
1558 // purpose  :
1559 // ========================================================================
1560 void Visual3d_View::SetTransform (const Handle(Graphic3d_Structure)& theStruct,
1561                                   const TColStd_Array2OfReal&        theTrsf)
1562 {
1563   const Standard_Integer anIndex = IsComputed (theStruct);
1564   if (anIndex != 0)
1565   {
1566     // Test is somewhat light !
1567     // trsf is transferred only if it is :
1568     // a translation
1569     // a scale
1570     if (theTrsf (0, 1) != 0.0 || theTrsf (0, 2) != 0.0
1571      || theTrsf (1, 0) != 0.0 || theTrsf (1, 2) != 0.0
1572      || theTrsf (2, 0) != 0.0 || theTrsf (2, 1) != 0.0)
1573     {
1574       ReCompute (theStruct);
1575     }
1576     else
1577     {
1578       const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
1579       aCompStruct->GraphicTransform (theTrsf);
1580     }
1581   }
1582
1583   theStruct->CalculateBoundBox();
1584   if (!theStruct->IsMutable()
1585    && !theStruct->CStructure()->IsForHighlight
1586    && !theStruct->CStructure()->IsInfinite)
1587   {
1588     const Graphic3d_ZLayerId aLayerId = theStruct->GetZLayer();
1589     myGraphicDriver->InvalidateBVHData (MyCView, aLayerId);
1590   }
1591 }
1592
1593 // ========================================================================
1594 // function : UnHighlight
1595 // purpose  :
1596 // ========================================================================
1597 void Visual3d_View::UnHighlight (const Handle(Graphic3d_Structure)& theStruct)
1598 {
1599   Standard_Integer anIndex = IsComputed (theStruct);
1600   if (anIndex != 0)
1601   {
1602     const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.ChangeValue (anIndex);
1603     aCompStruct->GraphicUnHighlight();
1604   }
1605 }
1606
1607 // ========================================================================
1608 // function : IsComputed
1609 // purpose  :
1610 // ========================================================================
1611 Standard_Integer Visual3d_View::IsComputed (const Handle(Graphic3d_Structure)& theStruct) const
1612 {
1613   const Standard_Integer aStructId  = theStruct->Identification();
1614   const Standard_Integer aNbStructs = myStructsToCompute.Length();
1615   for (Standard_Integer aStructIter = 1; aStructIter <= aNbStructs; ++aStructIter)
1616   {
1617     const Handle(Graphic3d_Structure)& aStruct = myStructsToCompute.Value (aStructIter);
1618     if (aStruct->Identification() == aStructId)
1619     {
1620       return aStructIter;
1621     }
1622   }
1623   return 0;
1624 }
1625
1626 // ========================================================================
1627 // function : IsDisplayed
1628 // purpose  :
1629 // ========================================================================
1630 Standard_Boolean Visual3d_View::IsDisplayed (const Handle(Graphic3d_Structure)& theStruct) const
1631 {
1632   return !IsDeleted()
1633       &&  myStructsDisplayed.Contains (theStruct);
1634 }
1635
1636 // ========================================================================
1637 // function : ContainsFacet
1638 // purpose  :
1639 // ========================================================================
1640 Standard_Boolean Visual3d_View::ContainsFacet() const
1641 {
1642   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
1643   {
1644     if (aStructIter.Key()->ContainsFacet())
1645     {
1646       return Standard_True;
1647     }
1648   }
1649   return Standard_False;
1650 }
1651
1652 // ========================================================================
1653 // function : ContainsFacet
1654 // purpose  :
1655 // ========================================================================
1656 Standard_Boolean Visual3d_View::ContainsFacet (const Graphic3d_MapOfStructure& theSet) const
1657 {
1658   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
1659   {
1660     if (aStructIter.Key()->ContainsFacet())
1661     {
1662       return Standard_True;
1663     }
1664   }
1665   return Standard_False;
1666 }
1667
1668 //! Auxiliary method for MinMaxValues() method
1669 inline void addStructureBndBox (const Handle(Graphic3d_Structure)& theStruct,
1670                                 const Standard_Boolean             theToIgnoreInfiniteFlag,
1671                                 Bnd_Box&                           theBndBox)
1672 {
1673   if (!theStruct->IsVisible())
1674   {
1675     return;
1676   }
1677   else if (theStruct->IsInfinite()
1678        && !theToIgnoreInfiniteFlag)
1679   {
1680     // XMin, YMin .... ZMax are initialized by means of infinite line data
1681     const Bnd_Box aBox = theStruct->MinMaxValues (Standard_False);
1682     if (!aBox.IsWhole()
1683      && !aBox.IsVoid())
1684     {
1685       theBndBox.Add (aBox);
1686     }
1687     return;
1688   }
1689
1690   // Only non-empty and non-infinite structures
1691   // are taken into account for calculation of MinMax
1692   if (theStruct->IsEmpty()
1693    || theStruct->TransformPersistenceMode() != Graphic3d_TMF_None)
1694   {
1695     return;
1696   }
1697
1698   // "FitAll" operation ignores object with transform persistence parameter
1699   const Bnd_Box aBox = theStruct->MinMaxValues (theToIgnoreInfiniteFlag);
1700
1701   // To prevent float overflow at camera parameters calculation and further
1702   // rendering, bounding boxes with at least one vertex coordinate out of
1703   // float range are skipped by view fit algorithms
1704   if (Abs (aBox.CornerMax().X()) >= ShortRealLast() ||
1705       Abs (aBox.CornerMax().Y()) >= ShortRealLast() ||
1706       Abs (aBox.CornerMax().Z()) >= ShortRealLast() ||
1707       Abs (aBox.CornerMin().X()) >= ShortRealLast() ||
1708       Abs (aBox.CornerMin().Y()) >= ShortRealLast() ||
1709       Abs (aBox.CornerMin().Z()) >= ShortRealLast())
1710     return;
1711
1712   theBndBox.Add (aBox);
1713 }
1714
1715 // ========================================================================
1716 // function : MinMaxValues
1717 // purpose  :
1718 // ========================================================================
1719 Bnd_Box Visual3d_View::MinMaxValues (const Standard_Boolean theToIgnoreInfiniteFlag) const
1720 {
1721   Bnd_Box aResult     = MinMaxValues (myStructsDisplayed,    theToIgnoreInfiniteFlag);
1722   Bnd_Box anImmediate = MinMaxValues (myImmediateStructures, theToIgnoreInfiniteFlag);
1723   aResult.Add (anImmediate);
1724   return aResult;
1725 }
1726
1727 // ========================================================================
1728 // function : MinMaxValues
1729 // purpose  :
1730 // ========================================================================
1731 Bnd_Box Visual3d_View::MinMaxValues (const Graphic3d_MapOfStructure& theSet,
1732                                      const Standard_Boolean          theToIgnoreInfiniteFlag) const
1733 {
1734   Bnd_Box aResult;
1735   const Standard_Integer aViewId = MyCView.ViewId;
1736   for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (theSet); aStructIter.More(); aStructIter.Next())
1737   {
1738     const Handle(Graphic3d_Structure)& aStructure = aStructIter.Key();
1739     if (!aStructIter.Value()->IsVisible())
1740     {
1741       continue;
1742     }
1743     else if (!aStructIter.Value()->CStructure()->ViewAffinity.IsNull()
1744           && !aStructIter.Value()->CStructure()->ViewAffinity->IsVisible (aViewId))
1745     {
1746       continue;
1747     }
1748
1749     addStructureBndBox (aStructure, theToIgnoreInfiniteFlag, aResult);
1750   }
1751   return aResult;
1752 }
1753
1754 // =======================================================================
1755 // function : NumberOfDisplayedStructures
1756 // purpose  :
1757 // =======================================================================
1758 Standard_Integer Visual3d_View::NumberOfDisplayedStructures() const
1759 {
1760   return myStructsDisplayed.Extent();
1761 }
1762
1763 // =======================================================================
1764 // function : Projects
1765 // purpose  :
1766 // =======================================================================
1767 void Visual3d_View::Projects (const Standard_Real theX,
1768                               const Standard_Real theY,
1769                               const Standard_Real theZ,
1770                               Standard_Real& thePX,
1771                               Standard_Real& thePY,
1772                               Standard_Real& thePZ) const
1773 {
1774   const Handle(Graphic3d_Camera)& aCamera = MyCView.Context.Camera;
1775
1776   gp_XYZ aViewSpaceDimensions = aCamera->ViewDimensions();
1777   Standard_Real aXSize = aViewSpaceDimensions.X();
1778   Standard_Real aYSize = aViewSpaceDimensions.Y();
1779   Standard_Real aZSize = aViewSpaceDimensions.Z();
1780
1781   gp_Pnt aPoint = aCamera->Project (gp_Pnt (theX, theY, theZ));
1782
1783   // NDC [-1, 1] --> PROJ [ -size / 2, +size / 2 ]
1784   thePX = aPoint.X() * aXSize * 0.5;
1785   thePY = aPoint.Y() * aYSize * 0.5;
1786   thePZ = aPoint.Z() * aZSize * 0.5;
1787 }
1788
1789 // =======================================================================
1790 // function : Identification
1791 // purpose  :
1792 // =======================================================================
1793 Standard_Integer Visual3d_View::Identification() const
1794 {
1795   return MyCView.ViewId;
1796 }
1797
1798 // =======================================================================
1799 // function : UpdateView
1800 // purpose  :
1801 // =======================================================================
1802 void Visual3d_View::UpdateView()
1803 {
1804   MyCView.Context.Aliasing        = MyContext.AliasingIsOn();
1805   MyCView.Context.BackZClipping   = MyContext.BackZClippingIsOn();
1806   MyCView.Context.FrontZClipping  = MyContext.FrontZClippingIsOn();
1807   MyCView.Context.DepthCueing     = MyContext.DepthCueingIsOn();
1808
1809   MyCView.Context.ZClipFrontPlane = float (MyContext.ZClippingFrontPlane());
1810   MyCView.Context.ZClipBackPlane  = float (MyContext.ZClippingBackPlane());
1811   MyCView.Context.DepthFrontPlane = float (MyContext.DepthCueingFrontPlane());
1812   MyCView.Context.DepthBackPlane  = float (MyContext.DepthCueingBackPlane());
1813
1814   MyCView.Context.Model           = MyContext.Model();
1815   MyCView.Context.Visualization   = MyContext.Visualization();
1816
1817   MyCView.Context.TextureEnv      = MyContext.TextureEnv();
1818   MyCView.Context.SurfaceDetail   = MyContext.SurfaceDetail();
1819 }
1820
1821 // =======================================================================
1822 // function : Compute
1823 // purpose  :
1824 // =======================================================================
1825 void Visual3d_View::Compute()
1826 {
1827   // force HLRValidation to False on all structures calculated in the view
1828   const Standard_Integer aNbCompStructs = myStructsComputed.Length();
1829   for (Standard_Integer aStructIter = 1; aStructIter <= aNbCompStructs; ++aStructIter)
1830   {
1831     myStructsComputed.Value (aStructIter)->SetHLRValidation (Standard_False);
1832   }
1833
1834   if (!ComputedMode())
1835   {
1836     return;
1837   }
1838
1839   // Change of orientation or of projection type =>
1840   // Remove structures that were calculated for the previous orientation.
1841   // Recalculation of new structures.
1842   NCollection_Sequence<Handle(Graphic3d_Structure)> aStructsSeq;
1843   for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
1844   {
1845     const Visual3d_TypeOfAnswer anAnswer = acceptDisplay (aStructIter.Key()->Visual());
1846     if (anAnswer == Visual3d_TOA_COMPUTE)
1847     {
1848       aStructsSeq.Append (aStructIter.Key()); // if the structure was calculated, it is recalculated
1849     }
1850   }
1851
1852   for (NCollection_Sequence<Handle(Graphic3d_Structure)>::Iterator aStructIter (aStructsSeq); aStructIter.More(); aStructIter.Next())
1853   {
1854     Display (aStructIter.ChangeValue(), Aspect_TOU_WAIT);
1855   }
1856 }
1857
1858 // =======================================================================
1859 // function : ReCompute
1860 // purpose  :
1861 // =======================================================================
1862 void Visual3d_View::ReCompute (const Handle(Graphic3d_Structure)& theStruct)
1863 {
1864   theStruct->CalculateBoundBox();
1865   if (!theStruct->IsMutable()
1866    && !theStruct->CStructure()->IsForHighlight
1867    && !theStruct->CStructure()->IsInfinite)
1868   {
1869     const Standard_Integer aLayerId = theStruct->DisplayPriority();
1870     myGraphicDriver->InvalidateBVHData(MyCView, aLayerId);
1871   }
1872
1873   if (!ComputedMode()
1874    ||  IsDeleted()
1875    || !IsDefined()
1876    || !IsActive()
1877    || !MyWindow->IsMapped()
1878    || !theStruct->IsDisplayed())
1879   {
1880     return;
1881   }
1882
1883   const Visual3d_TypeOfAnswer anAnswer = acceptDisplay (theStruct->Visual());
1884   if (anAnswer != Visual3d_TOA_COMPUTE)
1885   {
1886     return;
1887   }
1888
1889   const Standard_Integer anIndex = IsComputed (theStruct);
1890   if (anIndex == 0)
1891   {
1892     return;
1893   }
1894
1895   // compute + validation
1896   TColStd_Array2OfReal anIdent (0, 3, 0, 3);
1897   for (Standard_Integer aRow = 0; aRow <= 3; ++aRow)
1898   {
1899     for (Standard_Integer aCol = 0; aCol <= 3; ++aCol)
1900     {
1901       anIdent (aRow, aCol) = (aRow == aCol ? 1.0 : 0.0);
1902     }
1903   }
1904   TColStd_Array2OfReal aTrsf (0, 3, 0, 3);
1905   theStruct->Transform (aTrsf);
1906
1907   Handle(Graphic3d_Structure) aCompStructOld = myStructsComputed.ChangeValue (anIndex);
1908   Handle(Graphic3d_Structure) aCompStruct    = aCompStructOld;
1909   aCompStruct->SetTransform (anIdent, Graphic3d_TOC_REPLACE);
1910   theStruct->IsTransformed() ? theStruct->Compute (this, aTrsf, aCompStruct)
1911                              : theStruct->Compute (this,        aCompStruct);
1912   aCompStruct->SetHLRValidation (Standard_True);
1913
1914   // of which type will be the computed?
1915   const Visual3d_TypeOfVisualization aViewType = MyContext.Visualization();
1916   const Standard_Boolean toComputeWireframe = aViewType == Visual3d_TOV_WIREFRAME
1917                                            && theStruct->ComputeVisual() != Graphic3d_TOS_SHADING;
1918   const Standard_Boolean toComputeShading   = aViewType == Visual3d_TOV_SHADING
1919                                            && theStruct->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
1920   if (toComputeWireframe)
1921   {
1922     aCompStruct->SetVisual (Graphic3d_TOS_WIREFRAME);
1923   }
1924   else if (toComputeShading)
1925   {
1926     aCompStruct->SetVisual (Graphic3d_TOS_SHADING);
1927   }
1928
1929   if (theStruct->IsHighlighted())
1930   {
1931     aCompStruct->Highlight (Aspect_TOHM_COLOR, theStruct->HighlightColor(), Standard_False);
1932   }
1933
1934   // The previous calculation is removed and the new one is displayed
1935   myGraphicDriver->EraseStructure   (MyCView, aCompStructOld);
1936   myGraphicDriver->DisplayStructure (MyCView, aCompStruct, theStruct->DisplayPriority());
1937
1938   // why not just replace existing items?
1939   //myStructsToCompute.ChangeValue (anIndex) = theStruct;
1940   //myStructsComputed .ChangeValue (anIndex) = aCompStruct;
1941
1942   // hlhsr and the new associated compute are added
1943   myStructsToCompute.Append (theStruct);
1944   myStructsComputed .Append (aCompStruct);
1945
1946   // hlhsr and the new associated compute are removed
1947   myStructsToCompute.Remove (anIndex);
1948   myStructsComputed .Remove (anIndex);
1949 }
1950
1951 // =======================================================================
1952 // function : GraphicDriver
1953 // purpose  :
1954 // =======================================================================
1955 const Handle(Graphic3d_GraphicDriver)& Visual3d_View::GraphicDriver() const
1956 {
1957   return myGraphicDriver;
1958 }
1959
1960 // =======================================================================
1961 // function : HaveTheSameOwner
1962 // purpose  :
1963 // =======================================================================
1964 Standard_Integer Visual3d_View::HaveTheSameOwner (const Handle(Graphic3d_Structure)& theStruct) const
1965 {
1966   // Find in the sequence of already calculated structures
1967   // 1/ Structure with the same Owner as <AStructure>
1968   // 2/ Which is not <AStructure>
1969   // 3/ COMPUTED which of is valid
1970   const Standard_Integer aNbToCompStructs = myStructsToCompute.Length();
1971   for (Standard_Integer aStructIter = 1; aStructIter <= aNbToCompStructs; ++aStructIter)
1972   {
1973     const Handle(Graphic3d_Structure)& aStructToComp = myStructsToCompute.Value (aStructIter);
1974     if (aStructToComp->Owner()          == theStruct->Owner()
1975      && aStructToComp->Identification() != theStruct->Identification())
1976     {
1977       const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (aStructIter);
1978       if (aStructComp->HLRValidation())
1979       {
1980         return aStructIter;
1981       }
1982     }
1983   }
1984   return 0;
1985 }
1986
1987 // =======================================================================
1988 // function : CView
1989 // purpose  :
1990 // =======================================================================
1991 Standard_Address Visual3d_View::CView() const
1992 {
1993   return Standard_Address (&MyCView);
1994 }
1995
1996 // =======================================================================
1997 // function : ZBufferTriedronSetup
1998 // purpose  :
1999 // =======================================================================
2000 void Visual3d_View::ZBufferTriedronSetup (const Quantity_NameOfColor theXColor,
2001                                           const Quantity_NameOfColor theYColor,
2002                                           const Quantity_NameOfColor theZColor,
2003                                           const Standard_Real        theSizeRatio,
2004                                           const Standard_Real        theAxisDiametr,
2005                                           const Standard_Integer     theNbFacettes)
2006 {
2007   myGraphicDriver->ZBufferTriedronSetup (MyCView, theXColor, theYColor, theZColor,
2008                                          theSizeRatio, theAxisDiametr, theNbFacettes);
2009 }
2010
2011 // =======================================================================
2012 // function : TriedronDisplay
2013 // purpose  :
2014 // =======================================================================
2015 void Visual3d_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition thePosition,
2016                                      const Quantity_NameOfColor          theColor,
2017                                      const Standard_Real                 theScale,
2018                                      const Standard_Boolean              theAsWireframe)
2019 {
2020   myGraphicDriver->TriedronDisplay (MyCView, thePosition, theColor, theScale, theAsWireframe);
2021 }
2022
2023 // =======================================================================
2024 // function : TriedronErase
2025 // purpose  :
2026 // =======================================================================
2027 void Visual3d_View::TriedronErase()
2028 {
2029   myGraphicDriver->TriedronErase (MyCView);
2030 }
2031
2032 // =======================================================================
2033 // function : TriedronEcho
2034 // purpose  :
2035 // =======================================================================
2036 void Visual3d_View::TriedronEcho (const Aspect_TypeOfTriedronEcho theType)
2037 {
2038   myGraphicDriver->TriedronEcho (MyCView, theType);
2039 }
2040
2041 static void SetMinMaxValuesCallback (Visual3d_View* theView)
2042 {
2043   Graphic3d_CView* aCView = (Graphic3d_CView* )(theView->CView());
2044   Bnd_Box aBox = theView->MinMaxValues();
2045   if (!aBox.IsVoid())
2046   {
2047     gp_Pnt aMin = aBox.CornerMin();
2048     gp_Pnt aMax = aBox.CornerMax();
2049
2050     Graphic3d_Vec3 aMinVec ((Standard_ShortReal )aMin.X(), (Standard_ShortReal )aMin.Y(), (Standard_ShortReal )aMin.Z());
2051     Graphic3d_Vec3 aMaxVec ((Standard_ShortReal )aMax.X(), (Standard_ShortReal )aMax.Y(), (Standard_ShortReal )aMax.Z());
2052     const Handle(Graphic3d_GraphicDriver)& aDriver = theView->GraphicDriver();
2053     aDriver->GraduatedTrihedronMinMaxValues (*aCView, aMinVec, aMaxVec);
2054
2055   }
2056 }
2057
2058 // =======================================================================
2059 // function : GetGraduatedTrihedron
2060 // purpose  :
2061 // =======================================================================
2062 const Graphic3d_GraduatedTrihedron& Visual3d_View::GetGraduatedTrihedron() const
2063 {
2064   return myGTrihedron;
2065 }
2066
2067 // =======================================================================
2068 // function : GraduatedTrihedronDisplay
2069 // purpose  :
2070 // =======================================================================
2071 void Visual3d_View::GraduatedTrihedronDisplay (const Graphic3d_GraduatedTrihedron& theTrihedronData)
2072 {
2073   myGTrihedron = theTrihedronData;
2074
2075   myGTrihedron.PtrVisual3dView = this;
2076   myGTrihedron.CubicAxesCallback = SetMinMaxValuesCallback;
2077
2078   myGraphicDriver->GraduatedTrihedronDisplay (MyCView, myGTrihedron);
2079 }
2080
2081 // =======================================================================
2082 // function : GraduatedTrihedronErase
2083 // purpose  :
2084 // =======================================================================
2085 void Visual3d_View::GraduatedTrihedronErase()
2086 {
2087   myGTrihedron.PtrVisual3dView = NULL;
2088   myGraphicDriver->GraduatedTrihedronErase (MyCView);
2089 }
2090
2091 // =======================================================================
2092 // function : UnderLayer
2093 // purpose  :
2094 // =======================================================================
2095 const Handle(Visual3d_Layer)& Visual3d_View::UnderLayer() const
2096 {
2097   return myViewManager->UnderLayer();
2098 }
2099
2100 // =======================================================================
2101 // function : OverLayer
2102 // purpose  :
2103 // =======================================================================
2104 const Handle(Visual3d_Layer)& Visual3d_View::OverLayer() const
2105 {
2106   return myViewManager->OverLayer();
2107 }
2108
2109 // =======================================================================
2110 // function : LightLimit
2111 // purpose  :
2112 // =======================================================================
2113 Standard_Integer Visual3d_View::LightLimit() const
2114 {
2115   return myGraphicDriver->InquireLightLimit();
2116 }
2117
2118 // =======================================================================
2119 // function : PlaneLimit
2120 // purpose  :
2121 // =======================================================================
2122 Standard_Integer Visual3d_View::PlaneLimit() const
2123 {
2124   return myGraphicDriver->InquirePlaneLimit();
2125 }
2126
2127 // =======================================================================
2128 // function : ViewManager
2129 // purpose  :
2130 // =======================================================================
2131 Handle(Visual3d_ViewManager) Visual3d_View::ViewManager() const
2132 {
2133   return myViewManager;
2134 }
2135
2136 // =======================================================================
2137 // function : SetComputedMode
2138 // purpose  :
2139 // =======================================================================
2140 void Visual3d_View::SetComputedMode (const Standard_Boolean theMode)
2141 {
2142   if (( theMode &&  myIsInComputedMode)
2143    || (!theMode && !myIsInComputedMode))
2144   {
2145     return;
2146   }
2147
2148   myIsInComputedMode = theMode;
2149   if (!myIsInComputedMode)
2150   {
2151     for (Graphic3d_MapOfStructure::Iterator aStructIter (myStructsDisplayed); aStructIter.More(); aStructIter.Next())
2152     {
2153       const Handle(Graphic3d_Structure)& aStruct  = aStructIter.Key();
2154       const Visual3d_TypeOfAnswer        anAnswer = acceptDisplay (aStruct->Visual());
2155       if (anAnswer != Visual3d_TOA_COMPUTE)
2156       {
2157         continue;
2158       }
2159
2160       const Standard_Integer anIndex = IsComputed (aStruct);
2161       if (anIndex != 0)
2162       {
2163         const Handle(Graphic3d_Structure)& aStructComp = myStructsComputed.Value (anIndex);
2164         myGraphicDriver->EraseStructure   (MyCView, aStructComp);
2165         myGraphicDriver->DisplayStructure (MyCView, aStruct, aStruct->DisplayPriority());
2166       }
2167     }
2168     return;
2169   }
2170
2171   for (Graphic3d_MapOfStructure::Iterator aDispStructIter (myStructsDisplayed); aDispStructIter.More(); aDispStructIter.Next())
2172   {
2173     Handle(Graphic3d_Structure) aStruct  = aDispStructIter.Key();
2174     const Visual3d_TypeOfAnswer anAnswer = acceptDisplay (aStruct->Visual());
2175     if (anAnswer != Visual3d_TOA_COMPUTE)
2176     {
2177       continue;
2178     }
2179
2180     const Standard_Integer anIndex = IsComputed (aStruct);
2181     if (anIndex != 0)
2182     {
2183       myGraphicDriver->EraseStructure   (MyCView, aStruct);
2184       myGraphicDriver->DisplayStructure (MyCView, myStructsComputed.Value (anIndex), aStruct->DisplayPriority());
2185
2186       Display (aStruct, Aspect_TOU_WAIT);
2187       if (aStruct->IsHighlighted())
2188       {
2189         const Handle(Graphic3d_Structure)& aCompStruct = myStructsComputed.Value (anIndex);
2190         if (!aCompStruct->IsHighlighted())
2191         {
2192           aCompStruct->Highlight (Aspect_TOHM_COLOR, aStruct->HighlightColor(), Standard_False);
2193         }
2194       }
2195     }
2196     else
2197     {
2198       TColStd_Array2OfReal aTrsf (0, 3, 0, 3);
2199       aStruct->Transform (aTrsf);
2200       Handle(Graphic3d_Structure) aCompStruct = aStruct->IsTransformed() ? aStruct->Compute (this, aTrsf) : aStruct->Compute (this);
2201       aCompStruct->SetHLRValidation (Standard_True);
2202
2203       const Visual3d_TypeOfVisualization aViewType = MyContext.Visualization();
2204       const Standard_Boolean toComputeWireframe = aViewType == Visual3d_TOV_WIREFRAME
2205                                                 && aStruct->ComputeVisual() != Graphic3d_TOS_SHADING;
2206       const Standard_Boolean toComputeShading   = aViewType == Visual3d_TOV_SHADING
2207                                                 && aStruct->ComputeVisual() != Graphic3d_TOS_WIREFRAME;
2208       if (toComputeWireframe) aCompStruct->SetVisual (Graphic3d_TOS_WIREFRAME);
2209       if (toComputeShading  ) aCompStruct->SetVisual (Graphic3d_TOS_SHADING);
2210
2211       if (aStruct->IsHighlighted())
2212       {
2213         aCompStruct->Highlight (Aspect_TOHM_COLOR, aStruct->HighlightColor(), Standard_False);
2214       }
2215
2216       Standard_Boolean hasResult = Standard_False;
2217       const Standard_Integer aNbToCompute = myStructsToCompute.Length();
2218       const Standard_Integer aStructId    = aStruct->Identification();
2219       for (Standard_Integer aToCompStructIter = 1; aToCompStructIter <= aNbToCompute; ++aToCompStructIter)
2220       {
2221         if (myStructsToCompute.Value (aToCompStructIter)->Identification() == aStructId)
2222         {
2223           hasResult = Standard_True;
2224           myStructsComputed.ChangeValue (aToCompStructIter) = aCompStruct;
2225           break;
2226         }
2227       }
2228
2229       if (!hasResult)
2230       {
2231         myStructsToCompute.Append (aStruct);
2232         myStructsComputed .Append (aCompStruct);
2233       }
2234
2235       myGraphicDriver->EraseStructure   (MyCView, aStruct);
2236       myGraphicDriver->DisplayStructure (MyCView, aCompStruct, aStruct->DisplayPriority());
2237     }
2238   }
2239   Update (myViewManager->UpdateMode());
2240 }
2241
2242 // =======================================================================
2243 // function : ComputedMode
2244 // purpose  :
2245 // =======================================================================
2246 Standard_Boolean Visual3d_View::ComputedMode() const
2247 {
2248   return myIsInComputedMode;
2249 }
2250
2251 // =======================================================================
2252 // function : SetBackFacingModel
2253 // purpose  :
2254 // =======================================================================
2255 void Visual3d_View::SetBackFacingModel (const Visual3d_TypeOfBackfacingModel theModel)
2256 {
2257   switch (theModel)
2258   {
2259     default:
2260     case Visual3d_TOBM_AUTOMATIC:
2261       MyCView.Backfacing = 0;
2262       break;
2263     case Visual3d_TOBM_FORCE:
2264       MyCView.Backfacing = 1;
2265       break;
2266     case Visual3d_TOBM_DISABLE:
2267       MyCView.Backfacing = -1;
2268       break;
2269   }
2270   myGraphicDriver->SetBackFacingModel (MyCView);
2271 }
2272
2273 // =======================================================================
2274 // function : BackFacingModel
2275 // purpose  :
2276 // =======================================================================
2277 Visual3d_TypeOfBackfacingModel Visual3d_View::BackFacingModel() const
2278 {
2279   switch (MyCView.Backfacing)
2280   {
2281     case 0: return Visual3d_TOBM_AUTOMATIC;
2282     case 1: return Visual3d_TOBM_FORCE;
2283   }
2284   return Visual3d_TOBM_DISABLE;
2285 }
2286
2287 // =======================================================================
2288 // function : ReadDepths
2289 // purpose  :
2290 // =======================================================================
2291 void Visual3d_View::ReadDepths (const Standard_Integer theX,
2292                                 const Standard_Integer theY,
2293                                 const Standard_Integer theWidth,
2294                                 const Standard_Integer theHeight,
2295                                 const Standard_Address theBuffer) const
2296 {
2297   myGraphicDriver->ReadDepths (MyCView, theX, theY, theWidth, theHeight, theBuffer);
2298 }
2299
2300 // =======================================================================
2301 // function : FBOCreate
2302 // purpose  :
2303 // =======================================================================
2304 Graphic3d_PtrFrameBuffer Visual3d_View::FBOCreate(const Standard_Integer theWidth,
2305                                                   const Standard_Integer theHeight)
2306 {
2307   return myGraphicDriver->FBOCreate( MyCView, theWidth, theHeight );
2308 }
2309
2310 // =======================================================================
2311 // function : FBORelease
2312 // purpose  :
2313 // =======================================================================
2314 void Visual3d_View::FBORelease(Graphic3d_PtrFrameBuffer& theFBOPtr)
2315 {
2316   myGraphicDriver->FBORelease( MyCView, theFBOPtr );
2317 }
2318
2319 // =======================================================================
2320 // function : FBOGetDimensions
2321 // purpose  :
2322 // =======================================================================
2323 void Visual3d_View::FBOGetDimensions(const Graphic3d_PtrFrameBuffer theFBOPtr,
2324                                      Standard_Integer& theWidth,    Standard_Integer& theHeight,
2325                                      Standard_Integer& theWidthMax, Standard_Integer& theHeightMax)
2326 {
2327   myGraphicDriver->FBOGetDimensions( MyCView, theFBOPtr,
2328                                      theWidth, theHeight,
2329                                      theWidthMax, theHeightMax );
2330 }
2331
2332 // =======================================================================
2333 // function : FBOChangeViewport
2334 // purpose  :
2335 // =======================================================================
2336 void Visual3d_View::FBOChangeViewport(Graphic3d_PtrFrameBuffer& theFBOPtr,
2337                                       const Standard_Integer theWidth, const Standard_Integer theHeight)
2338 {
2339   myGraphicDriver->FBOChangeViewport( MyCView, theFBOPtr,
2340                                      theWidth, theHeight );
2341 }
2342
2343 // =======================================================================
2344 // function : BufferDump
2345 // purpose  :
2346 // =======================================================================
2347 Standard_Boolean Visual3d_View::BufferDump (Image_PixMap&               theImage,
2348                                             const Graphic3d_BufferType& theBufferType)
2349 {
2350   return myGraphicDriver->BufferDump (MyCView, theImage, theBufferType);
2351 }
2352
2353 // =======================================================================
2354 // function : EnableGLLight
2355 // purpose  :
2356 // =======================================================================
2357 void Visual3d_View::EnableGLLight( const Standard_Boolean enable ) const
2358 {
2359   myGraphicDriver->SetGLLightEnabled( MyCView, enable );
2360 }
2361
2362 // =======================================================================
2363 // function : IsGLLightEnabled
2364 // purpose  :
2365 // =======================================================================
2366 Standard_Boolean Visual3d_View::IsGLLightEnabled() const
2367 {
2368   return myGraphicDriver->IsGLLightEnabled( MyCView );
2369 }
2370
2371 // =======================================================================
2372 // function : Export
2373 // purpose  :
2374 // =======================================================================
2375 Standard_Boolean Visual3d_View::Export (const Standard_CString       theFileName,
2376                                         const Graphic3d_ExportFormat theFormat,
2377                                         const Graphic3d_SortType     theSortType,
2378                                         const Standard_Real          thePrecision,
2379                                         const Standard_Address       theProgressBarFunc,
2380                                         const Standard_Address       theProgressObject) const
2381 {
2382   Handle(Visual3d_Layer) anUnderLayer = myViewManager->UnderLayer();
2383   Handle(Visual3d_Layer) anOverLayer  = myViewManager->OverLayer();
2384
2385   Aspect_CLayer2d anOverCLayer;
2386   Aspect_CLayer2d anUnderCLayer;
2387   anOverCLayer.ptrLayer = anUnderCLayer.ptrLayer = NULL;
2388
2389   if (!anOverLayer.IsNull())
2390     anOverCLayer = anOverLayer->CLayer();
2391   if (!anUnderLayer.IsNull())
2392     anUnderCLayer = anUnderLayer->CLayer();
2393
2394   Standard_Integer aWidth, aHeight;
2395   Window()->Size (aWidth, aHeight);
2396
2397   return myGraphicDriver->Export (theFileName, theFormat, theSortType,
2398                                   aWidth, aHeight, MyCView, anUnderCLayer, anOverCLayer,
2399                                   thePrecision, theProgressBarFunc, theProgressObject);
2400 }
2401
2402 // =======================================================================
2403 // function : SetZLayerSettings
2404 // purpose  :
2405 // =======================================================================
2406 void Visual3d_View::SetZLayerSettings (const Graphic3d_ZLayerId        theLayerId,
2407                                        const Graphic3d_ZLayerSettings& theSettings)
2408 {
2409   myGraphicDriver->SetZLayerSettings (MyCView, theLayerId, theSettings);
2410 }
2411
2412 // =======================================================================
2413 // function : AddZLayer
2414 // purpose  :
2415 // =======================================================================
2416 void Visual3d_View::AddZLayer (const Graphic3d_ZLayerId theLayerId)
2417 {
2418   myGraphicDriver->AddZLayer (MyCView, theLayerId);
2419 }
2420
2421 // =======================================================================
2422 // function : RemoveZLayer
2423 // purpose  :
2424 // =======================================================================
2425 void Visual3d_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
2426 {
2427   myGraphicDriver->RemoveZLayer (MyCView, theLayerId);
2428 }
2429
2430 // =======================================================================
2431 // function : ChangeZLayer
2432 // purpose  :
2433 // =======================================================================
2434 void Visual3d_View::ChangeZLayer (const Handle(Graphic3d_Structure)& theStructure,
2435                                   const Graphic3d_ZLayerId           theLayerId)
2436 {
2437   myGraphicDriver->ChangeZLayer (*(theStructure->CStructure()), MyCView, theLayerId);
2438 }
2439
2440 // =======================================================================
2441 // function : Print
2442 // purpose  :
2443 // =======================================================================
2444 Standard_Boolean Visual3d_View::Print (const Aspect_Handle    thePrintDC, 
2445                                        const Standard_Boolean theToShowBackground,
2446                                        const Standard_CString theFilename,
2447                                        const Aspect_PrintAlgo thePrintAlgorithm,
2448                                        const Standard_Real    theScaleFactor) const
2449 {
2450   return Print (myViewManager->UnderLayer(),
2451                 myViewManager->OverLayer(),
2452                 thePrintDC, theToShowBackground,
2453                 theFilename, thePrintAlgorithm, 
2454                 theScaleFactor);
2455 }
2456
2457 // =======================================================================
2458 // function : Print
2459 // purpose  :
2460 // =======================================================================
2461 Standard_Boolean Visual3d_View::Print (const Handle(Visual3d_Layer)& theUnderLayer,
2462                                        const Handle(Visual3d_Layer)& theOverLayer,
2463                                        const Aspect_Handle           thePrintDC,
2464                                        const Standard_Boolean        theToShowBackground,
2465                                        const Standard_CString        theFilename,
2466                                        const Aspect_PrintAlgo        thePrintAlgorithm,
2467                                        const Standard_Real           theScaleFactor) const
2468 {
2469   if (IsDeleted()
2470   || !IsDefined()
2471   || !IsActive()
2472   || !MyWindow->IsMapped())
2473   {
2474     return Standard_False;
2475   }
2476
2477   Aspect_CLayer2d anOverCLayer;
2478   Aspect_CLayer2d anUnderCLayer;
2479   anOverCLayer.ptrLayer = anUnderCLayer.ptrLayer = NULL;
2480   if (!theOverLayer.IsNull())  anOverCLayer  = theOverLayer->CLayer();
2481   if (!theUnderLayer.IsNull()) anUnderCLayer = theUnderLayer->CLayer();
2482   return myGraphicDriver->Print (MyCView, anUnderCLayer, anOverCLayer,
2483                                  thePrintDC, theToShowBackground, theFilename,
2484                                  thePrintAlgorithm, theScaleFactor);
2485 }
2486
2487 //=============================================================================
2488 //function : HiddenObjects
2489 //purpose  :
2490 //=============================================================================
2491 const Handle(Graphic3d_NMapOfTransient)& Visual3d_View::HiddenObjects() const
2492 {
2493   return myHiddenObjects;
2494 }
2495
2496 //=============================================================================
2497 //function : HiddenObjects
2498 //purpose  :
2499 //=============================================================================
2500 Handle(Graphic3d_NMapOfTransient)& Visual3d_View::ChangeHiddenObjects()
2501 {
2502   return myHiddenObjects;
2503 }