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