0027266: Coding, TKOpenGl - drop unused files OpenGl_telem_util.hxx and OpenGl_tgl_fu...
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <OpenGl_CappingAlgo.hxx>
17 #include <OpenGl_Context.hxx>
18 #include <OpenGl_GlCore11.hxx>
19 #include <OpenGl_GraphicDriver.hxx>
20 #include <OpenGl_ShaderManager.hxx>
21 #include <OpenGl_ShaderProgram.hxx>
22 #include <OpenGl_StructureShadow.hxx>
23 #include <OpenGl_Vec.hxx>
24 #include <OpenGl_View.hxx>
25 #include <OpenGl_Workspace.hxx>
26
27 #include <Graphic3d_SequenceOfHClipPlane.hxx>
28
29
30 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Structure,Graphic3d_CStructure)
31
32 //! Auxiliary class for bounding box presentation
33 class OpenGl_BndBoxPrs : public OpenGl_Element
34 {
35
36 public:
37
38   //! Main constructor
39   OpenGl_BndBoxPrs (const Graphic3d_BndBox4f& theBndBox)
40   {
41     const float Xm = theBndBox.CornerMin().x();
42     const float Ym = theBndBox.CornerMin().y();
43     const float Zm = theBndBox.CornerMin().z();
44     const float XM = theBndBox.CornerMax().x();
45     const float YM = theBndBox.CornerMax().y();
46     const float ZM = theBndBox.CornerMax().z();
47
48     myVerts[0]  = OpenGl_Vec3 (Xm, Ym, Zm);
49     myVerts[1]  = OpenGl_Vec3 (Xm, Ym, ZM);
50     myVerts[2]  = OpenGl_Vec3 (Xm, YM, ZM);
51     myVerts[3]  = OpenGl_Vec3 (Xm, YM, Zm);
52     myVerts[4]  = OpenGl_Vec3 (Xm, Ym, Zm);
53     myVerts[5]  = OpenGl_Vec3 (XM, Ym, Zm);
54     myVerts[6]  = OpenGl_Vec3 (XM, Ym, ZM);
55     myVerts[7]  = OpenGl_Vec3 (XM, YM, ZM);
56     myVerts[8]  = OpenGl_Vec3 (XM, YM, Zm);
57     myVerts[9]  = OpenGl_Vec3 (XM, Ym, Zm);
58     myVerts[10] = OpenGl_Vec3 (XM, YM, Zm);
59     myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm);
60     myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM);
61     myVerts[13] = OpenGl_Vec3 (XM, YM, ZM);
62     myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM);
63     myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM);
64   }
65
66   //! Render presentation
67   virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const
68   {
69   #if !defined(GL_ES_VERSION_2_0)
70     // Apply line aspect
71     const OpenGl_AspectLine*     anAspectLine = theWorkspace->AspectLine (Standard_True);
72     const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
73
74     glDisable (GL_LIGHTING);
75
76     // Use highlight colors
77     theWorkspace->GetGlContext()->core11->glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
78
79     glEnableClientState (GL_VERTEX_ARRAY);
80     glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
81     glDrawArrays (GL_LINE_STRIP, 0, 16);
82     glDisableClientState (GL_VERTEX_ARRAY);
83
84     // restore aspects
85     if (!aPrevTexture.IsNull())
86     {
87       theWorkspace->EnableTexture (aPrevTexture);
88     }
89   #else
90     (void )theWorkspace;
91   #endif
92   }
93
94   //! Release graphical resources
95   virtual void Release (OpenGl_Context*)
96   {
97     //
98   }
99
100 protected:
101
102   //! Protected destructor
103   virtual ~OpenGl_BndBoxPrs() {}
104
105 private:
106
107   OpenGl_Vec3 myVerts[16]; //!< vertices array
108
109 public:
110
111   DEFINE_STANDARD_ALLOC
112
113 };
114
115 /*----------------------------------------------------------------------*/
116
117 // =======================================================================
118 // function : OpenGl_Structure
119 // purpose  :
120 // =======================================================================
121 OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager)
122 : Graphic3d_CStructure (theManager),
123   myAspectLine         (NULL),
124   myAspectFace         (NULL),
125   myAspectMarker       (NULL),
126   myAspectText         (NULL),
127   myHighlightColor     (NULL),
128   myInstancedStructure (NULL),
129   myIsRaytracable      (Standard_False),
130   myModificationState  (0),
131   myIsCulled           (Standard_True),
132   myIsMirrored         (Standard_False)
133 {
134   //
135 }
136
137 // =======================================================================
138 // function : ~OpenGl_Structure
139 // purpose  :
140 // =======================================================================
141 OpenGl_Structure::~OpenGl_Structure()
142 {
143   Release (Handle(OpenGl_Context)());
144 }
145
146 // =======================================================================
147 // function : UpdateAspects
148 // purpose  :
149 // =======================================================================
150 void OpenGl_Structure::UpdateAspects()
151 {
152   if (ContextLine.IsDef)
153     SetAspectLine (ContextLine);
154
155   if (ContextFillArea.IsDef)
156     SetAspectFace (ContextFillArea);
157
158   if (ContextMarker.IsDef)
159     SetAspectMarker (ContextMarker);
160
161   if (ContextText.IsDef)
162     SetAspectText (ContextText);
163 }
164
165 // =======================================================================
166 // function : UpdateTransformation
167 // purpose  :
168 // =======================================================================
169 void OpenGl_Structure::UpdateTransformation()
170 {
171   const OpenGl_Mat4& aMat = Graphic3d_CStructure::Transformation;
172   Standard_ShortReal aDet =
173     aMat.GetValue(0, 0) * (aMat.GetValue(1, 1) * aMat.GetValue(2, 2) - aMat.GetValue(2, 1) * aMat.GetValue(1, 2)) -
174     aMat.GetValue(0, 1) * (aMat.GetValue(1, 0) * aMat.GetValue(2, 2) - aMat.GetValue(2, 0) * aMat.GetValue(1, 2)) +
175     aMat.GetValue(0, 2) * (aMat.GetValue(1, 0) * aMat.GetValue(2, 1) - aMat.GetValue(2, 0) * aMat.GetValue(1, 1));
176
177   // Determinant of transform matrix less then 0 means that mirror transform applied.
178   myIsMirrored = aDet < 0.0f;
179
180   if (IsRaytracable())
181   {
182     ++myModificationState;
183   }
184 }
185
186 // =======================================================================
187 // function : SetAspectLine
188 // purpose  :
189 // =======================================================================
190 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &theAspect)
191 {
192   if (!myAspectLine)
193   {
194     myAspectLine = new OpenGl_AspectLine();
195   }
196   myAspectLine->SetAspect (theAspect);
197 }
198
199 // =======================================================================
200 // function : SetAspectFace
201 // purpose  :
202 // =======================================================================
203 void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect)
204 {
205   if (!myAspectFace)
206   {
207     myAspectFace = new OpenGl_AspectFace();
208   }
209   myAspectFace->SetAspect (theAspect);
210
211   if (IsRaytracable())
212   {
213     ++myModificationState;
214   }
215 }
216
217 // =======================================================================
218 // function : SetAspectMarker
219 // purpose  :
220 // =======================================================================
221 void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect)
222 {
223   if (!myAspectMarker)
224   {
225     myAspectMarker = new OpenGl_AspectMarker();
226   }
227   myAspectMarker->SetAspect (theAspect);
228 }
229
230 // =======================================================================
231 // function : SetAspectText
232 // purpose  :
233 // =======================================================================
234 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &theAspect)
235 {
236   if (!myAspectText)
237   {
238     myAspectText = new OpenGl_AspectText();
239   }
240   myAspectText->SetAspect (theAspect);
241 }
242
243 // =======================================================================
244 // function : clearHighlightBox
245 // purpose  :
246 // =======================================================================
247 void OpenGl_Structure::clearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
248 {
249   if (!myHighlightBox.IsNull())
250   {
251     myHighlightBox->Release (theGlCtx);
252     myHighlightBox.Nullify();
253   }
254 }
255
256 // =======================================================================
257 // function : HighlightWithColor
258 // purpose  :
259 // =======================================================================
260 void OpenGl_Structure::HighlightWithColor (const Graphic3d_Vec3&  theColor,
261                                            const Standard_Boolean theToCreate)
262 {
263   const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
264   if (theToCreate)
265     setHighlightColor   (aContext, theColor);
266   else
267     clearHighlightColor (aContext);
268 }
269
270 // =======================================================================
271 // function : HighlightWithBndBox
272 // purpose  :
273 // =======================================================================
274 void OpenGl_Structure::HighlightWithBndBox (const Handle(Graphic3d_Structure)& theStruct,
275                                             const Standard_Boolean             theToCreate)
276 {
277   const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
278   if (!theToCreate)
279   {
280     clearHighlightBox (aContext);
281     return;
282   }
283
284   if (!myHighlightBox.IsNull())
285   {
286     myHighlightBox->Release (aContext);
287   }
288   else
289   {
290     myHighlightBox = new OpenGl_Group (theStruct);
291   }
292
293   CALL_DEF_CONTEXTLINE& aContextLine = myHighlightBox->ChangeContextLine();
294   aContextLine.IsDef    = 1;
295   aContextLine.Color    = HighlightColor;
296   aContextLine.LineType = Aspect_TOL_SOLID;
297   aContextLine.Width    = 1.0f;
298   myHighlightBox->UpdateAspectLine (Standard_True);
299
300   OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox);
301   myHighlightBox->AddElement (aBndBoxPrs);
302 }
303
304 // =======================================================================
305 // function : setHighlightColor
306 // purpose  :
307 // =======================================================================
308 void OpenGl_Structure::setHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
309                                           const Graphic3d_Vec3&         theColor)
310 {
311   clearHighlightBox (theGlCtx);
312   if (myHighlightColor == NULL)
313   {
314     myHighlightColor = new TEL_COLOUR();
315   }
316
317   myHighlightColor->rgb[0] = theColor.r();
318   myHighlightColor->rgb[1] = theColor.g();
319   myHighlightColor->rgb[2] = theColor.b();
320   myHighlightColor->rgb[3] = 1.F;
321 }
322
323 // =======================================================================
324 // function : clearHighlightColor
325 // purpose  :
326 // =======================================================================
327 void OpenGl_Structure::clearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
328 {
329   clearHighlightBox(theGlCtx);
330   delete myHighlightColor;
331   myHighlightColor = NULL;
332 }
333
334 // =======================================================================
335 // function : OnVisibilityChanged
336 // purpose  :
337 // =======================================================================
338 void OpenGl_Structure::OnVisibilityChanged()
339 {
340   if (IsRaytracable())
341   {
342     ++myModificationState;
343   }
344 }
345
346 // =======================================================================
347 // function : IsRaytracable
348 // purpose  :
349 // =======================================================================
350 Standard_Boolean OpenGl_Structure::IsRaytracable() const
351 {
352   if (!myGroups.IsEmpty())
353   {
354     return myIsRaytracable; // geometry structure
355   }
356   else if (myInstancedStructure != NULL)
357   {
358     return myInstancedStructure->IsRaytracable(); // instance structure
359   }
360
361   return Standard_False; // has no any groups or structures
362 }
363
364 // =======================================================================
365 // function : UpdateRaytracableState
366 // purpose  :
367 // =======================================================================
368 void OpenGl_Structure::UpdateStateIfRaytracable (const Standard_Boolean toCheck) const
369 {
370   myIsRaytracable = !toCheck || OpenGl_Raytrace::IsRaytracedStructure (this);
371
372   if (IsRaytracable())
373   {
374     ++myModificationState;
375   }
376 }
377
378 // =======================================================================
379 // function : Connect
380 // purpose  :
381 // =======================================================================
382 void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
383 {
384   OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
385
386   Standard_ASSERT_RAISE (myInstancedStructure == NULL || myInstancedStructure == aStruct,
387     "Error! Instanced structure is already defined");
388
389   myInstancedStructure = aStruct;
390
391   if (aStruct->IsRaytracable())
392   {
393     UpdateStateIfRaytracable (Standard_False);
394   }
395 }
396
397 // =======================================================================
398 // function : Disconnect
399 // purpose  :
400 // =======================================================================
401 void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure)
402 {
403   OpenGl_Structure* aStruct = static_cast<OpenGl_Structure*> (&theStructure);
404
405   if (myInstancedStructure == aStruct)
406   {
407     myInstancedStructure = NULL;
408
409     if (aStruct->IsRaytracable())
410     {
411       UpdateStateIfRaytracable();
412     }
413   }
414 }
415
416 // =======================================================================
417 // function : NewGroup
418 // purpose  :
419 // =======================================================================
420 Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Structure)& theStruct)
421 {
422   Handle(OpenGl_Group) aGroup = new OpenGl_Group (theStruct);
423   myGroups.Append (aGroup);
424   return aGroup;
425 }
426
427 // =======================================================================
428 // function : RemoveGroup
429 // purpose  :
430 // =======================================================================
431 void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup)
432 {
433   if (theGroup.IsNull())
434   {
435     return;
436   }
437
438   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
439   {
440     // Check for the given group
441     if (aGroupIter.Value() == theGroup)
442     {
443       const Standard_Boolean wasRaytracable =
444         static_cast<const OpenGl_Group&> (*theGroup).IsRaytracable();
445
446       theGroup->Clear (Standard_False);
447
448       if (wasRaytracable)
449       {
450         UpdateStateIfRaytracable();
451       }
452
453       myGroups.Remove (aGroupIter);
454       return;
455     }
456   }
457 }
458
459 // =======================================================================
460 // function : Clear
461 // purpose  :
462 // =======================================================================
463 void OpenGl_Structure::Clear()
464 {
465   Clear (GlDriver()->GetSharedContext());
466 }
467
468 // =======================================================================
469 // function : Clear
470 // purpose  :
471 // =======================================================================
472 void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
473 {
474   Standard_Boolean aRaytracableGroupDeleted (Standard_False);
475
476   // Release groups
477   for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
478   {
479     aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable();
480
481     // Delete objects
482     aGroupIter.ChangeValue()->Release (theGlCtx);
483   }
484   myGroups.Clear();
485
486   if (aRaytracableGroupDeleted)
487   {
488     myIsRaytracable = Standard_False;
489   }
490
491   Is2dText       = Standard_False;
492   IsForHighlight = Standard_False;
493 }
494
495 // =======================================================================
496 // function : renderGeometry
497 // purpose  :
498 // =======================================================================
499 void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace,
500                                        bool&                           theHasClosed) const
501 {
502   if (myInstancedStructure != NULL)
503   {
504     myInstancedStructure->renderGeometry (theWorkspace, theHasClosed);
505   }
506
507   for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
508   {
509     theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed();
510     aGroupIter.Value()->Render (theWorkspace);
511   }
512 }
513
514 // =======================================================================
515 // function : renderClosedGeometry
516 // purpose  :
517 // =======================================================================
518 void OpenGl_Structure::renderClosedGeometry (const Handle(OpenGl_Workspace)& theWorkspace) const
519 {
520   if (myInstancedStructure != NULL)
521   {
522     myInstancedStructure->renderClosedGeometry (theWorkspace);
523   }
524
525   for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
526   {
527     if (aGroupIter.Value()->IsClosed())
528     {
529       aGroupIter.Value()->Render (theWorkspace);
530     }
531   }
532 }
533
534 // =======================================================================
535 // function : Render
536 // purpose  :
537 // =======================================================================
538 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
539 {
540   // Process the structure only if visible
541   if (!visible)
542   {
543     return;
544   }
545
546   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
547
548   // Render named status
549   const Standard_Integer aNamedStatus = theWorkspace->NamedStatus;
550   if (highlight)
551   {
552     theWorkspace->NamedStatus |= OPENGL_NS_HIGHLIGHT;
553   }
554
555   // Apply local transformation
556   aCtx->ModelWorldState.Push();
557   aCtx->ModelWorldState.SetCurrent (Transformation);
558
559   // detect scale transform
560   const Standard_Boolean   anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
561   const Standard_ShortReal aScaleX          = Transformation.GetRow (0).xyz().SquareModulus();
562   if (Abs (aScaleX - 1.f) > Precision::Confusion())
563   {
564     aCtx->SetGlNormalizeEnabled (Standard_True);
565   }
566
567   if (TransformPersistence.Flags)
568   {
569     OpenGl_Mat4 aProjection = aCtx->ProjectionState.Current();
570     OpenGl_Mat4 aWorldView  = aCtx->WorldViewState.Current();
571     TransformPersistence.Apply (aProjection, aWorldView, theWorkspace->Width(), theWorkspace->Height());
572
573     aCtx->ProjectionState.Push();
574     aCtx->WorldViewState.Push();
575     aCtx->ProjectionState.SetCurrent (aProjection);
576     aCtx->WorldViewState.SetCurrent (aWorldView);
577     aCtx->ApplyProjectionMatrix();
578   }
579
580   // Take into account transform persistence
581   aCtx->ApplyModelViewMatrix();
582
583   // Apply aspects
584   const OpenGl_AspectLine *anAspectLine = theWorkspace->AspectLine (Standard_False);
585   const OpenGl_AspectFace *anAspectFace = theWorkspace->AspectFace (Standard_False);
586   const OpenGl_AspectMarker *anAspectMarker = theWorkspace->AspectMarker (Standard_False);
587   const OpenGl_AspectText *anAspectText = theWorkspace->AspectText (Standard_False);
588   if (myAspectLine)
589   {
590     theWorkspace->SetAspectLine (myAspectLine);
591   }
592   if (myAspectFace)
593   {
594     theWorkspace->SetAspectFace (myAspectFace);
595   }
596   if (myAspectMarker)
597   {
598     theWorkspace->SetAspectMarker (myAspectMarker);
599   }
600   if (myAspectText)
601   {
602     theWorkspace->SetAspectText (myAspectText);
603   }
604
605   // Apply correction for mirror transform
606   if (myIsMirrored)
607   {
608     aCtx->core11fwd->glFrontFace (GL_CW);
609   }
610
611   // Apply highlight color
612   const TEL_COLOUR *aHighlightColor = theWorkspace->HighlightColor;
613   if (myHighlightColor)
614     theWorkspace->HighlightColor = myHighlightColor;
615
616   // Set up plane equations for non-structure transformed global model-view matrix
617   // List of planes to be applied to context state
618   NCollection_Handle<Graphic3d_SequenceOfHClipPlane> aUserPlanes;
619
620   // Collect clipping planes of structure scope
621   if (!myClipPlanes.IsEmpty())
622   {
623     Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes);
624     for (; aClippingIter.More(); aClippingIter.Next())
625     {
626       const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIter.Value();
627       if (!aClipPlane->IsOn())
628       {
629         continue;
630       }
631
632       if (aUserPlanes.IsNull())
633       {
634         aUserPlanes = new Graphic3d_SequenceOfHClipPlane();
635       }
636
637       aUserPlanes->Append (aClipPlane);
638     }
639   }
640
641   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
642   {
643     // add planes at loaded view matrix state
644     aCtx->ChangeClipping().AddWorld (aCtx, *aUserPlanes);
645
646     // Set OCCT state uniform variables
647     if (!aCtx->ShaderManager()->IsEmpty())
648     {
649       aCtx->ShaderManager()->UpdateClippingState();
650     }
651   }
652
653   // Render groups
654   bool hasClosedPrims = false;
655   renderGeometry (theWorkspace, hasClosedPrims);
656
657   // Reset correction for mirror transform
658   if (myIsMirrored)
659   {
660     aCtx->core11fwd->glFrontFace (GL_CCW);
661   }
662
663   // Render capping for structure groups
664   if (hasClosedPrims
665   && !aCtx->Clipping().Planes().IsEmpty())
666   {
667     OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this);
668   }
669
670   // Revert structure clippings
671   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
672   {
673     aCtx->ChangeClipping().Remove (aCtx, *aUserPlanes);
674
675     // Set OCCT state uniform variables
676     if (!aCtx->ShaderManager()->IsEmpty())
677     {
678       aCtx->ShaderManager()->RevertClippingState();
679     }
680   }
681
682   // Restore local transformation
683   aCtx->ModelWorldState.Pop();
684   aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
685   if (TransformPersistence.Flags)
686   {
687     aCtx->ProjectionState.Pop();
688     aCtx->WorldViewState.Pop();
689     aCtx->ApplyProjectionMatrix();
690   }
691
692   // Restore highlight color
693   theWorkspace->HighlightColor = aHighlightColor;
694
695   // Restore aspects
696   theWorkspace->SetAspectLine (anAspectLine);
697   theWorkspace->SetAspectFace (anAspectFace);
698   theWorkspace->SetAspectMarker (anAspectMarker);
699   theWorkspace->SetAspectText (anAspectText);
700
701   // Apply highlight box
702   if (!myHighlightBox.IsNull())
703   {
704     myHighlightBox->Render (theWorkspace);
705   }
706
707   // Restore named status
708   theWorkspace->NamedStatus = aNamedStatus;
709 }
710
711 // =======================================================================
712 // function : Release
713 // purpose  :
714 // =======================================================================
715 void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
716 {
717   // Release groups
718   Clear (theGlCtx);
719   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectLine);
720   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectFace);
721   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker);
722   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText);
723   clearHighlightColor (theGlCtx);
724 }
725
726 // =======================================================================
727 // function : ReleaseGlResources
728 // purpose  :
729 // =======================================================================
730 void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
731 {
732   for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
733   {
734     aGroupIter.ChangeValue()->Release (theGlCtx);
735   }
736   if (myAspectLine != NULL)
737   {
738     myAspectLine->Release (theGlCtx.operator->());
739   }
740   if (myAspectFace != NULL)
741   {
742     myAspectFace->Release (theGlCtx.operator->());
743   }
744   if (myAspectMarker != NULL)
745   {
746     myAspectMarker->Release (theGlCtx.operator->());
747   }
748   if (myAspectText != NULL)
749   {
750     myAspectText->Release (theGlCtx.operator->());
751   }
752   if (!myHighlightBox.IsNull())
753   {
754     myHighlightBox->Release (theGlCtx.operator->());
755   }
756 }
757
758 //=======================================================================
759 //function : ShadowLink
760 //purpose  :
761 //=======================================================================
762 Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const
763 {
764   return new OpenGl_StructureShadow (theManager, this);
765 }