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