0024590: Crash when processing OpenGl_BndBoxPrs objects
[occt.git] / src / OpenGl / OpenGl_Group.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
8 // under the terms of the GNU Lesser General Public 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 #ifdef HAVE_CONFIG_H
17   #include <config.h>
18 #endif
19
20 #include <OpenGl_Group.hxx>
21 #include <OpenGl_PrimitiveArray.hxx>
22 #include <OpenGl_Structure.hxx>
23 #include <OpenGl_Workspace.hxx>
24
25 // =======================================================================
26 // function : OpenGl_Group
27 // purpose  :
28 // =======================================================================
29 #ifndef HAVE_OPENCL
30 OpenGl_Group::OpenGl_Group()
31 #else
32 OpenGl_Group::OpenGl_Group (const OpenGl_Structure* theAncestorStructure)
33 #endif
34 : myAspectLine(NULL),
35   myAspectFace(NULL),
36   myAspectMarker(NULL),
37   myAspectText(NULL),
38   myFirst(NULL),
39   myLast(NULL)
40 {
41 #ifdef HAVE_OPENCL
42   myAncestorStructure = theAncestorStructure;
43   myIsRaytracable = Standard_False;
44   myModificationState = 0; // initial state
45 #endif
46 }
47
48 // =======================================================================
49 // function : ~OpenGl_Group
50 // purpose  :
51 // =======================================================================
52 OpenGl_Group::~OpenGl_Group()
53 {
54   Release (Handle(OpenGl_Context)());
55 }
56
57 // =======================================================================
58 // function : SetAspectLine
59 // purpose  :
60 // =======================================================================
61 void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theAspect,
62                                   const Standard_Boolean theIsGlobal)
63 {
64   if (theIsGlobal || myFirst == NULL)
65   {
66     if (myAspectLine == NULL)
67     {
68       myAspectLine = new OpenGl_AspectLine();
69     }
70     myAspectLine->SetAspect (theAspect);
71   }
72   else
73   {
74     OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine();
75     anAspectLine->SetAspect (theAspect);
76     AddElement (anAspectLine);
77   }
78 }
79
80 // =======================================================================
81 // function : SetAspectFace
82 // purpose  :
83 // =======================================================================
84 void OpenGl_Group::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA& theAspect,
85                                   const Standard_Boolean          theIsGlobal)
86 {
87   if (theIsGlobal || myFirst == NULL)
88   {
89     if (myAspectFace == NULL)
90     {
91       myAspectFace = new OpenGl_AspectFace();
92     }
93     myAspectFace->SetAspect (theAspect);
94   }
95   else
96   {
97     OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace();
98     anAspectFace->SetAspect (theAspect);
99     AddElement (anAspectFace);
100   }
101
102 #ifdef HAVE_OPENCL
103   if (myIsRaytracable)
104   {
105     myModificationState++;
106
107     if (myAncestorStructure != NULL)
108     {
109       myAncestorStructure->UpdateStateWithAncestorStructures();
110     }
111   }
112 #endif
113 }
114
115 // =======================================================================
116 // function : SetAspectMarker
117 // purpose  :
118 // =======================================================================
119 void OpenGl_Group::SetAspectMarker (const CALL_DEF_CONTEXTMARKER& theAspect,
120                                     const Standard_Boolean theIsGlobal)
121 {
122   if (theIsGlobal || myFirst == NULL)
123   {
124     if (myAspectMarker == NULL)
125     {
126       myAspectMarker = new OpenGl_AspectMarker();
127     }
128     myAspectMarker->SetAspect (theAspect);
129   }
130   else
131   {
132     OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker();
133     anAspectMarker->SetAspect (theAspect);
134     AddElement (anAspectMarker);
135   }
136 }
137
138 // =======================================================================
139 // function : SetAspectText
140 // purpose  :
141 // =======================================================================
142 void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theAspect,
143                                   const Standard_Boolean theIsGlobal)
144 {
145   if (theIsGlobal || myFirst == NULL)
146   {
147     if (myAspectText == NULL)
148     {
149       myAspectText = new OpenGl_AspectText();
150     }
151     myAspectText->SetAspect (theAspect);
152   }
153   else
154   {
155     OpenGl_AspectText* anAspectText = new OpenGl_AspectText();
156     anAspectText->SetAspect (theAspect);
157     AddElement (anAspectText);
158   }
159 }
160
161 // =======================================================================
162 // function : AddElement
163 // purpose  :
164 // =======================================================================
165 void OpenGl_Group::AddElement (OpenGl_Element* theElem)
166 {
167   OpenGl_ElementNode *aNode = new OpenGl_ElementNode();
168
169   aNode->elem = theElem;
170   aNode->next = NULL;
171   (myLast? myLast->next : myFirst) = aNode;
172   myLast = aNode;
173
174 #ifdef HAVE_OPENCL
175   if (OpenGl_Raytrace::IsRaytracedElement (aNode))
176   {
177     myModificationState++;
178     myIsRaytracable = Standard_True;
179
180     if (myAncestorStructure != NULL)
181     {
182       myAncestorStructure->UpdateStateWithAncestorStructures();
183       myAncestorStructure->SetRaytracableWithAncestorStructures();
184     }
185   }
186 #endif
187 }
188
189 // =======================================================================
190 // function : Render
191 // purpose  :
192 // =======================================================================
193 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
194 {
195   // Is rendering in ADD or IMMEDIATE mode?
196   const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
197
198   // Setup aspects
199   const OpenGl_AspectLine*   aBackAspectLine   = theWorkspace->AspectLine   (Standard_False);
200   const OpenGl_AspectFace*   aBackAspectFace   = theWorkspace->AspectFace   (Standard_False);
201   const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
202   const OpenGl_AspectText*   aBackAspectText   = theWorkspace->AspectText   (Standard_False);
203   Standard_Boolean isLineSet   = myAspectLine   && myAspectLine->RenderFiltered (theWorkspace, aFilter);
204   Standard_Boolean isFaceSet   = myAspectFace   && myAspectFace->RenderFiltered (theWorkspace, aFilter);
205   Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
206   Standard_Boolean isTextSet   = myAspectText   && myAspectText->RenderFiltered (theWorkspace, aFilter);
207
208   // Render group elements
209   for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
210   {
211     aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
212   }
213
214   // Restore aspects
215   if (isLineSet)
216     theWorkspace->SetAspectLine (aBackAspectLine);
217   if (isFaceSet)
218     theWorkspace->SetAspectFace (aBackAspectFace);
219   if (isMarkerSet)
220     theWorkspace->SetAspectMarker (aBackAspectMarker);
221   if (isTextSet)
222     theWorkspace->SetAspectText (aBackAspectText);
223 }
224
225 // =======================================================================
226 // function : Release
227 // purpose  :
228 // =======================================================================
229 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
230 {
231   // Delete elements
232   while (myFirst != NULL)
233   {
234     OpenGl_ElementNode* aNext = myFirst->next;
235     OpenGl_Element::Destroy (theGlCtx, myFirst->elem);
236     delete myFirst;
237     myFirst = aNext;
238   }
239   myLast = NULL;
240
241   OpenGl_Element::Destroy (theGlCtx, myAspectLine);
242   OpenGl_Element::Destroy (theGlCtx, myAspectFace);
243   OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
244   OpenGl_Element::Destroy (theGlCtx, myAspectText);
245 }