f6c2e90ebdf7ce1ae152c7da650e1888cf7cdcaa
[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 : InsertLayerBefore
279 //purpose  :
280 //=======================================================================
281 Standard_Boolean V3d_Viewer::InsertLayerBefore (Graphic3d_ZLayerId& theNewLayerId,
282                                                 const Graphic3d_ZLayerSettings& theSettings,
283                                                 const Graphic3d_ZLayerId theLayerAfter)
284 {
285   if (myZLayerGenId.Next (theNewLayerId))
286   {
287     myLayerIds.Add (theNewLayerId);
288     myDriver->InsertLayerBefore (theNewLayerId, theSettings, theLayerAfter);
289     return Standard_True;
290   }
291   return Standard_False;
292 }
293
294 //=======================================================================
295 //function : InsertLayerAfter
296 //purpose  :
297 //=======================================================================
298 Standard_Boolean V3d_Viewer::InsertLayerAfter (Graphic3d_ZLayerId& theNewLayerId,
299                                                const Graphic3d_ZLayerSettings& theSettings,
300                                                const Graphic3d_ZLayerId theLayerBefore)
301 {
302   if (myZLayerGenId.Next (theNewLayerId))
303   {
304     myLayerIds.Add (theNewLayerId);
305     myDriver->InsertLayerAfter (theNewLayerId, theSettings, theLayerBefore);
306     return Standard_True;
307   }
308   return Standard_False;
309 }
310
311 //=======================================================================
312 //function : RemoveZLayer
313 //purpose  : 
314 //=======================================================================
315 Standard_Boolean V3d_Viewer::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
316 {
317   if (!myLayerIds.Contains (theLayerId)
318     || theLayerId < myZLayerGenId.Lower()
319     || theLayerId > myZLayerGenId.Upper())
320   {
321     return Standard_False;
322   }
323
324   myDriver->RemoveZLayer (theLayerId);
325   myLayerIds.Remove  (theLayerId);
326   myZLayerGenId.Free (theLayerId);
327
328   return Standard_True;
329 }
330
331 //=======================================================================
332 //function : GetAllZLayers
333 //purpose  :
334 //=======================================================================
335 void V3d_Viewer::GetAllZLayers (TColStd_SequenceOfInteger& theLayerSeq) const
336 {
337   myDriver->ZLayers (theLayerSeq);
338 }
339
340 //=======================================================================
341 //function : SetZLayerSettings
342 //purpose  :
343 //=======================================================================
344 void V3d_Viewer::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, const Graphic3d_ZLayerSettings& theSettings)
345 {
346   myDriver->SetZLayerSettings (theLayerId, theSettings);
347 }
348
349 //=======================================================================
350 //function : ZLayerSettings
351 //purpose  :
352 //=======================================================================
353 const Graphic3d_ZLayerSettings& V3d_Viewer::ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const
354 {
355   return myDriver->ZLayerSettings (theLayerId);
356 }
357
358 //=======================================================================
359 //function : UpdateLights
360 //purpose  :
361 //=======================================================================
362 void V3d_Viewer::UpdateLights()
363 {
364   for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
365   {
366     anActiveViewIter.Value()->UpdateLights();
367   }
368 }
369
370 //=======================================================================
371 //function : SetLightOn
372 //purpose  :
373 //=======================================================================
374 void V3d_Viewer::SetLightOn (const Handle(V3d_Light)& theLight)
375 {
376   if (!myActiveLights.Contains (theLight))
377   {
378     myActiveLights.Append (theLight);
379   }
380
381   for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
382   {
383     anActiveViewIter.Value()->SetLightOn (theLight);
384   }
385 }
386
387 //=======================================================================
388 //function : SetLightOff
389 //purpose  :
390 //=======================================================================
391 void V3d_Viewer::SetLightOff (const Handle(V3d_Light)& theLight)
392 {
393   myActiveLights.Remove (theLight);
394   for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
395   {
396     anActiveViewIter.Value()->SetLightOff (theLight);
397   }
398 }
399
400 //=======================================================================
401 //function : SetLightOn
402 //purpose  :
403 //=======================================================================
404 void V3d_Viewer::SetLightOn()
405 {
406   for (V3d_ListOfLight::Iterator aDefLightIter (myDefinedLights); aDefLightIter.More(); aDefLightIter.Next())
407   {
408     if (!myActiveLights.Contains (aDefLightIter.Value()))
409     {
410       myActiveLights.Append (aDefLightIter.Value());
411       for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
412       {
413         anActiveViewIter.Value()->SetLightOn (aDefLightIter.Value());
414       }
415     }
416   }
417 }
418
419 //=======================================================================
420 //function : SetLightOff
421 //purpose  :
422 //=======================================================================
423 void V3d_Viewer::SetLightOff()
424 {
425   for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
426   {
427     for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
428     {
429       anActiveViewIter.Value()->SetLightOff (anActiveLightIter.Value());
430     }
431   }
432   myActiveLights.Clear();
433 }
434
435 //=======================================================================
436 //function : IsGlobalLight
437 //purpose  :
438 //=======================================================================
439 Standard_Boolean V3d_Viewer::IsGlobalLight (const Handle(V3d_Light)& theLight) const
440 {
441   return myActiveLights.Contains (theLight);
442 }
443
444 //=======================================================================
445 //function : AddLight
446 //purpose  :
447 //=======================================================================
448 void V3d_Viewer::AddLight (const Handle(V3d_Light)& theLight)
449 {
450   if (!myDefinedLights.Contains (theLight))
451   {
452     myDefinedLights.Append (theLight);
453   }
454 }
455
456 //=======================================================================
457 //function : DelLight
458 //purpose  :
459 //=======================================================================
460 void V3d_Viewer::DelLight (const Handle(V3d_Light)& theLight)
461 {
462   SetLightOff (theLight);
463   myDefinedLights.Remove (theLight);
464 }
465
466 //=======================================================================
467 //function : SetDefaultLights
468 //purpose  :
469 //=======================================================================
470 void V3d_Viewer::SetDefaultLights()
471 {
472   while (!myDefinedLights.IsEmpty())
473   {
474     Handle(V3d_Light) aLight = myDefinedLights.First();
475     DelLight (aLight);
476   }
477
478   Handle(V3d_DirectionalLight) aDirLight  = new V3d_DirectionalLight (V3d_Zneg, Quantity_NOC_WHITE, Standard_True);
479   Handle(V3d_AmbientLight)     anAmbLight = new V3d_AmbientLight (Quantity_NOC_WHITE);
480   AddLight (aDirLight);
481   AddLight (anAmbLight);
482   SetLightOn (aDirLight);
483   SetLightOn (anAmbLight);
484 }
485
486 //=======================================================================
487 //function : SetPrivilegedPlane
488 //purpose  :
489 //=======================================================================
490 void V3d_Viewer::SetPrivilegedPlane (const gp_Ax3& thePlane)
491 {
492   myPrivilegedPlane = thePlane;
493   Grid()->SetDrawMode(Grid()->DrawMode());
494   for (V3d_ListOfView::Iterator anActiveViewIter (myActiveViews); anActiveViewIter.More(); anActiveViewIter.Next())
495   {
496     anActiveViewIter.Value()->SetGrid (myPrivilegedPlane, Grid());
497   }
498
499   if (myDisplayPlane)
500   {
501     DisplayPrivilegedPlane (Standard_True, myDisplayPlaneLength);
502   }
503 }
504
505 //=======================================================================
506 //function : DisplayPrivilegedPlane
507 //purpose  :
508 //=======================================================================
509 void V3d_Viewer::DisplayPrivilegedPlane (const Standard_Boolean theOnOff, const Standard_Real theSize)
510 {
511   myDisplayPlane = theOnOff;
512   myDisplayPlaneLength = theSize;
513
514   if (!myDisplayPlane)
515   {
516     if (!myPlaneStructure.IsNull())
517         {
518       myPlaneStructure->Erase();
519     }
520     return;
521   }
522
523   if (myPlaneStructure.IsNull())
524   {
525     myPlaneStructure = new Graphic3d_Structure (StructureManager());
526     myPlaneStructure->SetInfiniteState (Standard_True);
527     myPlaneStructure->Display();
528   }
529   else
530   {
531     myPlaneStructure->Clear();
532   }
533
534   Handle(Graphic3d_Group) aGroup = myPlaneStructure->NewGroup();
535
536   Handle(Graphic3d_AspectLine3d) aLineAttrib = new Graphic3d_AspectLine3d (Quantity_NOC_GRAY60, Aspect_TOL_SOLID, 1.0);
537   aGroup->SetGroupPrimitivesAspect (aLineAttrib);
538
539   Handle(Graphic3d_AspectText3d) aTextAttrib = new Graphic3d_AspectText3d();
540   aTextAttrib->SetColor (Quantity_Color (Quantity_NOC_ROYALBLUE1));
541   aGroup->SetGroupPrimitivesAspect (aTextAttrib);
542
543   Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments (6);
544
545   const gp_Pnt& p0 = myPrivilegedPlane.Location();
546
547   const gp_Pnt pX (p0.XYZ() + myDisplayPlaneLength * myPrivilegedPlane.XDirection().XYZ());
548   aPrims->AddVertex (p0);
549   aPrims->AddVertex (pX);
550   aGroup->Text ("X", Graphic3d_Vertex (pX.X(), pX.Y(), pX.Z()), 1.0 / 81.0);
551
552   const gp_Pnt pY (p0.XYZ() + myDisplayPlaneLength * myPrivilegedPlane.YDirection().XYZ());
553   aPrims->AddVertex (p0);
554   aPrims->AddVertex (pY);
555   aGroup->Text ("Y", Graphic3d_Vertex (pY.X(), pY.Y(), pY.Z()), 1.0 / 81.0);
556
557   const gp_Pnt pZ (p0.XYZ() + myDisplayPlaneLength * myPrivilegedPlane.Direction().XYZ());
558   aPrims->AddVertex (p0);
559   aPrims->AddVertex (pZ);
560   aGroup->Text ("Z", Graphic3d_Vertex (pZ.X(), pZ.Y(), pZ.Z()), 1.0 / 81.0);
561
562   aGroup->AddPrimitiveArray (aPrims);
563
564   myPlaneStructure->Display();
565 }