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 | #include <OpenGl_Group.hxx> |
b64d84be | 17 | |
18 | #include <OpenGl_GraphicDriver.hxx> | |
19 | #include <OpenGl_Flipper.hxx> | |
2166f0fa | 20 | #include <OpenGl_PrimitiveArray.hxx> |
c357e426 | 21 | #include <OpenGl_SceneGeometry.hxx> |
b64d84be | 22 | #include <OpenGl_StencilTest.hxx> |
e276548b | 23 | #include <OpenGl_Structure.hxx> |
b64d84be | 24 | #include <OpenGl_Text.hxx> |
bf75be98 | 25 | #include <OpenGl_Workspace.hxx> |
2166f0fa | 26 | |
b64d84be | 27 | #include <Graphic3d_ArrayOfPrimitives.hxx> |
b64d84be | 28 | #include <Graphic3d_GroupDefinitionError.hxx> |
29 | ||
b64d84be | 30 | |
92efcf78 | 31 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group,Graphic3d_Group) |
32 | ||
4269bd1b | 33 | // ======================================================================= |
34 | // function : OpenGl_Group | |
35 | // purpose : | |
36 | // ======================================================================= | |
b64d84be | 37 | OpenGl_Group::OpenGl_Group (const Handle(Graphic3d_Structure)& theStruct) |
38 | : Graphic3d_Group (theStruct), | |
39 | myAspectLine(NULL), | |
e276548b | 40 | myAspectFace(NULL), |
41 | myAspectMarker(NULL), | |
42 | myAspectText(NULL), | |
43 | myFirst(NULL), | |
b64d84be | 44 | myLast(NULL), |
d4aaad5b | 45 | myIsRaytracable (Standard_False) |
2166f0fa | 46 | { |
b64d84be | 47 | Handle(OpenGl_Structure) aStruct = Handle(OpenGl_Structure)::DownCast (myStructure->CStructure()); |
c04c30b3 | 48 | if (aStruct.IsNull()) |
b64d84be | 49 | { |
50 | Graphic3d_GroupDefinitionError::Raise ("OpenGl_Group should be created by OpenGl_Structure!"); | |
51 | } | |
2166f0fa SK |
52 | } |
53 | ||
4269bd1b | 54 | // ======================================================================= |
55 | // function : ~OpenGl_Group | |
56 | // purpose : | |
57 | // ======================================================================= | |
2166f0fa SK |
58 | OpenGl_Group::~OpenGl_Group() |
59 | { | |
5e27df78 | 60 | Release (Handle(OpenGl_Context)()); |
2166f0fa SK |
61 | } |
62 | ||
4269bd1b | 63 | // ======================================================================= |
b6472664 | 64 | // function : SetGroupPrimitivesAspect |
4269bd1b | 65 | // purpose : |
66 | // ======================================================================= | |
b6472664 | 67 | void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)& theAspect) |
2166f0fa | 68 | { |
b6472664 | 69 | if (IsDeleted()) |
b64d84be | 70 | { |
71 | return; | |
72 | } | |
73 | ||
b6472664 | 74 | if (myAspectLine == NULL) |
2166f0fa | 75 | { |
b6472664 | 76 | myAspectLine = new OpenGl_AspectLine (theAspect); |
2166f0fa SK |
77 | } |
78 | else | |
79 | { | |
b6472664 | 80 | myAspectLine->SetAspect (theAspect); |
2166f0fa | 81 | } |
b6472664 | 82 | Update(); |
2166f0fa SK |
83 | } |
84 | ||
4269bd1b | 85 | // ======================================================================= |
b6472664 | 86 | // function : SetPrimitivesAspect |
4269bd1b | 87 | // purpose : |
88 | // ======================================================================= | |
b6472664 | 89 | void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)& theAspect) |
2166f0fa | 90 | { |
b6472664 | 91 | if (myAspectLine == NULL) |
b64d84be | 92 | { |
b6472664 | 93 | SetGroupPrimitivesAspect (theAspect); |
b64d84be | 94 | return; |
95 | } | |
b6472664 | 96 | else if (IsDeleted()) |
97 | { | |
98 | return; | |
99 | } | |
100 | ||
101 | OpenGl_AspectLine* anAspectLine = new OpenGl_AspectLine (theAspect); | |
102 | AddElement (anAspectLine); | |
103 | Update(); | |
104 | } | |
b64d84be | 105 | |
b6472664 | 106 | // ======================================================================= |
107 | // function : SetGroupPrimitivesAspect | |
108 | // purpose : | |
109 | // ======================================================================= | |
110 | void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect) | |
111 | { | |
112 | if (IsDeleted()) | |
2166f0fa | 113 | { |
b6472664 | 114 | return; |
115 | } | |
116 | ||
117 | if (myAspectFace == NULL) | |
118 | { | |
119 | myAspectFace = new OpenGl_AspectFace (theAspect); | |
2166f0fa SK |
120 | } |
121 | else | |
122 | { | |
b6472664 | 123 | myAspectFace->SetAspect (theAspect); |
2166f0fa | 124 | } |
e276548b | 125 | |
e276548b | 126 | if (myIsRaytracable) |
127 | { | |
b64d84be | 128 | OpenGl_Structure* aStruct = GlStruct(); |
129 | if (aStruct != NULL) | |
e276548b | 130 | { |
d4aaad5b | 131 | aStruct->UpdateStateIfRaytracable (Standard_False); |
e276548b | 132 | } |
133 | } | |
b6472664 | 134 | |
135 | Update(); | |
2166f0fa SK |
136 | } |
137 | ||
4269bd1b | 138 | // ======================================================================= |
b6472664 | 139 | // function : SetPrimitivesAspect |
4269bd1b | 140 | // purpose : |
141 | // ======================================================================= | |
b6472664 | 142 | void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectFillArea3d)& theAspect) |
2166f0fa | 143 | { |
b6472664 | 144 | if (myAspectFace == NULL) |
145 | { | |
146 | SetGroupPrimitivesAspect (theAspect); | |
147 | return; | |
148 | } | |
149 | else if (IsDeleted()) | |
b64d84be | 150 | { |
151 | return; | |
152 | } | |
153 | ||
b6472664 | 154 | OpenGl_AspectFace* anAspectFace = new OpenGl_AspectFace (theAspect); |
155 | AddElement (anAspectFace); | |
156 | Update(); | |
157 | } | |
158 | ||
159 | // ======================================================================= | |
160 | // function : SetGroupPrimitivesAspect | |
161 | // purpose : | |
162 | // ======================================================================= | |
163 | void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d)& theAspMarker) | |
164 | { | |
165 | if (IsDeleted()) | |
2166f0fa | 166 | { |
b6472664 | 167 | return; |
168 | } | |
169 | ||
170 | if (myAspectMarker == NULL) | |
171 | { | |
172 | myAspectMarker = new OpenGl_AspectMarker (theAspMarker); | |
2166f0fa SK |
173 | } |
174 | else | |
175 | { | |
b6472664 | 176 | myAspectMarker->SetAspect (theAspMarker); |
2166f0fa | 177 | } |
b6472664 | 178 | Update(); |
2166f0fa SK |
179 | } |
180 | ||
4269bd1b | 181 | // ======================================================================= |
b6472664 | 182 | // function : SetPrimitivesAspect |
4269bd1b | 183 | // purpose : |
184 | // ======================================================================= | |
b6472664 | 185 | void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectMarker3d)& theAspMarker) |
2166f0fa | 186 | { |
b6472664 | 187 | if (myAspectMarker == NULL) |
188 | { | |
189 | SetGroupPrimitivesAspect (theAspMarker); | |
190 | return; | |
191 | } | |
192 | else if (IsDeleted()) | |
b64d84be | 193 | { |
194 | return; | |
195 | } | |
196 | ||
b6472664 | 197 | OpenGl_AspectMarker* anAspectMarker = new OpenGl_AspectMarker (theAspMarker); |
198 | AddElement (anAspectMarker); | |
199 | Update(); | |
200 | } | |
201 | ||
202 | // ======================================================================= | |
203 | // function : SetGroupPrimitivesAspect | |
204 | // purpose : | |
205 | // ======================================================================= | |
206 | void OpenGl_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectText3d)& theAspText) | |
207 | { | |
208 | if (IsDeleted()) | |
2166f0fa | 209 | { |
b6472664 | 210 | return; |
211 | } | |
212 | ||
213 | if (myAspectText == NULL) | |
214 | { | |
215 | myAspectText = new OpenGl_AspectText (theAspText); | |
2166f0fa SK |
216 | } |
217 | else | |
218 | { | |
b6472664 | 219 | myAspectText->SetAspect (theAspText); |
220 | } | |
221 | Update(); | |
222 | } | |
223 | ||
224 | // ======================================================================= | |
225 | // function : SetPrimitivesAspect | |
226 | // purpose : | |
227 | // ======================================================================= | |
228 | void OpenGl_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectText3d)& theAspText) | |
229 | { | |
230 | if (myAspectText == NULL) | |
231 | { | |
232 | SetGroupPrimitivesAspect (theAspText); | |
233 | return; | |
234 | } | |
235 | else if (IsDeleted()) | |
236 | { | |
237 | return; | |
2166f0fa | 238 | } |
b6472664 | 239 | |
240 | OpenGl_AspectText* anAspectText = new OpenGl_AspectText (theAspText); | |
241 | AddElement (anAspectText); | |
242 | Update(); | |
2166f0fa SK |
243 | } |
244 | ||
b64d84be | 245 | // ======================================================================= |
246 | // function : AddPrimitiveArray | |
247 | // purpose : | |
248 | // ======================================================================= | |
871fa103 | 249 | void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType, |
250 | const Handle(Graphic3d_IndexBuffer)& theIndices, | |
251 | const Handle(Graphic3d_Buffer)& theAttribs, | |
252 | const Handle(Graphic3d_BoundBuffer)& theBounds, | |
253 | const Standard_Boolean theToEvalMinMax) | |
b64d84be | 254 | { |
255 | if (IsDeleted() | |
871fa103 | 256 | || theAttribs.IsNull()) |
b64d84be | 257 | { |
258 | return; | |
259 | } | |
260 | ||
8d3f219f | 261 | OpenGl_Structure* aStruct = GlStruct(); |
262 | const OpenGl_GraphicDriver* aDriver = aStruct->GlDriver(); | |
263 | ||
264 | OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (aDriver, theType, theIndices, theAttribs, theBounds); | |
b64d84be | 265 | AddElement (anArray); |
266 | ||
871fa103 | 267 | Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax); |
b64d84be | 268 | } |
269 | ||
270 | // ======================================================================= | |
271 | // function : Text | |
272 | // purpose : | |
273 | // ======================================================================= | |
274 | void OpenGl_Group::Text (const Standard_CString theTextUtf, | |
275 | const Graphic3d_Vertex& thePoint, | |
276 | const Standard_Real theHeight, | |
277 | const Quantity_PlaneAngle theAngle, | |
278 | const Graphic3d_TextPath theTp, | |
279 | const Graphic3d_HorizontalTextAlignment theHta, | |
280 | const Graphic3d_VerticalTextAlignment theVta, | |
281 | const Standard_Boolean theToEvalMinMax) | |
282 | { | |
283 | if (IsDeleted()) | |
284 | { | |
285 | return; | |
286 | } | |
287 | ||
288 | OpenGl_TextParam aParams; | |
289 | OpenGl_Structure* aStruct = GlStruct(); | |
290 | aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight); | |
291 | aParams.HAlign = theHta; | |
292 | aParams.VAlign = theVta; | |
293 | const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z()); | |
294 | OpenGl_Text* aText = new OpenGl_Text (theTextUtf, aPoint, aParams); | |
295 | AddElement (aText); | |
296 | Graphic3d_Group::Text (theTextUtf, thePoint, theHeight, theAngle, | |
297 | theTp, theHta, theVta, theToEvalMinMax); | |
298 | } | |
299 | ||
ce01ec26 | 300 | // ======================================================================= |
301 | // function : Text | |
302 | // purpose : | |
303 | // ======================================================================= | |
304 | void OpenGl_Group::Text (const Standard_CString theTextUtf, | |
305 | const gp_Ax2& theOrientation, | |
306 | const Standard_Real theHeight, | |
307 | const Quantity_PlaneAngle theAngle, | |
308 | const Graphic3d_TextPath theTp, | |
309 | const Graphic3d_HorizontalTextAlignment theHTA, | |
310 | const Graphic3d_VerticalTextAlignment theVTA, | |
3f1eb0ab | 311 | const Standard_Boolean theToEvalMinMax, |
312 | const Standard_Boolean theHasOwnAnchor) | |
ce01ec26 | 313 | { |
314 | if (IsDeleted()) | |
315 | { | |
316 | return; | |
317 | } | |
318 | ||
319 | OpenGl_TextParam aParams; | |
320 | OpenGl_Structure* aStruct = GlStruct(); | |
321 | ||
322 | aParams.Height = int ((theHeight < 2.0) ? aStruct->GlDriver()->DefaultTextHeight() : theHeight); | |
323 | aParams.HAlign = theHTA; | |
324 | aParams.VAlign = theVTA; | |
325 | ||
3f1eb0ab | 326 | OpenGl_Text* aText = new OpenGl_Text (theTextUtf, theOrientation, aParams, theHasOwnAnchor != Standard_False); |
ce01ec26 | 327 | |
328 | AddElement (aText); | |
329 | ||
330 | Graphic3d_Group::Text (theTextUtf, | |
331 | theOrientation, | |
332 | theHeight, | |
333 | theAngle, | |
334 | theTp, | |
335 | theHTA, | |
336 | theVTA, | |
3f1eb0ab | 337 | theToEvalMinMax, |
338 | theHasOwnAnchor); | |
ce01ec26 | 339 | |
340 | } | |
341 | ||
b64d84be | 342 | // ======================================================================= |
343 | // function : SetFlippingOptions | |
344 | // purpose : | |
345 | // ======================================================================= | |
346 | void OpenGl_Group::SetFlippingOptions (const Standard_Boolean theIsEnabled, | |
347 | const gp_Ax2& theRefPlane) | |
348 | { | |
349 | OpenGl_Flipper* aFlipper = new OpenGl_Flipper (theRefPlane); | |
350 | aFlipper->SetOptions (theIsEnabled); | |
351 | AddElement (aFlipper); | |
352 | } | |
353 | ||
354 | // ======================================================================= | |
355 | // function : SetStencilTestOptions | |
356 | // purpose : | |
357 | // ======================================================================= | |
358 | void OpenGl_Group::SetStencilTestOptions (const Standard_Boolean theIsEnabled) | |
359 | { | |
360 | OpenGl_StencilTest* aStencilTest = new OpenGl_StencilTest(); | |
361 | aStencilTest->SetOptions (theIsEnabled); | |
362 | AddElement (aStencilTest); | |
363 | } | |
364 | ||
4269bd1b | 365 | // ======================================================================= |
366 | // function : AddElement | |
367 | // purpose : | |
368 | // ======================================================================= | |
5322131b | 369 | void OpenGl_Group::AddElement (OpenGl_Element* theElem) |
2166f0fa | 370 | { |
e276548b | 371 | OpenGl_ElementNode *aNode = new OpenGl_ElementNode(); |
372 | ||
e276548b | 373 | aNode->elem = theElem; |
374 | aNode->next = NULL; | |
375 | (myLast? myLast->next : myFirst) = aNode; | |
376 | myLast = aNode; | |
377 | ||
e276548b | 378 | if (OpenGl_Raytrace::IsRaytracedElement (aNode)) |
379 | { | |
e276548b | 380 | myIsRaytracable = Standard_True; |
2166f0fa | 381 | |
b64d84be | 382 | OpenGl_Structure* aStruct = GlStruct(); |
383 | if (aStruct != NULL) | |
e276548b | 384 | { |
d4aaad5b | 385 | aStruct->UpdateStateIfRaytracable (Standard_False); |
e276548b | 386 | } |
387 | } | |
2166f0fa SK |
388 | } |
389 | ||
4269bd1b | 390 | // ======================================================================= |
391 | // function : Render | |
392 | // purpose : | |
393 | // ======================================================================= | |
bf75be98 | 394 | void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const |
2166f0fa | 395 | { |
4269bd1b | 396 | const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter(); |
2166f0fa SK |
397 | |
398 | // Setup aspects | |
b6472664 | 399 | theWorkspace->SetAllowFaceCulling (myIsClosed); |
f9ba5c4d | 400 | const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine(); |
401 | const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace(); | |
402 | const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker(); | |
403 | const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText(); | |
4269bd1b | 404 | Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter); |
405 | Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter); | |
406 | Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter); | |
407 | Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter); | |
2166f0fa SK |
408 | |
409 | // Render group elements | |
bf75be98 | 410 | for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next) |
2166f0fa | 411 | { |
5322131b | 412 | aNodeIter->elem->RenderFiltered (theWorkspace, aFilter); |
2166f0fa SK |
413 | } |
414 | ||
415 | // Restore aspects | |
4269bd1b | 416 | if (isLineSet) |
417 | theWorkspace->SetAspectLine (aBackAspectLine); | |
418 | if (isFaceSet) | |
419 | theWorkspace->SetAspectFace (aBackAspectFace); | |
420 | if (isMarkerSet) | |
421 | theWorkspace->SetAspectMarker (aBackAspectMarker); | |
422 | if (isTextSet) | |
423 | theWorkspace->SetAspectText (aBackAspectText); | |
2166f0fa SK |
424 | } |
425 | ||
b64d84be | 426 | // ======================================================================= |
427 | // function : Clear | |
428 | // purpose : | |
429 | // ======================================================================= | |
430 | void OpenGl_Group::Clear (const Standard_Boolean theToUpdateStructureMgr) | |
431 | { | |
432 | if (IsDeleted()) | |
433 | { | |
434 | return; | |
435 | } | |
436 | ||
437 | OpenGl_Structure* aStruct = GlStruct(); | |
438 | const Handle(OpenGl_Context)& aCtx = aStruct->GlDriver()->GetSharedContext(); | |
439 | ||
440 | Release (aCtx); | |
441 | Graphic3d_Group::Clear (theToUpdateStructureMgr); | |
d4aaad5b | 442 | |
443 | myIsRaytracable = Standard_False; | |
b64d84be | 444 | } |
445 | ||
4269bd1b | 446 | // ======================================================================= |
447 | // function : Release | |
448 | // purpose : | |
449 | // ======================================================================= | |
5e27df78 | 450 | void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx) |
451 | { | |
452 | // Delete elements | |
453 | while (myFirst != NULL) | |
454 | { | |
455 | OpenGl_ElementNode* aNext = myFirst->next; | |
10b9c7df | 456 | OpenGl_Element::Destroy (theGlCtx.operator->(), myFirst->elem); |
5e27df78 | 457 | delete myFirst; |
458 | myFirst = aNext; | |
459 | } | |
460 | myLast = NULL; | |
461 | ||
10b9c7df | 462 | OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectLine); |
463 | OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectFace); | |
464 | OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectMarker); | |
465 | OpenGl_Element::Destroy (theGlCtx.operator->(), myAspectText); | |
5e27df78 | 466 | } |