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