d1027b12ecb57ae6479c81bf4fd79ecaec543992
[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
8 // under the terms of the GNU Lesser General Public 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 #ifdef HAVE_CONFIG_H
17   #include <config.h>
18 #endif
19
20
21 #include <OpenGl_CappingAlgo.hxx>
22 #include <OpenGl_Context.hxx>
23 #include <OpenGl_GlCore11.hxx>
24 #include <OpenGl_ShaderManager.hxx>
25 #include <OpenGl_ShaderProgram.hxx>
26 #include <OpenGl_Structure.hxx>
27 #include <OpenGl_telem_util.hxx>
28 #include <OpenGl_Vec.hxx>
29 #include <OpenGl_View.hxx>
30 #include <OpenGl_Workspace.hxx>
31
32 #include <Graphic3d_SequenceOfHClipPlane_Handle.hxx>
33
34 //! Auxiliary class for bounding box presentation
35 class OpenGl_BndBoxPrs : public OpenGl_Element
36 {
37
38 public:
39
40   //! Main constructor
41   OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
42   {
43     const float Xm = theBndBox.Pmin.x;
44     const float Ym = theBndBox.Pmin.y;
45     const float Zm = theBndBox.Pmin.z;
46     const float XM = theBndBox.Pmax.x;
47     const float YM = theBndBox.Pmax.y;
48     const float ZM = theBndBox.Pmax.z;
49     myVerts[0]  = OpenGl_Vec3 (Xm, Ym, Zm);
50     myVerts[1]  = OpenGl_Vec3 (Xm, Ym, ZM);
51     myVerts[2]  = OpenGl_Vec3 (Xm, YM, ZM);
52     myVerts[3]  = OpenGl_Vec3 (Xm, YM, Zm);
53     myVerts[4]  = OpenGl_Vec3 (Xm, Ym, Zm);
54     myVerts[5]  = OpenGl_Vec3 (XM, Ym, Zm);
55     myVerts[6]  = OpenGl_Vec3 (XM, Ym, ZM);
56     myVerts[7]  = OpenGl_Vec3 (XM, YM, ZM);
57     myVerts[8]  = OpenGl_Vec3 (XM, YM, Zm);
58     myVerts[9]  = OpenGl_Vec3 (XM, Ym, Zm);
59     myVerts[10] = OpenGl_Vec3 (XM, YM, Zm);
60     myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm);
61     myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM);
62     myVerts[13] = OpenGl_Vec3 (XM, YM, ZM);
63     myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM);
64     myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM);
65   }
66
67   //! Render presentation
68   virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const
69   {
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     if ((theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0)
76     {
77       glDepthMask (GL_FALSE);
78     }
79
80     // Use highlight colors
81     glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
82
83     glEnableClientState (GL_VERTEX_ARRAY);
84     glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
85     glDrawArrays (GL_LINE_STRIP, 0, 16);
86     glDisableClientState (GL_VERTEX_ARRAY);
87
88     // restore aspects
89     if (!aPrevTexture.IsNull())
90     {
91       theWorkspace->EnableTexture (aPrevTexture);
92     }
93   }
94
95   //! Release graphical resources
96   virtual void Release (const Handle(OpenGl_Context)& )
97   {
98     //
99   }
100
101 protected:
102
103   //! Protected destructor
104   virtual ~OpenGl_BndBoxPrs() {}
105
106 private:
107
108   OpenGl_Vec3 myVerts[16]; //!< vertices array
109
110 public:
111
112   DEFINE_STANDARD_ALLOC
113
114 };
115
116 /*----------------------------------------------------------------------*/
117
118 // =======================================================================
119 // function : call_util_transpose_mat
120 // purpose  :
121 // =======================================================================
122 static void call_util_transpose_mat (float tmat[16], float mat[4][4])
123 {
124   int i, j;
125
126   for (i=0; i<4; i++)
127     for (j=0; j<4; j++)
128       tmat[j*4+i] = mat[i][j];
129 }
130
131 // =======================================================================
132 // function : OpenGl_Structure
133 // purpose  :
134 // =======================================================================
135 OpenGl_Structure::OpenGl_Structure ()
136 : myTransformation(NULL),
137   myTransPers(NULL),
138   myAspectLine(NULL),
139   myAspectFace(NULL),
140   myAspectMarker(NULL),
141   myAspectText(NULL),
142   myHighlightBox(NULL),
143   myHighlightColor(NULL),
144   myNamedStatus(0),
145   myZLayer(0)
146 {
147 #if HAVE_OPENCL
148   myIsRaytracable = Standard_False;
149   myModificationState = 0;
150 #endif
151 }
152
153 // =======================================================================
154 // function : ~OpenGl_Structure
155 // purpose  :
156 // =======================================================================
157 OpenGl_Structure::~OpenGl_Structure()
158 {
159   Release (Handle(OpenGl_Context)());
160   delete myTransformation;  myTransformation  = NULL;
161   delete myTransPers;       myTransPers       = NULL;
162 }
163
164 // =======================================================================
165 // function : SetTransformation
166 // purpose  :
167 // =======================================================================
168 void OpenGl_Structure::SetTransformation (const float *theMatrix)
169 {
170   if (!myTransformation)
171   {
172     myTransformation = new OpenGl_Matrix();
173   }
174
175   matcpy (myTransformation->mat, theMatrix);
176
177 #ifdef HAVE_OPENCL
178   if (myIsRaytracable)
179   {
180     UpdateStateWithAncestorStructures();
181   }
182 #endif
183 }
184
185 // =======================================================================
186 // function : SetTransformPersistence
187 // purpose  :
188 // =======================================================================
189 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
190 {
191   if (!myTransPers)
192     myTransPers = new TEL_TRANSFORM_PERSISTENCE;
193
194   myTransPers->mode = ATransPers.Flag;
195   myTransPers->pointX = ATransPers.Point.x;
196   myTransPers->pointY = ATransPers.Point.y;
197   myTransPers->pointZ = ATransPers.Point.z;
198 }
199
200 // =======================================================================
201 // function : SetAspectLine
202 // purpose  :
203 // =======================================================================
204 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &theAspect)
205 {
206   if (!myAspectLine)
207   {
208     myAspectLine = new OpenGl_AspectLine();
209   }
210   myAspectLine->SetAspect (theAspect);
211 }
212
213 // =======================================================================
214 // function : SetAspectFace
215 // purpose  :
216 // =======================================================================
217 void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect)
218 {
219   if (!myAspectFace)
220   {
221     myAspectFace = new OpenGl_AspectFace();
222   }
223   myAspectFace->SetAspect (theAspect);
224
225 #ifdef HAVE_OPENCL
226   if (myIsRaytracable)
227   {
228     UpdateStateWithAncestorStructures();
229   }
230 #endif
231 }
232
233 // =======================================================================
234 // function : SetAspectMarker
235 // purpose  :
236 // =======================================================================
237 void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect)
238 {
239   if (!myAspectMarker)
240   {
241     myAspectMarker = new OpenGl_AspectMarker();
242   }
243   myAspectMarker->SetAspect (theAspect);
244 }
245
246 // =======================================================================
247 // function : SetAspectText
248 // purpose  :
249 // =======================================================================
250 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &theAspect)
251 {
252   if (!myAspectText)
253   {
254     myAspectText = new OpenGl_AspectText();
255   }
256   myAspectText->SetAspect (theAspect);
257 }
258
259 // =======================================================================
260 // function : SetHighlightBox
261 // purpose  :
262 // =======================================================================
263 void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
264                                         const CALL_DEF_BOUNDBOX&      theBoundBox)
265 {
266   if (myHighlightBox != NULL)
267   {
268     myHighlightBox->Release (theGlCtx);
269   }
270   else
271   {
272 #ifndef HAVE_OPENCL
273     myHighlightBox = new OpenGl_Group();
274 #else
275     myHighlightBox = new OpenGl_Group (this);
276 #endif
277   }
278
279   CALL_DEF_CONTEXTLINE aContextLine;
280   aContextLine.Color    = theBoundBox.Color;
281   aContextLine.LineType = Aspect_TOL_SOLID;
282   aContextLine.Width    = 1.0f;
283   myHighlightBox->SetAspectLine (aContextLine);
284
285   OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (theBoundBox);
286   myHighlightBox->AddElement (TelParray, aBndBoxPrs);
287 }
288
289 // =======================================================================
290 // function : ClearHighlightBox
291 // purpose  :
292 // =======================================================================
293 void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
294 {
295   if (myHighlightBox != NULL)
296   {
297     OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
298   }
299 }
300
301 // =======================================================================
302 // function : SetHighlightColor
303 // purpose  :
304 // =======================================================================
305 void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
306                                           const Standard_ShortReal R,
307                                           const Standard_ShortReal G,
308                                           const Standard_ShortReal B)
309 {
310   ClearHighlightBox (theGlCtx);
311   if (myHighlightColor == NULL)
312   {
313     myHighlightColor = new TEL_COLOUR();
314   }
315
316   myHighlightColor->rgb[0] = R;
317   myHighlightColor->rgb[1] = G;
318   myHighlightColor->rgb[2] = B;
319   myHighlightColor->rgb[3] = 1.F;
320 }
321
322 // =======================================================================
323 // function : ClearHighlightColor
324 // purpose  :
325 // =======================================================================
326 void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
327 {
328   ClearHighlightBox(theGlCtx);
329   delete myHighlightColor;
330   myHighlightColor = NULL;
331 }
332
333 // =======================================================================
334 // function : SetNamedStatus
335 // purpose  :
336 // =======================================================================
337 void OpenGl_Structure::SetNamedStatus (const Standard_Integer aStatus)
338 {
339   myNamedStatus = aStatus;
340
341 #ifdef HAVE_OPENCL
342   if (myIsRaytracable)
343   {
344     UpdateStateWithAncestorStructures();
345   }
346 #endif
347 }
348
349 #ifdef HAVE_OPENCL
350
351 // =======================================================================
352 // function : RegisterAncestorStructure
353 // purpose  :
354 // =======================================================================
355 void OpenGl_Structure::RegisterAncestorStructure (const OpenGl_Structure* theStructure) const
356 {
357   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
358   {
359     if (anIt.Value() == theStructure)
360     {
361       return;
362     }    
363   }
364
365   myAncestorStructures.Append (theStructure);
366 }
367
368 // =======================================================================
369 // function : UnregisterAncestorStructure
370 // purpose  :
371 // =======================================================================
372 void OpenGl_Structure::UnregisterAncestorStructure (const OpenGl_Structure* theStructure) const
373 {
374   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
375   {
376     if (anIt.Value() == theStructure)
377     {
378       myAncestorStructures.Remove (anIt);
379       return;
380     }    
381   }
382 }
383
384 // =======================================================================
385 // function : UnregisterFromAncestorStructure
386 // purpose  :
387 // =======================================================================
388 void OpenGl_Structure::UnregisterFromAncestorStructure() const
389 {
390   for (OpenGl_ListOfStructure::Iterator anIta (myAncestorStructures); anIta.More(); anIta.Next())
391   {
392     OpenGl_Structure* anAncestor = const_cast<OpenGl_Structure*> (anIta.ChangeValue());
393
394     for (OpenGl_ListOfStructure::Iterator anIts (anAncestor->myConnected); anIts.More(); anIts.Next())
395     {
396       if (anIts.Value() == this)
397       {
398         anAncestor->myConnected.Remove (anIts);
399         return;
400       }      
401     }
402   }
403 }
404
405 // =======================================================================
406 // function : UpdateStateWithAncestorStructures
407 // purpose  :
408 // =======================================================================
409 void OpenGl_Structure::UpdateStateWithAncestorStructures() const
410 {
411   myModificationState++;
412
413   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
414   {
415     anIt.Value()->UpdateStateWithAncestorStructures();
416   }
417 }
418
419 // =======================================================================
420 // function : UpdateRaytracableWithAncestorStructures
421 // purpose  :
422 // =======================================================================
423 void OpenGl_Structure::UpdateRaytracableWithAncestorStructures() const
424 {
425   myIsRaytracable = OpenGl_Raytrace::IsRaytracedStructure (this);
426
427   if (!myIsRaytracable)
428   {
429     for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
430     {
431       anIt.Value()->UpdateRaytracableWithAncestorStructures();
432     }
433   }
434 }
435
436 // =======================================================================
437 // function : SetRaytracableWithAncestorStructures
438 // purpose  :
439 // =======================================================================
440 void OpenGl_Structure::SetRaytracableWithAncestorStructures() const
441 {
442   myIsRaytracable = Standard_True;
443
444   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
445   {
446     if (!anIt.Value()->IsRaytracable())
447     {
448       anIt.Value()->SetRaytracableWithAncestorStructures();
449     }
450   }
451 }
452
453 #endif
454
455 // =======================================================================
456 // function : Connect
457 // purpose  :
458 // =======================================================================
459 void OpenGl_Structure::Connect (const OpenGl_Structure *theStructure)
460 {
461   Disconnect (theStructure);
462   myConnected.Append (theStructure);
463
464 #ifdef HAVE_OPENCL
465   if (theStructure->IsRaytracable())
466   {
467     UpdateStateWithAncestorStructures();
468     SetRaytracableWithAncestorStructures();
469   }
470
471   theStructure->RegisterAncestorStructure (this);
472 #endif
473 }
474
475 // =======================================================================
476 // function : Disconnect
477 // purpose  :
478 // =======================================================================
479 void OpenGl_Structure::Disconnect (const OpenGl_Structure *theStructure)
480 {
481   OpenGl_ListOfStructure::Iterator its (myConnected);
482   while (its.More())
483   {
484     // Check for the given structure
485     if (its.Value() == theStructure)
486     {
487       myConnected.Remove (its);
488
489 #ifdef HAVE_OPENCL
490       if (theStructure->IsRaytracable())
491       {
492         UpdateStateWithAncestorStructures();
493         UpdateRaytracableWithAncestorStructures();
494       }
495
496       theStructure->UnregisterAncestorStructure (this);
497 #endif
498
499       return;
500     }
501     its.Next();
502   }
503 }
504
505 // =======================================================================
506 // function : AddGroup
507 // purpose  :
508 // =======================================================================
509 OpenGl_Group * OpenGl_Structure::AddGroup()
510 {
511   // Create new group
512 #ifndef HAVE_OPENCL
513   OpenGl_Group *g = new OpenGl_Group();
514 #else
515   OpenGl_Group *g = new OpenGl_Group (this);
516 #endif
517
518   myGroups.Append(g);
519   return g;
520 }
521
522 // =======================================================================
523 // function : RemoveGroup
524 // purpose  :
525 // =======================================================================
526 void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
527                                     const OpenGl_Group*           theGroup)
528 {
529   for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
530   {
531     // Check for the given group
532     if (anIter.Value() == theGroup)
533     {
534       myGroups.Remove (anIter);
535
536 #ifdef HAVE_OPENCL
537       if (theGroup->IsRaytracable())
538       {
539         UpdateStateWithAncestorStructures();
540         UpdateRaytracableWithAncestorStructures();
541       }
542 #endif
543
544       // Delete object
545       OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (theGroup));
546       return;
547     }
548   }
549 }
550
551 // =======================================================================
552 // function : Clear
553 // purpose  :
554 // =======================================================================
555 void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
556 {
557 #ifdef HAVE_OPENCL
558   Standard_Boolean aRaytracableGroupDeleted (Standard_False);
559 #endif
560
561   // Release groups
562   for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
563   {
564 #ifdef HAVE_OPENCL
565     aRaytracableGroupDeleted |= anIter.Value()->IsRaytracable();
566 #endif
567     
568     // Delete objects
569     OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
570   }
571   myGroups.Clear();
572
573 #ifdef HAVE_OPENCL
574   if (aRaytracableGroupDeleted)
575   {
576     UpdateStateWithAncestorStructures();
577     UpdateRaytracableWithAncestorStructures();
578   }
579 #endif
580 }
581
582 // =======================================================================
583 // function : Render
584 // purpose  :
585 // =======================================================================
586 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
587 {
588   // Process the structure only if visible
589   if ( myNamedStatus & OPENGL_NS_HIDE )
590     return;
591
592   // Render named status
593   const Standard_Integer named_status = AWorkspace->NamedStatus;
594   AWorkspace->NamedStatus |= myNamedStatus;
595
596   // Is rendering in ADD or IMMEDIATE mode?
597   const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
598
599   const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
600
601   // Apply local transformation
602   GLint matrix_mode = 0;
603   const OpenGl_Matrix *local_trsf = NULL;
604   if (myTransformation)
605   {
606     if (isImmediate)
607     {
608       Tmatrix3 aModelWorld;
609       call_util_transpose_mat (*aModelWorld, myTransformation->mat);
610       glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
611
612       if (!aCtx->ShaderManager()->IsEmpty())
613       {
614         Tmatrix3 aWorldView;
615         glGetFloatv (GL_MODELVIEW_MATRIX, *aWorldView);
616
617         Tmatrix3 aProjection;
618         glGetFloatv (GL_PROJECTION_MATRIX, *aProjection);
619
620         aCtx->ShaderManager()->UpdateModelWorldStateTo (aModelWorld);
621         aCtx->ShaderManager()->UpdateWorldViewStateTo (aWorldView);
622         aCtx->ShaderManager()->UpdateProjectionStateTo (aProjection);
623       }
624
625       glMatrixMode (GL_MODELVIEW);
626       glPushMatrix ();
627       glScalef (1.F, 1.F, 1.F);
628       glMultMatrixf (*aModelWorld);
629     }
630     else
631     {
632       glMatrixMode (GL_MODELVIEW);
633       glPushMatrix();
634
635       local_trsf = AWorkspace->SetStructureMatrix (myTransformation);
636     }
637   }
638
639   // Apply transform persistence
640   const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
641   if ( myTransPers && myTransPers->mode != 0 )
642   {
643     trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence (aCtx, myTransPers);
644   }
645
646   // Apply aspects
647   const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
648   const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
649   const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
650   const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
651   if (myAspectLine)
652     AWorkspace->SetAspectLine(myAspectLine);
653   if (myAspectFace)
654     AWorkspace->SetAspectFace(myAspectFace);
655   if (myAspectMarker)
656     AWorkspace->SetAspectMarker(myAspectMarker);
657   if (myAspectText)
658     AWorkspace->SetAspectText(myAspectText);
659
660   // Apply highlight box
661   if (myHighlightBox)
662     myHighlightBox->Render( AWorkspace );
663
664   // Apply highlight color
665   const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
666   if (myHighlightColor)
667     AWorkspace->HighlightColor = myHighlightColor;
668
669   // Render connected structures
670   OpenGl_ListOfStructure::Iterator its(myConnected);
671   while (its.More())
672   {
673     its.Value()->Render(AWorkspace);
674     its.Next();
675   }
676
677   // Set up plane equations for non-structure transformed global model-view matrix
678   const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
679
680   // List of planes to be applied to context state
681   Handle(Graphic3d_SequenceOfHClipPlane) aUserPlanes;
682
683   // Collect clipping planes of structure scope
684   if (!myClipPlanes.IsEmpty())
685   {
686     Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
687     for (; aClippingIt.More(); aClippingIt.Next())
688     {
689       const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
690       if (!aClipPlane->IsOn())
691       {
692         continue;
693       }
694
695       if (aUserPlanes.IsNull())
696       {
697         aUserPlanes = new Graphic3d_SequenceOfHClipPlane();
698       }
699
700       aUserPlanes->Append (aClipPlane);
701     }
702   }
703
704   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
705   {
706     // add planes at loaded view matrix state
707     aContext->ChangeClipping().AddWorld (*aUserPlanes, AWorkspace);
708
709     // Set OCCT state uniform variables
710     if (!aContext->ShaderManager()->IsEmpty())
711     {
712       aContext->ShaderManager()->UpdateClippingState();
713     }
714   }
715
716   // Render groups
717   OpenGl_ListOfGroup::Iterator itg(myGroups);
718   while (itg.More())
719   {
720     itg.Value()->Render(AWorkspace);
721     itg.Next();
722   }
723
724   // Render capping for structure groups
725   if (!aContext->Clipping().Planes().IsEmpty())
726   {
727     OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
728   }
729
730   // Revert structure clippings
731   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
732   {
733     aContext->ChangeClipping().Remove (*aUserPlanes);
734
735     // Set OCCT state uniform variables
736     if (!aContext->ShaderManager()->IsEmpty())
737     {
738       aContext->ShaderManager()->RevertClippingState();
739     }
740   }
741
742   // Restore highlight color
743   AWorkspace->HighlightColor = highlight_color;
744
745   // Restore aspects
746   AWorkspace->SetAspectLine(aspect_line);
747   AWorkspace->SetAspectFace(aspect_face);
748   AWorkspace->SetAspectMarker(aspect_marker);
749   AWorkspace->SetAspectText(aspect_text);
750
751   // Restore transform persistence
752   if ( myTransPers && myTransPers->mode != 0 )
753   {
754     AWorkspace->ActiveView()->BeginTransformPersistence (aContext, trans_pers);
755   }
756
757   // Restore local transformation
758   if (myTransformation)
759   {
760     if (isImmediate)
761     {
762       glPopMatrix ();
763       glMatrixMode (matrix_mode);
764
765       Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
766                                     { 0.f, 1.f, 0.f, 0.f },
767                                     { 0.f, 0.f, 1.f, 0.f },
768                                     { 0.f, 0.f, 0.f, 1.f } };
769
770       aContext->ShaderManager()->RevertModelWorldStateTo (aModelWorldState);
771     }
772     else
773     {
774       AWorkspace->SetStructureMatrix (local_trsf, true);
775
776       glMatrixMode (GL_MODELVIEW);
777       glPopMatrix();
778     }
779   }
780
781   // Restore named status
782   AWorkspace->NamedStatus = named_status;
783 }
784
785 // =======================================================================
786 // function : Release
787 // purpose  :
788 // =======================================================================
789 void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
790 {
791   // Release groups
792   Clear (theGlCtx);
793   OpenGl_Element::Destroy (theGlCtx, myAspectLine);
794   OpenGl_Element::Destroy (theGlCtx, myAspectFace);
795   OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
796   OpenGl_Element::Destroy (theGlCtx, myAspectText);
797   ClearHighlightColor (theGlCtx);
798
799 #ifdef HAVE_OPENCL
800   // Remove from connected list of ancestor
801   UnregisterFromAncestorStructure();
802 #endif
803 }
804
805 // =======================================================================
806 // function : ReleaseGlResources
807 // purpose  :
808 // =======================================================================
809 void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
810 {
811   for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
812   {
813     OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
814     if (aGroup != NULL)
815     {
816       aGroup->Release (theGlCtx);
817     }
818   }
819   if (myAspectLine != NULL)
820   {
821     myAspectLine->Release (theGlCtx);
822   }
823   if (myAspectFace != NULL)
824   {
825     myAspectFace->Release (theGlCtx);
826   }
827   if (myAspectMarker != NULL)
828   {
829     myAspectMarker->Release (theGlCtx);
830   }
831   if (myAspectText != NULL)
832   {
833     myAspectText->Release (theGlCtx);
834   }
835   if (myHighlightBox != NULL)
836   {
837     myHighlightBox->Release (theGlCtx);
838   }
839 }
840
841 //=======================================================================
842 //function : SetZLayer
843 //purpose  :
844 //=======================================================================
845 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
846 {
847   myZLayer = theLayerIndex;
848 }
849
850 //=======================================================================
851 //function : GetZLayer
852 //purpose  :
853 //=======================================================================
854 Standard_Integer OpenGl_Structure::GetZLayer () const
855 {
856   return myZLayer;
857 }