0030364: Visualization, TKOpenGl - allow initializing a Surface-less EGL context
[occt.git] / src / V3d / V3d_Viewer.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <V3d_Viewer.hxx>
15
16 #include <Aspect_Grid.hxx>
17 #include <Aspect_IdentDefinitionError.hxx>
18 #include <Graphic3d_ArrayOfSegments.hxx>
19 #include <Graphic3d_AspectLine3d.hxx>
20 #include <Graphic3d_AspectMarker3d.hxx>
21 #include <Graphic3d_AspectText3d.hxx>
22 #include <Graphic3d_GraphicDriver.hxx>
23 #include <Graphic3d_Group.hxx>
24 #include <Graphic3d_Structure.hxx>
25 #include <Standard_ErrorHandler.hxx>
26 #include <Standard_Type.hxx>
27 #include <V3d.hxx>
28 #include <V3d_BadValue.hxx>
29 #include <V3d_CircularGrid.hxx>
30 #include <V3d_AmbientLight.hxx>
31 #include <V3d_DirectionalLight.hxx>
32 #include <V3d_RectangularGrid.hxx>
33 #include <V3d_View.hxx>
34
35 IMPLEMENT_STANDARD_RTTIEXT(V3d_Viewer, Standard_Transient)
36
37 // ========================================================================
38 // function : V3d_Viewer
39 // purpose  :
40 // ========================================================================
41 V3d_Viewer::V3d_Viewer (const Handle(Graphic3d_GraphicDriver)& theDriver)
42 : myDriver (theDriver),
43   myStructureManager (new Graphic3d_StructureManager (theDriver)),
44   myZLayerGenId (1, IntegerLast()),
45   myBackground (Quantity_NOC_GRAY30),
46   myViewSize (1000.0),
47   myViewProj (V3d_XposYnegZpos),
48   myVisualization (V3d_ZBUFFER),
49   myShadingModel (Graphic3d_TOSM_VERTEX),
50   myDefaultTypeOfView (V3d_ORTHOGRAPHIC),
51   myComputedMode (Standard_True),
52   myDefaultComputedMode (Standard_False),
53   myPrivilegedPlane (gp_Ax3 (gp_Pnt (0.,0.,0), gp_Dir (0.,0.,1.), gp_Dir (1.,0.,0.))),
54   myDisplayPlane (Standard_False),
55   myDisplayPlaneLength (1000.0),
56   myGridType (Aspect_GT_Rectangular),
57   myGridEcho (Standard_True),
58   myGridEchoLastVert (ShortRealLast(), ShortRealLast(), ShortRealLast())
59 {
60   myRGrid = new V3d_RectangularGrid (this, Quantity_Color (Quantity_NOC_GRAY50), Quantity_Color (Quantity_NOC_GRAY70));
61   myCGrid = new V3d_CircularGrid    (this, Quantity_Color (Quantity_NOC_GRAY50), Quantity_Color (Quantity_NOC_GRAY70));
62 }
63
64 // ========================================================================
65 // function : V3d_Viewer
66 // purpose  :
67 // ========================================================================
68 V3d_Viewer::V3d_Viewer (const Handle(Graphic3d_GraphicDriver)& theDriver,
69                         const Standard_ExtString ,
70                         const Standard_CString ,
71                         const Standard_Real                theViewSize,
72                         const V3d_TypeOfOrientation        theViewProj,
73                         const Quantity_Color&              theViewBackground,
74                         const V3d_TypeOfVisualization      theVisualization,
75                         const Graphic3d_TypeOfShadingModel theShadingModel,
76                         const Standard_Boolean             theComputedMode,
77                         const Standard_Boolean             theDefaultComputedMode)
78 : myDriver (theDriver),
79   myStructureManager (new Graphic3d_StructureManager (theDriver)),
80   myZLayerGenId (1, IntegerLast()),
81   myBackground (theViewBackground),
82   myViewSize (theViewSize),
83   myViewProj (theViewProj),
84   myVisualization (theVisualization),
85   myShadingModel (theShadingModel),
86   myDefaultTypeOfView (V3d_ORTHOGRAPHIC),
87   myComputedMode (theComputedMode),
88   myDefaultComputedMode (theDefaultComputedMode),
89   myPrivilegedPlane (gp_Ax3 (gp_Pnt (0.,0.,0), gp_Dir (0.,0.,1.), gp_Dir (1.,0.,0.))),
90   myDisplayPlane (Standard_False),
91   myDisplayPlaneLength (theViewSize),
92   myGridType (Aspect_GT_Rectangular),
93   myGridEcho (Standard_True),
94   myGridEchoLastVert (ShortRealLast(), ShortRealLast(), ShortRealLast())
95 {
96   myRGrid = new V3d_RectangularGrid (this, Quantity_Color (Quantity_NOC_GRAY50), Quantity_Color (Quantity_NOC_GRAY70));
97   myCGrid = new V3d_CircularGrid    (this, Quantity_Color (Quantity_NOC_GRAY50), Quantity_Color (Quantity_NOC_GRAY70));
98   SetDefaultViewSize (theViewSize);
99 }
100
101 // ========================================================================
102 // function : CreateView
103 // purpose  :
104 // ========================================================================
105 Handle(V3d_View) V3d_Viewer::CreateView ()
106 {
107   return new V3d_View(this, myDefaultTypeOfView);
108 }
109
110 // ========================================================================
111 // function : SetViewOn
112 // purpose  :
113 // ========================================================================
114 void V3d_Viewer::SetViewOn()
115 {
116   for (V3d_ListOfView::Iterator aDefViewIter (myDefinedViews); aDefViewIter.More(); aDefViewIter.Next())
117   {
118     SetViewOn (aDefViewIter.Value());
119   }
120 }
121
122 // ========================================================================
123 // function : SetViewOff
124 // purpose  :
125 // ========================================================================
126 void V3d_Viewer::SetViewOff()
127 {
128   for (V3d_ListOfView::Iterator aDefViewIter (myDefinedViews); aDefViewIter.More(); aDefViewIter.Next())
129   {
130     SetViewOff (aDefViewIter.Value());
131   }
132 }
133
134 // ========================================================================
135 // function : SetViewOn
136 // purpose  :
137 // ========================================================================
138 void V3d_Viewer::SetViewOn (const Handle(V3d_View)& theView)
139 {
140   Handle(Graphic3d_CView) aViewImpl = theView->View();
141   if (!aViewImpl->IsDefined() || myActiveViews.Contains (theView))
142   {
143     return;
144   }
145
146   myActiveViews.Append (theView);
147   aViewImpl->Activate();
148   for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
149   {
150     theView->SetLightOn (anActiveLightIter.Value());
151   }
152
153   theView->SetGrid (myPrivilegedPlane, Grid ());
154   theView->SetGridActivity (Grid ()->IsActive ());
155   if (theView->SetImmediateUpdate (Standard_False))
156   {
157     theView->Redraw();
158     theView->SetImmediateUpdate (Standard_True);
159   }
160 }
161
162 // ========================================================================
163 // function : SetViewOff
164 // purpose  :
165 // ========================================================================
166 void V3d_Viewer::SetViewOff (const Handle(V3d_View)& theView)
167 {
168   Handle(Graphic3d_CView) aViewImpl = theView->View();
169   if (aViewImpl->IsDefined() && myActiveViews.Contains (theView))
170   {
171     myActiveViews.Remove (theView);
172     aViewImpl->Deactivate() ;
173   }
174 }
175
176 // ========================================================================
177 // function : Redraw
178 // purpose  :
179 // ========================================================================
180 void V3d_Viewer::Redraw() const
181 {
182   for (V3d_ListOfView::Iterator aDefViewIter (myDefinedViews); aDefViewIter.More(); aDefViewIter.Next())
183   {
184     aDefViewIter.Value()->Redraw();
185   }
186 }
187
188 // ========================================================================
189 // function : RedrawImmediate
190 // purpose  :
191 // ========================================================================
192 void V3d_Viewer::RedrawImmediate() const
193 {
194   for (V3d_ListOfView::Iterator aDefViewIter (myDefinedViews); aDefViewIter.More(); aDefViewIter.Next())
195   {
196     aDefViewIter.Value()->RedrawImmediate();
197   }
198 }
199
200 // ========================================================================
201 // function : Invalidate
202 // purpose  :
203 // ========================================================================
204 void V3d_Viewer::Invalidate() const
205 {
206   for (V3d_ListOfView::Iterator aDefViewIter (myDefinedViews); aDefViewIter.More(); aDefViewIter.Next())
207   {
208     aDefViewIter.Value()->Invalidate();
209   }
210 }
211
212 // ========================================================================
213 // function : Remove
214 // purpose  :
215 // ========================================================================
216 void V3d_Viewer::Remove()
217 {
218   myStructureManager->Remove();
219 }
220
221 // ========================================================================
222 // function : Erase
223 // purpose  :
224 // ========================================================================
225 void V3d_Viewer::Erase() const
226 {
227   myStructureManager->Erase();
228 }
229
230 // ========================================================================
231 // function : UnHighlight
232 // purpose  :
233 // ========================================================================
234 void V3d_Viewer::UnHighlight() const
235 {
236   myStructureManager->UnHighlight();
237 }
238
239 void V3d_Viewer::SetDefaultViewSize (const Standard_Real theSize)
240 {
241   if (theSize <= 0.0)
242     throw V3d_BadValue("V3d_Viewer::SetDefaultViewSize, bad size");
243   myViewSize = theSize;
244 }
245
246 // ========================================================================
247 // function : IfMoreViews
248 // purpose  :
249 // ========================================================================
250 Standard_Boolean V3d_Viewer::IfMoreViews() const
251 {
252   return myDefinedViews.Size() < myStructureManager->MaxNumOfViews();
253 }
254
255 // ========================================================================
256 // function : AddView
257 // purpose  :
258 // ========================================================================
259 void V3d_Viewer::AddView (const Handle(V3d_View)& theView)
260 {
261   if (!myDefinedViews.Contains (theView))
262   {
263     myDefinedViews.Append (theView);
264   }
265 }
266
267 // ========================================================================
268 // function : DelView
269 // purpose  :
270 // ========================================================================
271 void V3d_Viewer::DelView (const Handle(V3d_View)& theView)
272 {
273   myActiveViews.Remove (theView);
274   myDefinedViews.Remove (theView);
275 }
276
277 //=======================================================================
278 //function : AddZLayer
279 //purpose  :
280 //=======================================================================
281 Standard_Boolean V3d_Viewer::AddZLayer (Graphic3d_ZLayerId& theLayerId)
282 {
283   try
284   {
285     OCC_CATCH_SIGNALS
286     theLayerId = myZLayerGenId.Next();
287   }
288   catch (Aspect_IdentDefinitionError)
289   {
290     // new index can't be generated
291     return Standard_False;
292   }
293
294   myLayerIds.Add (theLayerId);
295   myDriver->AddZLayer (theLayerId);
296
297   return Standard_True;
298 }
299
300 //=======================================================================
301 //function : RemoveZLayer
302 //purpose  : 
303 //=======================================================================
304 Standard_Boolean V3d_Viewer::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
305 {
306   if (!myLayerIds.Contains (theLayerId)
307     || theLayerId < myZLayerGenId.Lower()
308     || theLayerId > myZLayerGenId.Upper())
309   {
310     return Standard_False;
311   }
312
313   myDriver->RemoveZLayer (theLayerId);
314   myLayerIds.Remove  (theLayerId);
315   myZLayerGenId.Free (theLayerId);
316
317   return Standard_True;
318 }
319
320 //=======================================================================
321 //function : GetAllZLayers
322 //purpose  :
323 //=======================================================================
324 void V3d_Viewer::GetAllZLayers (TColStd_SequenceOfInteger& theLayerSeq) const
325 {
326   myDriver->ZLayers (theLayerSeq);
327 }
328
329 //=======================================================================
330 //function : SetZLayerSettings
331 //purpose  :
332 //=======================================================================
333 void V3d_Viewer::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings)
334 {
335   myDriver->SetZLayerSettings (theLayerId, theSettings);
336 }
337
338 //=======================================================================
339 //function : ZLayerSettings
340 //purpose  :
341 //=======================================================================
342 Graphic3d_ZLayerSettings V3d_Viewer::ZLayerSettings (const Graphic3d_ZLayerId theLayerId)
343 {
344   return myDriver->ZLayerSettings (theLayerId);
345 }
346
347 //=======================================================================
348 //function : UpdateLights
349 //purpose  :
350 //=======================================================================
351 void V3d_Viewer::UpdateLights()
352 {
353   for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
354   {
355     anActiveViewIter.Value()->UpdateLights();
356   }
357 }
358
359 //=======================================================================
360 //function : SetLightOn
361 //purpose  :
362 //=======================================================================
363 void V3d_Viewer::SetLightOn (const Handle(V3d_Light)& theLight)
364 {
365   if (!myActiveLights.Contains (theLight))
366   {
367     myActiveLights.Append (theLight);
368   }
369
370   for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
371   {
372     anActiveViewIter.Value()->SetLightOn (theLight);
373   }
374 }
375
376 //=======================================================================
377 //function : SetLightOff
378 //purpose  :
379 //=======================================================================
380 void V3d_Viewer::SetLightOff (const Handle(V3d_Light)& theLight)
381 {
382   myActiveLights.Remove (theLight);
383   for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
384   {
385     anActiveViewIter.Value()->SetLightOff (theLight);
386   }
387 }
388
389 //=======================================================================
390 //function : SetLightOn
391 //purpose  :
392 //=======================================================================
393 void V3d_Viewer::SetLightOn()
394 {
395   for (V3d_ListOfLight::Iterator aDefLightIter (myDefinedLights); aDefLightIter.More(); aDefLightIter.Next())
396   {
397     if (!myActiveLights.Contains (aDefLightIter.Value()))
398     {
399       myActiveLights.Append (aDefLightIter.Value());
400       for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
401       {
402         anActiveViewIter.Value()->SetLightOn (aDefLightIter.Value());
403       }
404     }
405   }
406 }
407
408 //=======================================================================
409 //function : SetLightOff
410 //purpose  :
411 //=======================================================================
412 void V3d_Viewer::SetLightOff()
413 {
414   for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
415   {
416     for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
417     {
418       anActiveViewIter.Value()->SetLightOff (anActiveLightIter.Value());
419     }
420   }
421   myActiveLights.Clear();
422 }
423
424 //=======================================================================
425 //function : IsGlobalLight
426 //purpose  :
427 //=======================================================================
428 Standard_Boolean V3d_Viewer::IsGlobalLight (const Handle(V3d_Light)& theLight) const
429 {
430   return myActiveLights.Contains (theLight);
431 }
432
433 //=======================================================================
434 //function : AddLight
435 //purpose  :
436 //=======================================================================
437 void V3d_Viewer::AddLight (const Handle(V3d_Light)& theLight)
438 {
439   if (!myDefinedLights.Contains (theLight))
440   {
441     myDefinedLights.Append (theLight);
442   }
443 }
444
445 //=======================================================================
446 //function : DelLight
447 //purpose  :
448 //=======================================================================
449 void V3d_Viewer::DelLight (const Handle(V3d_Light)& theLight)
450 {
451   SetLightOff (theLight);
452   myDefinedLights.Remove (theLight);
453 }
454
455 //=======================================================================
456 //function : SetDefaultLights
457 //purpose  :
458 //=======================================================================
459 void V3d_Viewer::SetDefaultLights()
460 {
461   while (!myDefinedLights.IsEmpty())
462   {
463     Handle(V3d_Light) aLight = myDefinedLights.First();
464     DelLight (aLight);
465   }
466
467   Handle(V3d_DirectionalLight) aDirLight  = new V3d_DirectionalLight (V3d_Zneg, Quantity_NOC_WHITE, Standard_True);
468   Handle(V3d_AmbientLight)     anAmbLight = new V3d_AmbientLight (Quantity_NOC_WHITE);
469   AddLight (aDirLight);
470   AddLight (anAmbLight);
471   SetLightOn (aDirLight);
472   SetLightOn (anAmbLight);
473 }
474
475 //=======================================================================
476 //function : SetPrivilegedPlane
477 //purpose  :
478 //=======================================================================
479 void V3d_Viewer::SetPrivilegedPlane (const gp_Ax3& thePlane)
480 {
481   myPrivilegedPlane = thePlane;
482   Grid()->SetDrawMode(Grid()->DrawMode());
483   for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
484   {
485     anActiveViewIter.Value()->SetGrid (myPrivilegedPlane, Grid());
486   }
487
488   if (myDisplayPlane)
489   {
490     DisplayPrivilegedPlane (Standard_True, myDisplayPlaneLength);
491   }
492 }
493
494 //=======================================================================
495 //function : DisplayPrivilegedPlane
496 //purpose  :
497 //=======================================================================
498 void V3d_Viewer::DisplayPrivilegedPlane (const Standard_Boolean theOnOff, const Standard_Real theSize)
499 {
500   myDisplayPlane = theOnOff;
501   myDisplayPlaneLength = theSize;
502
503   if (!myDisplayPlane)
504   {
505     if (!myPlaneStructure.IsNull())
506         {
507       myPlaneStructure->Erase();
508     }
509     return;
510   }
511
512   if (myPlaneStructure.IsNull())
513   {
514     myPlaneStructure = new Graphic3d_Structure (StructureManager());
515     myPlaneStructure->SetInfiniteState (Standard_True);
516     myPlaneStructure->Display();
517   }
518   else
519   {
520     myPlaneStructure->Clear();
521   }
522
523   Handle(Graphic3d_Group) aGroup = myPlaneStructure->NewGroup();
524
525   Handle(Graphic3d_AspectLine3d) aLineAttrib = new Graphic3d_AspectLine3d (Quantity_NOC_GRAY60, Aspect_TOL_SOLID, 1.0);
526   aGroup->SetGroupPrimitivesAspect (aLineAttrib);
527
528   Handle(Graphic3d_AspectText3d) aTextAttrib = new Graphic3d_AspectText3d();
529   aTextAttrib->SetColor (Quantity_Color (Quantity_NOC_ROYALBLUE1));
530   aGroup->SetGroupPrimitivesAspect (aTextAttrib);
531
532   Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments (6);
533
534   const gp_Pnt& p0 = myPrivilegedPlane.Location();
535
536   const gp_Pnt pX (p0.XYZ() + myDisplayPlaneLength * myPrivilegedPlane.XDirection().XYZ());
537   aPrims->AddVertex (p0);
538   aPrims->AddVertex (pX);
539   aGroup->Text ("X", Graphic3d_Vertex (pX.X(), pX.Y(), pX.Z()), 1.0 / 81.0);
540
541   const gp_Pnt pY (p0.XYZ() + myDisplayPlaneLength * myPrivilegedPlane.YDirection().XYZ());
542   aPrims->AddVertex (p0);
543   aPrims->AddVertex (pY);
544   aGroup->Text ("Y", Graphic3d_Vertex (pY.X(), pY.Y(), pY.Z()), 1.0 / 81.0);
545
546   const gp_Pnt pZ (p0.XYZ() + myDisplayPlaneLength * myPrivilegedPlane.Direction().XYZ());
547   aPrims->AddVertex (p0);
548   aPrims->AddVertex (pZ);
549   aGroup->Text ("Z", Graphic3d_Vertex (pZ.X(), pZ.Y(), pZ.Z()), 1.0 / 81.0);
550
551   aGroup->AddPrimitiveArray (aPrims);
552
553   myPlaneStructure->Display();
554 }