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