0025133: TKOpenGl - Crash on closing a view containing presentations with capping
[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 : Render
611 // purpose  :
612 // =======================================================================
613 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
614 {
615   // Process the structure only if visible
616   if ( myNamedStatus & OPENGL_NS_HIDE )
617     return;
618
619   const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
620
621   // Render named status
622   const Standard_Integer named_status = AWorkspace->NamedStatus;
623   AWorkspace->NamedStatus |= myNamedStatus;
624
625   // Is rendering in ADD or IMMEDIATE mode?
626   const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & OPENGL_NS_IMMEDIATE) != 0;
627
628   // Apply local transformation
629   GLint matrix_mode = 0;
630   const OpenGl_Matrix *local_trsf = NULL;
631   if (myTransformation)
632   {
633     if (isImmediate)
634     {
635       Tmatrix3 aModelWorld;
636       call_util_transpose_mat (*aModelWorld, myTransformation->mat);
637       glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
638
639       if (!aCtx->ShaderManager()->IsEmpty())
640       {
641         Tmatrix3 aWorldView;
642         glGetFloatv (GL_MODELVIEW_MATRIX, *aWorldView);
643
644         Tmatrix3 aProjection;
645         glGetFloatv (GL_PROJECTION_MATRIX, *aProjection);
646
647         aCtx->ShaderManager()->UpdateModelWorldStateTo (&aModelWorld);
648         aCtx->ShaderManager()->UpdateWorldViewStateTo (&aWorldView);
649         aCtx->ShaderManager()->UpdateProjectionStateTo (&aProjection);
650       }
651
652       glMatrixMode (GL_MODELVIEW);
653       glPushMatrix ();
654       glScalef (1.F, 1.F, 1.F);
655       glMultMatrixf (*aModelWorld);
656     }
657     else
658     {
659       glMatrixMode (GL_MODELVIEW);
660       glPushMatrix();
661
662       local_trsf = AWorkspace->SetStructureMatrix (myTransformation);
663     }
664   }
665
666   // Apply transform persistence
667   const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
668   if ( myTransPers && myTransPers->mode != 0 )
669   {
670     trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence (aCtx, myTransPers);
671   }
672
673   // Apply aspects
674   const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
675   const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
676   const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
677   const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
678   if (myAspectLine)
679     AWorkspace->SetAspectLine(myAspectLine);
680   if (myAspectFace)
681     AWorkspace->SetAspectFace(myAspectFace);
682   if (myAspectMarker)
683     AWorkspace->SetAspectMarker(myAspectMarker);
684   if (myAspectText)
685     AWorkspace->SetAspectText(myAspectText);
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   // Apply highlight box
804   if (!myHighlightBox.IsNull())
805   {
806     myHighlightBox->Render (AWorkspace);
807   }
808
809   // Restore named status
810   AWorkspace->NamedStatus = named_status;
811 }
812
813 // =======================================================================
814 // function : Release
815 // purpose  :
816 // =======================================================================
817 void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
818 {
819   // Release groups
820   Clear (theGlCtx);
821   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectLine);
822   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectFace);
823   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker);
824   OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText);
825   clearHighlightColor (theGlCtx);
826
827   // Remove from connected list of ancestor
828   UnregisterFromAncestorStructure();
829 }
830
831 // =======================================================================
832 // function : ReleaseGlResources
833 // purpose  :
834 // =======================================================================
835 void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
836 {
837   for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next())
838   {
839     aGroupIter.ChangeValue()->Release (theGlCtx);
840   }
841   if (myAspectLine != NULL)
842   {
843     myAspectLine->Release (theGlCtx.operator->());
844   }
845   if (myAspectFace != NULL)
846   {
847     myAspectFace->Release (theGlCtx.operator->());
848   }
849   if (myAspectMarker != NULL)
850   {
851     myAspectMarker->Release (theGlCtx.operator->());
852   }
853   if (myAspectText != NULL)
854   {
855     myAspectText->Release (theGlCtx.operator->());
856   }
857   if (!myHighlightBox.IsNull())
858   {
859     myHighlightBox->Release (theGlCtx.operator->());
860   }
861 }
862
863 //=======================================================================
864 //function : SetZLayer
865 //purpose  :
866 //=======================================================================
867 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
868 {
869   myZLayer = theLayerIndex;
870 }
871
872 //=======================================================================
873 //function : GetZLayer
874 //purpose  :
875 //=======================================================================
876 Standard_Integer OpenGl_Structure::GetZLayer () const
877 {
878   return myZLayer;
879 }
880
881 //! Dummy structure which just redirects to groups of another structure.
882 class OpenGl_StructureShadow : public OpenGl_Structure
883 {
884
885 public:
886
887   //! Create empty structure
888   OpenGl_StructureShadow (const Handle(Graphic3d_StructureManager)& theManager,
889                           const Handle(OpenGl_Structure)&           theStructure);
890
891   virtual const Graphic3d_SequenceOfGroup& DrawGroups() const { return myParent->DrawGroups(); }
892
893 private:
894
895   Handle(OpenGl_Structure) myParent;
896
897 public:
898
899   DEFINE_STANDARD_RTTI(OpenGl_Structure) // Type definition
900
901 };
902
903 DEFINE_STANDARD_HANDLE(OpenGl_StructureShadow, OpenGl_Structure)
904
905 IMPLEMENT_STANDARD_HANDLE (OpenGl_StructureShadow, OpenGl_Structure)
906 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_StructureShadow, OpenGl_Structure)
907
908 //=======================================================================
909 //function : OpenGl_StructureShadow
910 //purpose  :
911 //=======================================================================
912 OpenGl_StructureShadow::OpenGl_StructureShadow (const Handle(Graphic3d_StructureManager)& theManager,
913                                                 const Handle(OpenGl_Structure)&           theStructure)
914 : OpenGl_Structure (theManager)
915 {
916   Handle(OpenGl_StructureShadow) aShadow = Handle(OpenGl_StructureShadow)::DownCast (theStructure);
917   myParent = aShadow.IsNull() ? theStructure : aShadow->myParent;
918
919
920   Composition   = myParent->Composition;
921   ContainsFacet = myParent->ContainsFacet;
922   IsInfinite    = myParent->IsInfinite;
923   for (Standard_Integer i = 0; i <= 3; ++i)
924   {
925     for (Standard_Integer j = 0; j <= 3; ++j)
926     {
927       Graphic3d_CStructure::Transformation[i][j] = myParent->Graphic3d_CStructure::Transformation[i][j];
928     }
929   }
930
931   TransformPersistence.IsSet = myParent->TransformPersistence.IsSet;
932   TransformPersistence.Flag  = myParent->TransformPersistence.Flag;
933   TransformPersistence.Point = myParent->TransformPersistence.Point;
934 }
935
936 //=======================================================================
937 //function : ShadowLink
938 //purpose  :
939 //=======================================================================
940 Handle(Graphic3d_CStructure) OpenGl_Structure::ShadowLink (const Handle(Graphic3d_StructureManager)& theManager) const
941 {
942   return new OpenGl_StructureShadow (theManager, this);
943 }