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