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