Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-08-01 |
2 | // Created by: Sergey ZERCHANINOV | |
973c2be1 | 3 | // Copyright (c) 2011-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
2166f0fa | 15 | |
e276548b | 16 | #ifdef HAVE_CONFIG_H |
17 | #include <config.h> | |
18 | #endif | |
19 | ||
20 | #include <OpenGl_Group.hxx> | |
b64d84be | 21 | |
22 | #include <OpenGl_GraphicDriver.hxx> | |
23 | #include <OpenGl_Flipper.hxx> | |
2166f0fa | 24 | #include <OpenGl_PrimitiveArray.hxx> |
b64d84be | 25 | #include <OpenGl_StencilTest.hxx> |
e276548b | 26 | #include <OpenGl_Structure.hxx> |
b64d84be | 27 | #include <OpenGl_Text.hxx> |
bf75be98 | 28 | #include <OpenGl_Workspace.hxx> |
2166f0fa | 29 | |
b64d84be | 30 | #include <Graphic3d_ArrayOfPrimitives.hxx> |
31 | #include <Graphic3d_CUserDraw.hxx> | |
32 | #include <Graphic3d_GroupDefinitionError.hxx> | |
33 | ||
34 | IMPLEMENT_STANDARD_HANDLE (OpenGl_Group, Graphic3d_Group) | |
35 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group, Graphic3d_Group) | |
36 | ||
4269bd1b | 37 | // ======================================================================= |
38 | // function : OpenGl_Group | |
39 | // purpose : | |
40 | // ======================================================================= | |
b64d84be | 41 | OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct) |
42 | : Graphic3d_Group (theStruct), | |
43 | myAspectLine(NULL), | |
e276548b | 44 | myAspectFace(NULL), |
45 | myAspectMarker(NULL), | |
46 | myAspectText(NULL), | |
47 | myFirst(NULL), | |
b64d84be | 48 | myLast(NULL), |
49 | myIsRaytracable (Standard_False), | |
50 | myModificationState (0) | |
2166f0fa | 51 | { |
b64d84be | 52 | Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure()); |
53 | if (aStruct == NULL) | |
54 | { | |
55 | Graphic3d_GroupDefinitionError::Raise ("OpenGl_Group should be created by OpenGl_Structure!"); | |
56 | } | |
2166f0fa SK |
57 | } |
58 | ||
4269bd1b | 59 | // ======================================================================= |
60 | // function : ~OpenGl_Group | |
61 | // purpose : | |
62 | // ======================================================================= | |
2166f0fa SK |
63 | OpenGl_Group::~OpenGl_Group() |
64 | { | |
5e27df78 | 65 | Release (Handle(OpenGl_Context)()); |
2166f0fa SK |
66 | } |
67 | ||
4269bd1b | 68 | // ======================================================================= |
b64d84be | 69 | // function : UpdateAspectLine |
4269bd1b | 70 | // purpose : |
71 | // ======================================================================= | |
b64d84be | 72 | void OpenGl_Group::UpdateAspectLine (const Standard_Boolean theIsGlobal) |
2166f0fa | 73 | { |
b64d84be | 74 | if (!ContextLine.IsDef) |
75 | { | |
76 | return; | |
77 | } | |
78 | ||
2166f0fa SK |
79 | if (theIsGlobal || myFirst == NULL) |
80 | { | |
81 | if (myAspectLine == NULL) | |
fd4a6963 | 82 | { |
2166f0fa | 83 | myAspectLine = new OpenGl_AspectLine(); |
fd4a6963 | 84 | } |
b64d84be | 85 | myAspectLine->SetAspect (ContextLine); |
2166f0fa SK |
86 | } |
87 | else | |
88 | { | |
89 | OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine(); | |
b64d84be | 90 | anAspectLine->SetAspect (ContextLine); |
5322131b | 91 | AddElement (anAspectLine); |
2166f0fa SK |
92 | } |
93 | } | |
94 | ||
4269bd1b | 95 | // ======================================================================= |
b64d84be | 96 | // function : UpdateAspectFace |
4269bd1b | 97 | // purpose : |
98 | // ======================================================================= | |
b64d84be | 99 | void OpenGl_Group::UpdateAspectFace (const Standard_Boolean theIsGlobal) |
2166f0fa | 100 | { |
b64d84be | 101 | if (!ContextFillArea.IsDef) |
102 | { | |
103 | return; | |
104 | } | |
105 | ||
2166f0fa SK |
106 | if (theIsGlobal || myFirst == NULL) |
107 | { | |
108 | if (myAspectFace == NULL) | |
bf75be98 | 109 | { |
2166f0fa | 110 | myAspectFace = new OpenGl_AspectFace(); |
bf75be98 | 111 | } |
b64d84be | 112 | myAspectFace->SetAspect (ContextFillArea); |
2166f0fa SK |
113 | } |
114 | else | |
115 | { | |
116 | OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace(); | |
b64d84be | 117 | anAspectFace->SetAspect (ContextFillArea); |
5322131b | 118 | AddElement (anAspectFace); |
2166f0fa | 119 | } |
e276548b | 120 | |
121 | #ifdef HAVE_OPENCL | |
122 | if (myIsRaytracable) | |
123 | { | |
b64d84be | 124 | ++myModificationState; |
125 | OpenGl_Structure* aStruct = GlStruct(); | |
126 | if (aStruct != NULL) | |
e276548b | 127 | { |
b64d84be | 128 | aStruct->UpdateStateWithAncestorStructures(); |
e276548b | 129 | } |
130 | } | |
131 | #endif | |
2166f0fa SK |
132 | } |
133 | ||
4269bd1b | 134 | // ======================================================================= |
b64d84be | 135 | // function : UpdateAspectMarker |
4269bd1b | 136 | // purpose : |
137 | // ======================================================================= | |
b64d84be | 138 | void OpenGl_Group::UpdateAspectMarker (const Standard_Boolean theIsGlobal) |
2166f0fa | 139 | { |
b64d84be | 140 | if (!ContextMarker.IsDef) |
141 | { | |
142 | return; | |
143 | } | |
144 | ||
2166f0fa SK |
145 | if (theIsGlobal || myFirst == NULL) |
146 | { | |
147 | if (myAspectMarker == NULL) | |
a577aaab | 148 | { |
2166f0fa | 149 | myAspectMarker = new OpenGl_AspectMarker(); |
a577aaab | 150 | } |
b64d84be | 151 | myAspectMarker->SetAspect (ContextMarker); |
2166f0fa SK |
152 | } |
153 | else | |
154 | { | |
155 | OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker(); | |
b64d84be | 156 | anAspectMarker->SetAspect (ContextMarker); |
5322131b | 157 | AddElement (anAspectMarker); |
2166f0fa SK |
158 | } |
159 | } | |
160 | ||
4269bd1b | 161 | // ======================================================================= |
b64d84be | 162 | // function : UpdateAspectText |
4269bd1b | 163 | // purpose : |
164 | // ======================================================================= | |
b64d84be | 165 | void OpenGl_Group::UpdateAspectText (const Standard_Boolean theIsGlobal) |
2166f0fa | 166 | { |
b64d84be | 167 | if (!ContextText.IsDef) |
168 | { | |
169 | return; | |
170 | } | |
171 | ||
2166f0fa SK |
172 | if (theIsGlobal || myFirst == NULL) |
173 | { | |
174 | if (myAspectText == NULL) | |
fd4a6963 | 175 | { |
2166f0fa | 176 | myAspectText = new OpenGl_AspectText(); |
fd4a6963 | 177 | } |
b64d84be | 178 | myAspectText->SetAspect (ContextText); |
2166f0fa SK |
179 | } |
180 | else | |
181 | { | |
182 | OpenGl_AspectText* anAspectText = new OpenGl_AspectText(); | |
b64d84be | 183 | anAspectText->SetAspect (ContextText); |
5322131b | 184 | AddElement (anAspectText); |
2166f0fa SK |
185 | } |
186 | } | |
187 | ||
b64d84be | 188 | // ======================================================================= |
189 | // function : AddPrimitiveArray | |
190 | // purpose : | |
191 | // ======================================================================= | |
192 | void OpenGl_Group::AddPrimitiveArray (const Handle(Graphic3d_ArrayOfPrimitives)& thePrim, | |
193 | const Standard_Boolean theToEvalMinMax) | |
194 | { | |
195 | if (IsDeleted() | |
196 | || !thePrim->IsValid()) | |
197 | { | |
198 | return; | |
199 | } | |
200 | ||
201 | OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray ((CALL_DEF_PARRAY *)thePrim->Array()); | |
202 | AddElement (anArray); | |
203 | ||
204 | Graphic3d_Group::AddPrimitiveArray (thePrim, theToEvalMinMax); | |
205 | } | |
206 | ||
207 | // ======================================================================= | |
208 | // function : Text | |
209 | // purpose : | |
210 | // ======================================================================= | |
211 | void OpenGl_Group::Text (const Standard_CString theTextUtf, | |
212 | const Graphic3d_Vertex& thePoint, | |
213 | const Standard_Real theHeight, | |
214 | const Quantity_PlaneAngle theAngle, | |
215 | const Graphic3d_TextPath theTp, | |
216 | const Graphic3d_HorizontalTextAlignment theHta, | |
217 | const Graphic3d_VerticalTextAlignment theVta, | |
218 | const Standard_Boolean theToEvalMinMax) | |
219 | { | |
220 | if (IsDeleted()) | |
221 | { | |
222 | return; | |
223 | } | |
224 | ||
225 | OpenGl_TextParam aParams; | |
226 | OpenGl_Structure* aStruct = GlStruct(); | |
227 | aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight); | |
228 | aParams.HAlign = theHta; | |
229 | aParams.VAlign = theVta; | |
230 | const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z()); | |
231 | OpenGl_Text* aText = new OpenGl_Text (theTextUtf, aPoint, aParams); | |
232 | AddElement (aText); | |
233 | Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle, | |
234 | theTp, theHta, theVta, theToEvalMinMax); | |
235 | } | |
236 | ||
237 | // ======================================================================= | |
238 | // function : UserDraw | |
239 | // purpose : | |
240 | // ======================================================================= | |
241 | void OpenGl_Group::UserDraw (const Standard_Address theObject, | |
242 | const Standard_Boolean theToEvalMinMax, | |
243 | const Standard_Boolean theContainsFacet) | |
244 | { | |
245 | if (IsDeleted()) | |
246 | { | |
247 | return; | |
248 | } | |
249 | ||
250 | OpenGl_Structure* aStruct = GlStruct(); | |
251 | if (aStruct->GlDriver()->UserDrawCallback() == NULL) | |
252 | { | |
253 | return; | |
254 | } | |
255 | ||
256 | Graphic3d_CUserDraw aUserDraw; | |
257 | aUserDraw.Data = theObject; | |
258 | aUserDraw.Bounds = theToEvalMinMax ? &myBounds : NULL; | |
259 | OpenGl_Element* aUserDrawElem = aStruct->GlDriver()->UserDrawCallback()(&aUserDraw); | |
260 | if (aUserDrawElem != NULL) | |
261 | { | |
262 | AddElement (aUserDrawElem); | |
263 | } | |
264 | Graphic3d_Group::UserDraw (theObject, theToEvalMinMax, theContainsFacet); | |
265 | } | |
266 | ||
267 | // ======================================================================= | |
268 | // function : SetFlippingOptions | |
269 | // purpose : | |
270 | // ======================================================================= | |
271 | void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled, | |
272 | const gp_Ax2& theRefPlane) | |
273 | { | |
274 | OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane); | |
275 | aFlipper->SetOptions (theIsEnabled); | |
276 | AddElement (aFlipper); | |
277 | } | |
278 | ||
279 | // ======================================================================= | |
280 | // function : SetStencilTestOptions | |
281 | // purpose : | |
282 | // ======================================================================= | |
283 | void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled) | |
284 | { | |
285 | OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest(); | |
286 | aStencilTest->SetOptions (theIsEnabled); | |
287 | AddElement (aStencilTest); | |
288 | } | |
289 | ||
4269bd1b | 290 | // ======================================================================= |
291 | // function : AddElement | |
292 | // purpose : | |
293 | // ======================================================================= | |
5322131b | 294 | void OpenGl_Group::AddElement (OpenGl_Element* theElem) |
2166f0fa | 295 | { |
e276548b | 296 | OpenGl_ElementNode *aNode = new OpenGl_ElementNode(); |
297 | ||
e276548b | 298 | aNode->elem = theElem; |
299 | aNode->next = NULL; | |
300 | (myLast? myLast->next : myFirst) = aNode; | |
301 | myLast = aNode; | |
302 | ||
303 | #ifdef HAVE_OPENCL | |
304 | if (OpenGl_Raytrace::IsRaytracedElement (aNode)) | |
305 | { | |
306 | myModificationState++; | |
307 | myIsRaytracable = Standard_True; | |
2166f0fa | 308 | |
b64d84be | 309 | OpenGl_Structure* aStruct = GlStruct(); |
310 | if (aStruct != NULL) | |
e276548b | 311 | { |
b64d84be | 312 | aStruct->UpdateStateWithAncestorStructures(); |
313 | aStruct->SetRaytracableWithAncestorStructures(); | |
e276548b | 314 | } |
315 | } | |
316 | #endif | |
2166f0fa SK |
317 | } |
318 | ||
4269bd1b | 319 | // ======================================================================= |
320 | // function : Render | |
321 | // purpose : | |
322 | // ======================================================================= | |
bf75be98 | 323 | void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const |
2166f0fa SK |
324 | { |
325 | // Is rendering in ADD or IMMEDIATE mode? | |
4269bd1b | 326 | const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter(); |
2166f0fa SK |
327 | |
328 | // Setup aspects | |
bf75be98 | 329 | const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine (Standard_False); |
330 | const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace (Standard_False); | |
331 | const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False); | |
332 | const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText (Standard_False); | |
4269bd1b | 333 | Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter); |
334 | Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter); | |
335 | Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter); | |
336 | Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter); | |
2166f0fa SK |
337 | |
338 | // Render group elements | |
bf75be98 | 339 | for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next) |
2166f0fa | 340 | { |
5322131b | 341 | aNodeIter->elem->RenderFiltered (theWorkspace, aFilter); |
2166f0fa SK |
342 | } |
343 | ||
344 | // Restore aspects | |
4269bd1b | 345 | if (isLineSet) |
346 | theWorkspace->SetAspectLine (aBackAspectLine); | |
347 | if (isFaceSet) | |
348 | theWorkspace->SetAspectFace (aBackAspectFace); | |
349 | if (isMarkerSet) | |
350 | theWorkspace->SetAspectMarker (aBackAspectMarker); | |
351 | if (isTextSet) | |
352 | theWorkspace->SetAspectText (aBackAspectText); | |
2166f0fa SK |
353 | } |
354 | ||
b64d84be | 355 | // ======================================================================= |
356 | // function : Clear | |
357 | // purpose : | |
358 | // ======================================================================= | |
359 | void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr) | |
360 | { | |
361 | if (IsDeleted()) | |
362 | { | |
363 | return; | |
364 | } | |
365 | ||
366 | OpenGl_Structure* aStruct = GlStruct(); | |
367 | const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext(); | |
368 | ||
369 | Release (aCtx); | |
370 | Graphic3d_Group::Clear (theToUpdateStructureMgr); | |
371 | } | |
372 | ||
4269bd1b | 373 | // ======================================================================= |
374 | // function : Release | |
375 | // purpose : | |
376 | // ======================================================================= | |
5e27df78 | 377 | void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx) |
378 | { | |
379 | // Delete elements | |
380 | while (myFirst != NULL) | |
381 | { | |
382 | OpenGl_ElementNode* aNext = myFirst->next; | |
383 | OpenGl_Element::Destroy (theGlCtx, myFirst->elem); | |
384 | delete myFirst; | |
385 | myFirst = aNext; | |
386 | } | |
387 | myLast = NULL; | |
388 | ||
389 | OpenGl_Element::Destroy (theGlCtx, myAspectLine); | |
390 | OpenGl_Element::Destroy (theGlCtx, myAspectFace); | |
391 | OpenGl_Element::Destroy (theGlCtx, myAspectMarker); | |
392 | OpenGl_Element::Destroy (theGlCtx, myAspectText); | |
393 | } |