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