Update of unstable Boolean test cases
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <OpenGl_CappingAlgo.hxx>
17 #include <OpenGl_Context.hxx>
18 #include <OpenGl_GlCore11.hxx>
19 #include <OpenGl_GraphicDriver.hxx>
20 #include <OpenGl_ShaderManager.hxx>
21 #include <OpenGl_ShaderProgram.hxx>
22 #include <OpenGl_StructureShadow.hxx>
23 #include <OpenGl_telem_util.hxx>
24 #include <OpenGl_Vec.hxx>
25 #include <OpenGl_View.hxx>
26 #include <OpenGl_Workspace.hxx>
27
28 #include <Graphic3d_SequenceOfHClipPlane.hxx>
29
30 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
77     // Use highlight colors
78     theWorkspace->GetGlContext()->core11->glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
79
80     glEnableClientState (GL_VERTEX_ARRAY);
81     glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
82     glDrawArrays (GL_LINE_STRIP, 0, 16);
83     glDisableClientState (GL_VERTEX_ARRAY);
84
85     // restore aspects
86     if (!aPrevTexture.IsNull())
87     {
88       theWorkspace->EnableTexture (aPrevTexture);
89     }
90   #endif
91   }
92
93   //! Release graphical resources
94   virtual void Release (OpenGl_Context*)
95   {
96     //
97   }
98
99 protected:
100
101   //! Protected destructor
102   virtual ~OpenGl_BndBoxPrs() {}
103
104 private:
105
106   OpenGl_Vec3 myVerts[16]; //!< vertices array
107
108 public:
109
110   DEFINE_STANDARD_ALLOC
111
112 };
113
114 /*----------------------------------------------------------------------*/
115
116 // =======================================================================
117 // function : OpenGl_Structure
118 // purpose  :
119 // =======================================================================
120 OpenGl_Structure::OpenGl_Structure (const Handle(Graphic3d_StructureManager)& theManager)
121 : Graphic3d_CStructure (theManager),
122   myTransformation(NULL),
123   myTransPers(NULL),
124   myAspectLine(NULL),
125   myAspectFace(NULL),
126   myAspectMarker(NULL),
127   myAspectText(NULL),
128   myHighlightColor(NULL),
129   myIsRaytracable (Standard_False),
130   myModificationState (0),
131   myIsCulled (Standard_True),
132   myIsMirrored (Standard_False)
133 {
134   //
135 }
136
137 // =======================================================================
138 // function : ~OpenGl_Structure
139 // purpose  :
140 // =======================================================================
141 OpenGl_Structure::~OpenGl_Structure()
142 {
143   Release (Handle(OpenGl_Context)());
144   delete myTransformation;  myTransformation  = NULL;
145   delete myTransPers;       myTransPers       = NULL;
146 }
147
148 // =======================================================================
149 // function : UpdateAspects
150 // purpose  :
151 // =======================================================================
152 void OpenGl_Structure::UpdateAspects()
153 {
154   SetTransformPersistence (TransformPersistence);
155
156   if (ContextLine.IsDef)
157     SetAspectLine (ContextLine);
158
159   if (ContextFillArea.IsDef)
160     SetAspectFace (ContextFillArea);
161
162   if (ContextMarker.IsDef)
163     SetAspectMarker (ContextMarker);
164
165   if (ContextText.IsDef)
166     SetAspectText (ContextText);
167 }
168
169 // =======================================================================
170 // function : UpdateTransformation
171 // purpose  :
172 // =======================================================================
173 void OpenGl_Structure::UpdateTransformation()
174 {
175   if (myTransformation == NULL)
176   {
177     myTransformation = new OpenGl_Matrix();
178   }
179
180   Standard_ShortReal (*aMat)[4] = Graphic3d_CStructure::Transformation;
181
182   Standard_ShortReal aDet =
183     aMat[0][0] * (aMat[1][1] * aMat[2][2] - aMat[2][1] * aMat[1][2]) -
184     aMat[0][1] * (aMat[1][0] * aMat[2][2] - aMat[2][0] * aMat[1][2]) +
185     aMat[0][2] * (aMat[1][0] * aMat[2][1] - aMat[2][0] * aMat[1][1]);
186
187   // Determinant of transform matrix less then 0 means that mirror transform applied.
188   myIsMirrored = aDet < 0.0f;
189
190   matcpy (myTransformation->mat, &Graphic3d_CStructure::Transformation[0][0]);
191
192   if (myIsRaytracable)
193   {
194     UpdateStateWithAncestorStructures();
195   }
196 }
197
198 // =======================================================================
199 // function : SetTransformPersistence
200 // purpose  :
201 // =======================================================================
202 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
203 {
204   if (!myTransPers)
205     myTransPers = new TEL_TRANSFORM_PERSISTENCE;
206
207   myTransPers->mode = ATransPers.Flag;
208   myTransPers->pointX = ATransPers.Point.x;
209   myTransPers->pointY = ATransPers.Point.y;
210   myTransPers->pointZ = ATransPers.Point.z;
211   MarkAsNotCulled();
212 }
213
214 // =======================================================================
215 // function : SetAspectLine
216 // purpose  :
217 // =======================================================================
218 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &theAspect)
219 {
220   if (!myAspectLine)
221   {
222     myAspectLine = new OpenGl_AspectLine();
223   }
224   myAspectLine->SetAspect (theAspect);
225 }
226
227 // =======================================================================
228 // function : SetAspectFace
229 // purpose  :
230 // =======================================================================
231 void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect)
232 {
233   if (!myAspectFace)
234   {
235     myAspectFace = new OpenGl_AspectFace();
236   }
237   myAspectFace->SetAspect (theAspect);
238
239   if (myIsRaytracable)
240   {
241     UpdateStateWithAncestorStructures();
242   }
243 }
244
245 // =======================================================================
246 // function : SetAspectMarker
247 // purpose  :
248 // =======================================================================
249 void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect)
250 {
251   if (!myAspectMarker)
252   {
253     myAspectMarker = new OpenGl_AspectMarker();
254   }
255   myAspectMarker->SetAspect (theAspect);
256 }
257
258 // =======================================================================
259 // function : SetAspectText
260 // purpose  :
261 // =======================================================================
262 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &theAspect)
263 {
264   if (!myAspectText)
265   {
266     myAspectText = new OpenGl_AspectText();
267   }
268   myAspectText->SetAspect (theAspect);
269 }
270
271 // =======================================================================
272 // function : clearHighlightBox
273 // purpose  :
274 // =======================================================================
275 void OpenGl_Structure::clearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
276 {
277   if (!myHighlightBox.IsNull())
278   {
279     myHighlightBox->Release (theGlCtx);
280     myHighlightBox.Nullify();
281   }
282 }
283
284 // =======================================================================
285 // function : HighlightWithColor
286 // purpose  :
287 // =======================================================================
288 void OpenGl_Structure::HighlightWithColor (const Graphic3d_Vec3&  theColor,
289                                            const Standard_Boolean theToCreate)
290 {
291   const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
292   if (theToCreate)
293     setHighlightColor   (aContext, theColor);
294   else
295     clearHighlightColor (aContext);
296 }
297
298 // =======================================================================
299 // function : HighlightWithBndBox
300 // purpose  :
301 // =======================================================================
302 void OpenGl_Structure::HighlightWithBndBox (const Handle(Graphic3d_Structure)& theStruct,
303                                             const Standard_Boolean             theToCreate)
304 {
305   const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
306   if (!theToCreate)
307   {
308     clearHighlightBox (aContext);
309     return;
310   }
311
312   if (!myHighlightBox.IsNull())
313   {
314     myHighlightBox->Release (aContext);
315   }
316   else
317   {
318     myHighlightBox = new OpenGl_Group (theStruct);
319   }
320
321   CALL_DEF_CONTEXTLINE& aContextLine = myHighlightBox->ChangeContextLine();
322   aContextLine.IsDef    = 1;
323   aContextLine.Color    = HighlightColor;
324   aContextLine.LineType = Aspect_TOL_SOLID;
325   aContextLine.Width    = 1.0f;
326   myHighlightBox->UpdateAspectLine (Standard_True);
327
328   OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (myBndBox);
329   myHighlightBox->AddElement (aBndBoxPrs);
330 }
331
332 // =======================================================================
333 // function : setHighlightColor
334 // purpose  :
335 // =======================================================================
336 void OpenGl_Structure::setHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
337                                           const Graphic3d_Vec3&         theColor)
338 {
339   clearHighlightBox (theGlCtx);
340   if (myHighlightColor == NULL)
341   {
342     myHighlightColor = new TEL_COLOUR();
343   }
344
345   myHighlightColor->rgb[0] = theColor.r();
346   myHighlightColor->rgb[1] = theColor.g();
347   myHighlightColor->rgb[2] = theColor.b();
348   myHighlightColor->rgb[3] = 1.F;
349 }
350
351 // =======================================================================
352 // function : clearHighlightColor
353 // purpose  :
354 // =======================================================================
355 void OpenGl_Structure::clearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
356 {
357   clearHighlightBox(theGlCtx);
358   delete myHighlightColor;
359   myHighlightColor = NULL;
360 }
361
362 // =======================================================================
363 // function : OnVisibilityChanged
364 // purpose  :
365 // =======================================================================
366 void OpenGl_Structure::OnVisibilityChanged()
367 {
368   if (myIsRaytracable)
369   {
370     UpdateStateWithAncestorStructures();
371   }
372 }
373
374 // =======================================================================
375 // function : RegisterAncestorStructure
376 // purpose  :
377 // =======================================================================
378 void OpenGl_Structure::RegisterAncestorStructure (const OpenGl_Structure* theStructure) const
379 {
380   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
381   {
382     if (anIt.Value() == theStructure)
383     {
384       return;
385     }
386   }
387
388   myAncestorStructures.Append (theStructure);
389 }
390
391 // =======================================================================
392 // function : UnregisterAncestorStructure
393 // purpose  :
394 // =======================================================================
395 void OpenGl_Structure::UnregisterAncestorStructure (const OpenGl_Structure* theStructure) const
396 {
397   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
398   {
399     if (anIt.Value() == theStructure)
400     {
401       myAncestorStructures.Remove (anIt);
402       return;
403     }
404   }
405 }
406
407 // =======================================================================
408 // function : UnregisterFromAncestorStructure
409 // purpose  :
410 // =======================================================================
411 void OpenGl_Structure::UnregisterFromAncestorStructure() const
412 {
413   for (OpenGl_ListOfStructure::Iterator anIta (myAncestorStructures); anIta.More(); anIta.Next())
414   {
415     OpenGl_Structure* anAncestor = const_cast<OpenGl_Structure*> (anIta.ChangeValue());
416
417     for (OpenGl_ListOfStructure::Iterator anIts (anAncestor->myConnected); anIts.More(); anIts.Next())
418     {
419       if (anIts.Value() == this)
420       {
421         anAncestor->myConnected.Remove (anIts);
422         return;
423       }
424     }
425   }
426 }
427
428 // =======================================================================
429 // function : UpdateStateWithAncestorStructures
430 // purpose  :
431 // =======================================================================
432 void OpenGl_Structure::UpdateStateWithAncestorStructures() const
433 {
434   myModificationState++;
435
436   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
437   {
438     anIt.Value()->UpdateStateWithAncestorStructures();
439   }
440 }
441
442 // =======================================================================
443 // function : UpdateRaytracableWithAncestorStructures
444 // purpose  :
445 // =======================================================================
446 void OpenGl_Structure::UpdateRaytracableWithAncestorStructures() const
447 {
448   myIsRaytracable = OpenGl_Raytrace::IsRaytracedStructure (this);
449
450   if (!myIsRaytracable)
451   {
452     for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
453     {
454       anIt.Value()->UpdateRaytracableWithAncestorStructures();
455     }
456   }
457 }
458
459 // =======================================================================
460 // function : SetRaytracableWithAncestorStructures
461 // purpose  :
462 // =======================================================================
463 void OpenGl_Structure::SetRaytracableWithAncestorStructures() const
464 {
465   myIsRaytracable = Standard_True;
466
467   for (OpenGl_ListOfStructure::Iterator anIt (myAncestorStructures); anIt.More(); anIt.Next())
468   {
469     if (!anIt.Value()->IsRaytracable())
470     {
471       anIt.Value()->SetRaytracableWithAncestorStructures();
472     }
473   }
474 }
475
476 // =======================================================================
477 // function : Connect
478 // purpose  :
479 // =======================================================================
480 void OpenGl_Structure::Connect (Graphic3d_CStructure& theStructure)
481 {
482   OpenGl_Structure* aStruct = (OpenGl_Structure* )&theStructure;
483   Disconnect (theStructure);
484   myConnected.Append (aStruct);
485
486   if (aStruct->IsRaytracable())
487   {
488     UpdateStateWithAncestorStructures();
489     SetRaytracableWithAncestorStructures();
490   }
491
492   aStruct->RegisterAncestorStructure (this);
493 }
494
495 // =======================================================================
496 // function : Disconnect
497 // purpose  :
498 // =======================================================================
499 void OpenGl_Structure::Disconnect (Graphic3d_CStructure& theStructure)
500 {
501   OpenGl_Structure* aStruct = (OpenGl_Structure* )&theStructure;
502   for (OpenGl_ListOfStructure::Iterator anIter (myConnected); anIter.More(); anIter.Next())
503   {
504     // Check for the given structure
505     if (anIter.Value() == aStruct)
506     {
507       myConnected.Remove (anIter);
508
509       if (aStruct->IsRaytracable())
510       {
511         UpdateStateWithAncestorStructures();
512         UpdateRaytracableWithAncestorStructures();
513       }
514
515       aStruct->UnregisterAncestorStructure (this);
516       return;
517     }
518   }
519 }
520
521 // =======================================================================
522 // function : NewGroup
523 // purpose  :
524 // =======================================================================
525 Handle(Graphic3d_Group) OpenGl_Structure::NewGroup (const Handle(Graphic3d_Structure)& theStruct)
526 {
527   Handle(OpenGl_Group) aGroup = new OpenGl_Group (theStruct);
528   myGroups.Append (aGroup);
529   return aGroup;
530 }
531
532 // =======================================================================
533 // function : RemoveGroup
534 // purpose  :
535 // =======================================================================
536 void OpenGl_Structure::RemoveGroup (const Handle(Graphic3d_Group)& theGroup)
537 {
538   if (theGroup.IsNull())
539   {
540     return;
541   }
542
543   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
544   {
545     // Check for the given group
546     if (aGroupIter.Value() == theGroup)
547     {
548       theGroup->Clear (Standard_False);
549
550       if (((OpenGl_Group* )theGroup.operator->())->IsRaytracable())
551       {
552         UpdateStateWithAncestorStructures();
553         UpdateRaytracableWithAncestorStructures();
554       }
555
556       myGroups.Remove (aGroupIter);
557       return;
558     }
559   }
560 }
561
562 // =======================================================================
563 // function : Clear
564 // purpose  :
565 // =======================================================================
566 void OpenGl_Structure::Clear()
567 {
568   Clear (GlDriver()->GetSharedContext());
569 }
570
571 // =======================================================================
572 // function : Clear
573 // purpose  :
574 // =======================================================================
575 void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
576 {
577   Standard_Boolean aRaytracableGroupDeleted (Standard_False);
578
579   // Release groups
580   for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
581   {
582     aRaytracableGroupDeleted |= aGroupIter.Value()->IsRaytracable();
583
584     // Delete objects
585     aGroupIter.ChangeValue()->Release (theGlCtx);
586   }
587   myGroups.Clear();
588
589   if (aRaytracableGroupDeleted)
590   {
591     UpdateStateWithAncestorStructures();
592     UpdateRaytracableWithAncestorStructures();
593   }
594
595   Is2dText       = Standard_False;
596   IsForHighlight = Standard_False;
597 }
598
599 // =======================================================================
600 // function : RenderGeometry
601 // purpose  :
602 // =======================================================================
603 void OpenGl_Structure::RenderGeometry (const Handle(OpenGl_Workspace) &theWorkspace) const
604 {
605   // Render groups
606   const Graphic3d_SequenceOfGroup& aGroups = DrawGroups();
607   for (OpenGl_Structure::GroupIterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
608   {
609     aGroupIter.Value()->Render (theWorkspace);
610   }
611 }
612
613 // =======================================================================
614 // function : Render
615 // purpose  :
616 // =======================================================================
617 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
618 {
619   // Process the structure only if visible
620   if (!visible)
621   {
622     return;
623   }
624
625   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
626
627   // Render named status
628   const Standard_Integer aNamedStatus = theWorkspace->NamedStatus;
629   if (highlight)
630   {
631     theWorkspace->NamedStatus |= OPENGL_NS_HIGHLIGHT;
632   }
633
634   // Do we need to restore GL_NORMALIZE?
635   const Standard_Boolean anOldGlNormalize = aCtx->IsGlNormalizeEnabled();
636
637   // Apply local transformation
638   if (myTransformation)
639   {
640     OpenGl_Matrix aModelWorld;
641     OpenGl_Transposemat3 (&aModelWorld, myTransformation);
642     aCtx->ModelWorldState.Push();
643     aCtx->ModelWorldState.SetCurrent (OpenGl_Mat4::Map ((Standard_ShortReal* )aModelWorld.mat));
644
645     Standard_ShortReal aScaleX = OpenGl_Vec3 (myTransformation->mat[0][0],
646                                               myTransformation->mat[0][1],
647                                               myTransformation->mat[0][2]).SquareModulus();
648     // Scale transform detected.
649     if (Abs (aScaleX - 1.f) > Precision::Confusion())
650     {
651       aCtx->SetGlNormalizeEnabled (Standard_True);
652     }
653   }
654
655   // Apply transform persistence
656   const TEL_TRANSFORM_PERSISTENCE *aTransPersistence = NULL;
657   if ( myTransPers && myTransPers->mode != 0 )
658   {
659     aTransPersistence = theWorkspace->ActiveView()->BeginTransformPersistence (aCtx, myTransPers, theWorkspace->Width(), theWorkspace->Height());
660   }
661
662   // Take into account transform persistence
663   aCtx->ApplyModelViewMatrix();
664
665   // Apply aspects
666   const OpenGl_AspectLine *anAspectLine = theWorkspace->AspectLine (Standard_False);
667   const OpenGl_AspectFace *anAspectFace = theWorkspace->AspectFace (Standard_False);
668   const OpenGl_AspectMarker *anAspectMarker = theWorkspace->AspectMarker (Standard_False);
669   const OpenGl_AspectText *anAspectText = theWorkspace->AspectText (Standard_False);
670   if (myAspectLine)
671   {
672     theWorkspace->SetAspectLine (myAspectLine);
673   }
674   if (myAspectFace)
675   {
676     theWorkspace->SetAspectFace (myAspectFace);
677   }
678   if (myAspectMarker)
679   {
680     theWorkspace->SetAspectMarker (myAspectMarker);
681   }
682   if (myAspectText)
683   {
684     theWorkspace->SetAspectText (myAspectText);
685   }
686
687   // Apply correction for mirror transform
688   if (myIsMirrored)
689   {
690     aCtx->core11fwd->glFrontFace (GL_CW);
691   }
692
693   // Apply highlight color
694   const TEL_COLOUR *aHighlightColor = theWorkspace->HighlightColor;
695   if (myHighlightColor)
696     theWorkspace->HighlightColor = myHighlightColor;
697
698   // Render connected structures
699   OpenGl_ListOfStructure::Iterator anIter (myConnected);
700   while (anIter.More())
701   {
702     anIter.Value()->RenderGeometry (theWorkspace);
703     anIter.Next();
704   }
705
706   // Set up plane equations for non-structure transformed global model-view matrix
707   // List of planes to be applied to context state
708   NCollection_Handle<Graphic3d_SequenceOfHClipPlane> aUserPlanes;
709
710   // Collect clipping planes of structure scope
711   if (!myClipPlanes.IsEmpty())
712   {
713     Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes);
714     for (; aClippingIter.More(); aClippingIter.Next())
715     {
716       const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIter.Value();
717       if (!aClipPlane->IsOn())
718       {
719         continue;
720       }
721
722       if (aUserPlanes.IsNull())
723       {
724         aUserPlanes = new Graphic3d_SequenceOfHClipPlane();
725       }
726
727       aUserPlanes->Append (aClipPlane);
728     }
729   }
730
731   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
732   {
733     // add planes at loaded view matrix state
734     aCtx->ChangeClipping().AddWorld (*aUserPlanes, theWorkspace);
735
736     // Set OCCT state uniform variables
737     if (!aCtx->ShaderManager()->IsEmpty())
738     {
739       aCtx->ShaderManager()->UpdateClippingState();
740     }
741   }
742
743   // Render groups
744   const Graphic3d_SequenceOfGroup& aGroups = DrawGroups();
745   for (OpenGl_Structure::GroupIterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
746   {
747     aGroupIter.Value()->Render (theWorkspace);
748   }
749
750   // Reset correction for mirror transform
751   if (myIsMirrored)
752   {
753     aCtx->core11fwd->glFrontFace (GL_CCW);
754   }
755
756   // Render capping for structure groups
757   if (!aCtx->Clipping().Planes().IsEmpty())
758   {
759     OpenGl_CappingAlgo::RenderCapping (theWorkspace, aGroups);
760   }
761
762   // Revert structure clippings
763   if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
764   {
765     aCtx->ChangeClipping().Remove (*aUserPlanes);
766
767     // Set OCCT state uniform variables
768     if (!aCtx->ShaderManager()->IsEmpty())
769     {
770       aCtx->ShaderManager()->RevertClippingState();
771     }
772   }
773
774   // Apply local transformation
775   if (myTransformation)
776   {
777     aCtx->ModelWorldState.Pop();
778     aCtx->SetGlNormalizeEnabled (anOldGlNormalize);
779   }
780
781   // Restore highlight color
782   theWorkspace->HighlightColor = aHighlightColor;
783
784   // Restore aspects
785   theWorkspace->SetAspectLine (anAspectLine);
786   theWorkspace->SetAspectFace (anAspectFace);
787   theWorkspace->SetAspectMarker (anAspectMarker);
788   theWorkspace->SetAspectText (anAspectText);
789
790   // Restore transform persistence
791   if ( myTransPers && myTransPers->mode != 0 )
792   {
793     theWorkspace->ActiveView()->BeginTransformPersistence (aCtx, aTransPersistence, theWorkspace->Width(), theWorkspace->Height());
794   }
795
796   // Apply highlight box
797   if (!myHighlightBox.IsNull())
798   {
799     myHighlightBox->Render (theWorkspace);
800   }
801
802   // Restore named status
803   theWorkspace->NamedStatus = aNamedStatus;
804 }
805
806 // =======================================================================
807 // function : Release
808 // purpose  :
809 // =======================================================================
810 void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
811 {
812   // Release groups
813   Clear (theGlCtx);
814   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectLine);
815   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectFace);
816   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker);
817   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText);
818   clearHighlightColor (theGlCtx);
819
820   // Remove from connected list of ancestor
821   UnregisterFromAncestorStructure();
822 }
823
824 // =======================================================================
825 // function : ReleaseGlResources
826 // purpose  :
827 // =======================================================================
828 void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
829 {
830   for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
831   {
832     aGroupIter.ChangeValue()->Release (theGlCtx);
833   }
834   if (myAspectLine != NULL)
835   {
836     myAspectLine->Release (theGlCtx.operator->());
837   }
838   if (myAspectFace != NULL)
839   {
840     myAspectFace->Release (theGlCtx.operator->());
841   }
842   if (myAspectMarker != NULL)
843   {
844     myAspectMarker->Release (theGlCtx.operator->());
845   }
846   if (myAspectText != NULL)
847   {
848     myAspectText->Release (theGlCtx.operator->());
849   }
850   if (!myHighlightBox.IsNull())
851   {
852     myHighlightBox->Release (theGlCtx.operator->());
853   }
854 }
855
856 //=======================================================================
857 //function : ShadowLink
858 //purpose  :
859 //=======================================================================
860 Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const
861 {
862   return new OpenGl_StructureShadow (theManager, this);
863 }