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