0027961: Visualization - remove unused and no more working OpenGl_AVIWriter
[occt.git] / src / OpenGl / OpenGl_SceneGeometry.cxx
CommitLineData
e276548b 1// Created on: 2013-08-27
2// Created by: Denis BOGOLEPOV
3// Copyright (c) 2013 OPEN CASCADE SAS
4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
e276548b 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.
e276548b 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
e276548b 15
65578e1c 16#include <OSD_Timer.hxx>
c7b59798 17#include <OSD_Parallel.hxx>
65578e1c 18#include <Standard_Assert.hxx>
25ef750e 19#include <OpenGl_ArbTexBindless.hxx>
b7cd4ba7 20#include <OpenGl_PrimitiveArray.hxx>
65578e1c 21#include <OpenGl_SceneGeometry.hxx>
b7cd4ba7 22#include <OpenGl_Structure.hxx>
c04c30b3 23#include <Graphic3d_GraphicDriver.hxx>
b7cd4ba7 24
265d4508 25//! Use this macro to output BVH profiling info
25ef750e 26// #define RAY_TRACE_PRINT_INFO
e276548b 27
265d4508 28namespace
29{
e276548b 30 //! Useful constant for null floating-point 4D vector.
265d4508 31 static const BVH_Vec4f ZERO_VEC_4F;
25ef750e 32}
e276548b 33
34// =======================================================================
64c759f8 35// function : OpenGl_RaytraceMaterial
e276548b 36// purpose : Creates new default material
37// =======================================================================
38OpenGl_RaytraceMaterial::OpenGl_RaytraceMaterial()
265d4508 39: Ambient (ZERO_VEC_4F),
40 Diffuse (ZERO_VEC_4F),
41 Specular (ZERO_VEC_4F),
42 Emission (ZERO_VEC_4F),
43 Reflection (ZERO_VEC_4F),
44 Refraction (ZERO_VEC_4F),
45 Transparency (ZERO_VEC_4F)
e276548b 46{ }
47
48// =======================================================================
64c759f8 49// function : OpenGl_RaytraceMaterial
e276548b 50// purpose : Creates new material with specified properties
51// =======================================================================
265d4508 52OpenGl_RaytraceMaterial::OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient,
53 const BVH_Vec4f& theDiffuse,
54 const BVH_Vec4f& theSpecular)
e276548b 55: Ambient (theAmbient),
56 Diffuse (theDiffuse),
57 Specular (theSpecular),
265d4508 58 Emission (ZERO_VEC_4F),
59 Reflection (ZERO_VEC_4F),
60 Refraction (ZERO_VEC_4F),
61 Transparency (ZERO_VEC_4F)
e276548b 62{
63 //
64}
65
66// =======================================================================
64c759f8 67// function : OpenGl_RaytraceMaterial
e276548b 68// purpose : Creates new material with specified properties
69// =======================================================================
265d4508 70OpenGl_RaytraceMaterial::OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient,
71 const BVH_Vec4f& theDiffuse,
72 const BVH_Vec4f& theSpecular,
73 const BVH_Vec4f& theEmission,
74 const BVH_Vec4f& theTranspar)
e276548b 75: Ambient (theAmbient),
76 Diffuse (theDiffuse),
77 Specular (theSpecular),
78 Emission (theEmission),
265d4508 79 Reflection (ZERO_VEC_4F),
80 Refraction (ZERO_VEC_4F),
e276548b 81 Transparency (theTranspar)
82{
83 //
84}
85
86// =======================================================================
64c759f8 87// function : OpenGl_RaytraceMaterial
e276548b 88// purpose : Creates new material with specified properties
89// =======================================================================
265d4508 90OpenGl_RaytraceMaterial::OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient,
91 const BVH_Vec4f& theDiffuse,
92 const BVH_Vec4f& theSpecular,
93 const BVH_Vec4f& theEmission,
94 const BVH_Vec4f& theTranspar,
95 const BVH_Vec4f& theReflection,
96 const BVH_Vec4f& theRefraction)
e276548b 97: Ambient (theAmbient),
98 Diffuse (theDiffuse),
99 Specular (theSpecular),
100 Emission (theEmission),
101 Reflection (theReflection),
102 Refraction (theRefraction),
103 Transparency (theTranspar)
104{
105 //
106}
107
108// =======================================================================
109// function : OpenGl_LightSource
110// purpose : Creates new light source
111// =======================================================================
265d4508 112OpenGl_RaytraceLight::OpenGl_RaytraceLight (const BVH_Vec4f& theDiffuse,
113 const BVH_Vec4f& thePosition)
e276548b 114: Diffuse (theDiffuse),
115 Position (thePosition)
116{
117 //
118}
119
f2474958 120// =======================================================================
121// function : QuadBVH
122// purpose : Returns quad BVH (QBVH) tree produced from binary BVH
123// =======================================================================
124const QuadBvhHandle& OpenGl_TriangleSet::QuadBVH()
125{
126 if (!myIsDirty)
127 {
128 Standard_ASSERT_RAISE (!myQuadBVH.IsNull(), "Error! BVH was not collapsed into QBVH");
129 }
130 else
131 {
132 myQuadBVH = BVH()->CollapseToQuadTree(); // build binary BVH and collapse it
133
134 myBVH->Clear(); // erase binary BVH
135 }
136
137 return myQuadBVH;
138}
139
50d0e1ce 140// =======================================================================
141// function : Center
142// purpose : Returns centroid position along the given axis
143// =======================================================================
144Standard_ShortReal OpenGl_TriangleSet::Center (
145 const Standard_Integer theIndex, const Standard_Integer theAxis) const
146{
147 // Note: Experiments show that the use of the box centroid (instead
148 // of the triangle centroid) increases render performance up to 12%
149
150 const BVH_Vec4i& aTriangle = Elements[theIndex];
151
152 const Standard_ShortReal aVertex0 =
153 BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.x()], theAxis);
154 const Standard_ShortReal aVertex1 =
155 BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.y()], theAxis);
156 const Standard_ShortReal aVertex2 =
157 BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.z()], theAxis);
158
159 return (Min (Min (aVertex0, aVertex1), aVertex2) +
160 Max (Max (aVertex0, aVertex1), aVertex2)) * 0.5f;
161}
162
25ef750e 163// =======================================================================
164// function : Box
165// purpose : Returns AABB of primitive set
166// =======================================================================
167OpenGl_TriangleSet::BVH_BoxNt OpenGl_TriangleSet::Box() const
168{
169 const BVH_Transform<Standard_ShortReal, 4>* aTransform =
170 dynamic_cast<const BVH_Transform<Standard_ShortReal, 4>* > (Properties().operator->());
171
172 BVH_BoxNt aBox = BVH_PrimitiveSet<Standard_ShortReal, 3>::Box();
173
174 if (aTransform != NULL)
175 {
176 BVH_BoxNt aTransformedBox;
177
178 for (Standard_Integer aX = 0; aX <= 1; ++aX)
179 {
180 for (Standard_Integer aY = 0; aY <= 1; ++aY)
181 {
182 for (Standard_Integer aZ = 0; aZ <= 1; ++aZ)
183 {
184 BVH_Vec4f aCorner = aTransform->Transform() * BVH_Vec4f (
185 aX == 0 ? aBox.CornerMin().x() : aBox.CornerMax().x(),
186 aY == 0 ? aBox.CornerMin().y() : aBox.CornerMax().y(),
187 aZ == 0 ? aBox.CornerMin().z() : aBox.CornerMax().z(),
188 1.f);
189
fe30607a 190 aTransformedBox.Add (aCorner.xyz());
25ef750e 191 }
192 }
193 }
194
195 return aTransformedBox;
196 }
197
198 return aBox;
199}
200
65578e1c 201// =======================================================================
202// function : OpenGl_TriangleSet
203// purpose : Creates new OpenGL element triangulation
204// =======================================================================
205OpenGl_TriangleSet::OpenGl_TriangleSet (const Standard_Size theArrayID)
206: BVH_Triangulation<Standard_ShortReal, 3>(),
207 myArrayID (theArrayID)
208{
209 myBuilder = new BVH_BinnedBuilder<Standard_ShortReal, 3 /* dim */, 48 /* bins */>
210 (5 /* leaf size */, 32 /* max height */, Standard_False, OSD_Parallel::NbLogicalProcessors() + 1 /* threads */);
211}
212
e276548b 213// =======================================================================
214// function : Clear
265d4508 215// purpose : Clears ray-tracing geometry
e276548b 216// =======================================================================
265d4508 217void OpenGl_RaytraceGeometry::Clear()
e276548b 218{
25ef750e 219 BVH_Geometry<Standard_ShortReal, 3>::BVH_Geometry::Clear();
e276548b 220
265d4508 221 std::vector<OpenGl_RaytraceLight,
222 NCollection_StdAllocator<OpenGl_RaytraceLight> > anEmptySources;
e276548b 223
265d4508 224 Sources.swap (anEmptySources);
e276548b 225
226 std::vector<OpenGl_RaytraceMaterial,
265d4508 227 NCollection_StdAllocator<OpenGl_RaytraceMaterial> > anEmptyMaterials;
e276548b 228
229 Materials.swap (anEmptyMaterials);
230}
231
265d4508 232struct OpenGL_BVHParallelBuilder
e276548b 233{
25ef750e 234 BVH_ObjectSet<Standard_ShortReal, 3>* Set;
e276548b 235
25ef750e 236 OpenGL_BVHParallelBuilder (BVH_ObjectSet<Standard_ShortReal, 3>* theSet)
65578e1c 237 : Set (theSet)
e276548b 238 {
265d4508 239 //
e276548b 240 }
e276548b 241
c7b59798 242 void operator() (const Standard_Integer theObjectIdx) const
265d4508 243 {
c7b59798 244 OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (
245 Set->Objects().ChangeValue (static_cast<Standard_Integer> (theObjectIdx)).operator->());
5322131b 246
c7b59798 247 if (aTriangleSet != NULL)
f2474958 248 aTriangleSet->QuadBVH();
265d4508 249 }
250};
e276548b 251
e276548b 252// =======================================================================
265d4508 253// function : ProcessAcceleration
254// purpose : Performs post-processing of high-level BVH
e276548b 255// =======================================================================
265d4508 256Standard_Boolean OpenGl_RaytraceGeometry::ProcessAcceleration()
e276548b 257{
25ef750e 258#ifdef RAY_TRACE_PRINT_INFO
47e9c178 259 OSD_Timer aTimer;
e276548b 260#endif
5322131b 261
265d4508 262 MarkDirty(); // force BVH rebuilding
e276548b 263
25ef750e 264#ifdef RAY_TRACE_PRINT_INFO
265d4508 265 aTimer.Reset();
266 aTimer.Start();
e276548b 267#endif
268
f2474958 269 OSD_Parallel::For (0, Size(), OpenGL_BVHParallelBuilder (this));
5322131b 270
f2474958 271 myBotLevelTreeDepth = 1;
fc73a202 272
265d4508 273 for (Standard_Integer anObjectIdx = 0; anObjectIdx < Size(); ++anObjectIdx)
e276548b 274 {
265d4508 275 OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (
276 myObjects.ChangeValue (anObjectIdx).operator->());
277
278 Standard_ASSERT_RETURN (aTriangleSet != NULL,
279 "Error! Failed to get triangulation of OpenGL element", Standard_False);
5322131b 280
f2474958 281 Standard_ASSERT_RETURN (!aTriangleSet->QuadBVH().IsNull(),
265d4508 282 "Error! Failed to update bottom-level BVH of OpenGL element", Standard_False);
fc73a202 283
f2474958 284 QuadBvhHandle aBVH = aTriangleSet->QuadBVH();
47e9c178 285
286 // correct data array of bottom-level BVH to set special flag for outer
287 // nodes in order to distinguish them from outer nodes of top-level BVH
288 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aBVH->Length(); ++aNodeIdx)
289 {
290 if (aBVH->IsOuter (aNodeIdx))
291 {
292 aBVH->NodeInfoBuffer()[aNodeIdx].x() = -1;
293 }
294 }
295
f2474958 296 myBotLevelTreeDepth = Max (myBotLevelTreeDepth, aTriangleSet->QuadBVH()->Depth());
e276548b 297 }
298
25ef750e 299#ifdef RAY_TRACE_PRINT_INFO
265d4508 300 aTimer.Stop();
e276548b 301
265d4508 302 std::cout << "Updating bottom-level BVHs (sec): " <<
303 aTimer.ElapsedTime() << std::endl;
304#endif
e276548b 305
25ef750e 306#ifdef RAY_TRACE_PRINT_INFO
265d4508 307 aTimer.Reset();
308 aTimer.Start();
309#endif
e276548b 310
f2474958 311 QuadBvhHandle aBVH = QuadBVH();
312
313 Standard_ASSERT_RETURN (!aBVH.IsNull(),
314 "Error! Failed to update high-level BVH of ray-tracing scene", Standard_False);
315
316 myTopLevelTreeDepth = aBVH->Depth();
e276548b 317
25ef750e 318#ifdef RAY_TRACE_PRINT_INFO
265d4508 319 aTimer.Stop();
e276548b 320
265d4508 321 std::cout << "Updating high-level BVH (sec): " <<
322 aTimer.ElapsedTime() << std::endl;
e276548b 323#endif
324
265d4508 325 Standard_Integer aVerticesOffset = 0;
326 Standard_Integer aElementsOffset = 0;
f2474958 327 Standard_Integer aBvhNodesOffset = QuadBVH()->Length();
e276548b 328
265d4508 329 for (Standard_Integer aNodeIdx = 0; aNodeIdx < aBVH->Length(); ++aNodeIdx)
e276548b 330 {
f2474958 331 if (aBVH->IsOuter (aNodeIdx))
332 {
333 Standard_ASSERT_RETURN (aBVH->BegPrimitive (aNodeIdx) == aBVH->EndPrimitive (aNodeIdx),
334 "Error! Invalid leaf node in high-level BVH (contains several objects)", Standard_False);
e276548b 335
f2474958 336 const Standard_Integer anObjectIdx = aBVH->BegPrimitive (aNodeIdx);
e276548b 337
f2474958 338 Standard_ASSERT_RETURN (anObjectIdx < myObjects.Size(),
339 "Error! Invalid leaf node in high-level BVH (contains out-of-range object)", Standard_False);
e276548b 340
f2474958 341 OpenGl_TriangleSet* aTriangleSet = dynamic_cast<OpenGl_TriangleSet*> (myObjects (anObjectIdx).get());
e276548b 342
f2474958 343 // Note: We overwrite node info record to store parameters
344 // of bottom-level BVH and triangulation of OpenGL element
e276548b 345
f2474958 346 aBVH->NodeInfoBuffer()[aNodeIdx] = BVH_Vec4i (anObjectIdx + 1, // to keep leaf flag
347 aBvhNodesOffset,
348 aVerticesOffset,
349 aElementsOffset);
e276548b 350
f2474958 351 aVerticesOffset += static_cast<Standard_Integer> (aTriangleSet->Vertices.size());
352 aElementsOffset += static_cast<Standard_Integer> (aTriangleSet->Elements.size());
e276548b 353
f2474958 354 aBvhNodesOffset += aTriangleSet->QuadBVH()->Length();
355 }
e276548b 356 }
e276548b 357
265d4508 358 return Standard_True;
359}
e276548b 360
f2474958 361// =======================================================================
362// function : QuadBVH
363// purpose : Returns quad BVH (QBVH) tree produced from binary BVH
364// =======================================================================
365const QuadBvhHandle& OpenGl_RaytraceGeometry::QuadBVH()
366{
367 if (!myIsDirty)
368 {
369 Standard_ASSERT_RAISE (!myQuadBVH.IsNull(), "Error! BVH was not collapsed into QBVH");
370 }
371 else
372 {
373 myQuadBVH = BVH()->CollapseToQuadTree(); // build binary BVH and collapse it
374
375 myBVH->Clear(); // erase binary BVH
376 }
377
378 return myQuadBVH;
379}
380
265d4508 381// =======================================================================
382// function : AccelerationOffset
383// purpose : Returns offset of bottom-level BVH for given leaf node
384// =======================================================================
385Standard_Integer OpenGl_RaytraceGeometry::AccelerationOffset (Standard_Integer theNodeIdx)
386{
f2474958 387 const QuadBvhHandle& aBVH = QuadBVH();
e276548b 388
265d4508 389 if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
390 return INVALID_OFFSET;
e276548b 391
265d4508 392 return aBVH->NodeInfoBuffer().at (theNodeIdx).y();
e276548b 393}
394
395// =======================================================================
265d4508 396// function : VerticesOffset
397// purpose : Returns offset of triangulation vertices for given leaf node
e276548b 398// =======================================================================
265d4508 399Standard_Integer OpenGl_RaytraceGeometry::VerticesOffset (Standard_Integer theNodeIdx)
e276548b 400{
f2474958 401 const QuadBvhHandle& aBVH = QuadBVH();
e276548b 402
265d4508 403 if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
404 return INVALID_OFFSET;
e276548b 405
265d4508 406 return aBVH->NodeInfoBuffer().at (theNodeIdx).z();
407}
e276548b 408
265d4508 409// =======================================================================
410// function : ElementsOffset
411// purpose : Returns offset of triangulation elements for given leaf node
412// =======================================================================
413Standard_Integer OpenGl_RaytraceGeometry::ElementsOffset (Standard_Integer theNodeIdx)
414{
f2474958 415 const QuadBvhHandle& aBVH = QuadBVH();
e276548b 416
265d4508 417 if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
418 return INVALID_OFFSET;
e276548b 419
265d4508 420 return aBVH->NodeInfoBuffer().at (theNodeIdx).w();
e276548b 421}
422
423// =======================================================================
265d4508 424// function : TriangleSet
425// purpose : Returns triangulation data for given leaf node
e276548b 426// =======================================================================
265d4508 427OpenGl_TriangleSet* OpenGl_RaytraceGeometry::TriangleSet (Standard_Integer theNodeIdx)
e276548b 428{
f2474958 429 const QuadBvhHandle& aBVH = QuadBVH();
e276548b 430
265d4508 431 if (theNodeIdx >= aBVH->Length() || !aBVH->IsOuter (theNodeIdx))
432 return NULL;
e276548b 433
265d4508 434 if (aBVH->NodeInfoBuffer().at (theNodeIdx).x() > myObjects.Size())
435 return NULL;
5322131b 436
f2474958 437 return dynamic_cast<OpenGl_TriangleSet*> (
438 myObjects (aBVH->NodeInfoBuffer().at (theNodeIdx).x() - 1).get());
e276548b 439}
440
25ef750e 441// =======================================================================
442// function : AcquireTextures
443// purpose : Makes the OpenGL texture handles resident
444// =======================================================================
445Standard_Boolean OpenGl_RaytraceGeometry::AcquireTextures (const Handle(OpenGl_Context)& theContext) const
446{
447 if (theContext->arbTexBindless == NULL)
448 {
449 return Standard_True;
450 }
451
452#if !defined(GL_ES_VERSION_2_0)
453 for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx)
454 {
455 theContext->arbTexBindless->glMakeTextureHandleResidentARB (myTextureHandles[anIdx]);
456
457 if (glGetError() != GL_NO_ERROR)
458 {
459#ifdef RAY_TRACE_PRINT_INFO
460 std::cout << "Error: Failed to make OpenGL texture resident" << std::endl;
461#endif
462 return Standard_False;
463 }
464 }
465#endif
466
467 return Standard_True;
468}
469
470// =======================================================================
471// function : ReleaseTextures
472// purpose : Makes the OpenGL texture handles non-resident
473// =======================================================================
474Standard_Boolean OpenGl_RaytraceGeometry::ReleaseTextures (const Handle(OpenGl_Context)& theContext) const
475{
476 if (theContext->arbTexBindless == NULL)
477 {
478 return Standard_True;
479 }
480
481#if !defined(GL_ES_VERSION_2_0)
482 for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx)
483 {
484 theContext->arbTexBindless->glMakeTextureHandleNonResidentARB (myTextureHandles[anIdx]);
485
486 if (glGetError() != GL_NO_ERROR)
487 {
488#ifdef RAY_TRACE_PRINT_INFO
489 std::cout << "Error: Failed to make OpenGL texture non-resident" << std::endl;
490#endif
491 return Standard_False;
492 }
493 }
494#endif
495
496 return Standard_True;
497}
498
499// =======================================================================
500// function : AddTexture
501// purpose : Adds new OpenGL texture to the scene and returns its index
502// =======================================================================
503Standard_Integer OpenGl_RaytraceGeometry::AddTexture (const Handle(OpenGl_Texture)& theTexture)
504{
3a9b5dc8 505 if (theTexture->TextureId() == OpenGl_Texture::NO_TEXTURE)
506 {
507 return -1;
508 }
509
25ef750e 510 NCollection_Vector<Handle (OpenGl_Texture)>::iterator anIter =
511 std::find (myTextures.begin(), myTextures.end(), theTexture);
512
513 if (anIter == myTextures.end())
514 {
515 if (myTextures.Size() >= MAX_TEX_NUMBER)
516 {
517 return -1;
518 }
519
520 myTextures.Append (theTexture);
521 }
522
523 return static_cast<Standard_Integer> (anIter - myTextures.begin());
524}
525
526// =======================================================================
527// function : UpdateTextureHandles
528// purpose : Updates unique 64-bit texture handles to use in shaders
529// =======================================================================
530Standard_Boolean OpenGl_RaytraceGeometry::UpdateTextureHandles (const Handle(OpenGl_Context)& theContext)
531{
532 if (theContext->arbTexBindless == NULL)
533 {
534 return Standard_False;
535 }
536
47e9c178 537 if (myTextureSampler.IsNull())
538 {
539 myTextureSampler = new OpenGl_Sampler();
540 myTextureSampler->Init (*theContext.operator->());
541 myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
542 myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_MAG_FILTER, GL_LINEAR);
543 myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_WRAP_S, GL_REPEAT);
544 myTextureSampler->SetParameter (*theContext.operator->(), GL_TEXTURE_WRAP_T, GL_REPEAT);
545 }
546
25ef750e 547 myTextureHandles.clear();
548
549#if !defined(GL_ES_VERSION_2_0)
550 for (Standard_Integer anIdx = 0; anIdx < myTextures.Size(); ++anIdx)
551 {
47e9c178 552 const GLuint64 aHandle = theContext->arbTexBindless->glGetTextureSamplerHandleARB (
553 myTextures.Value (anIdx)->TextureId(), myTextureSampler->SamplerID());
25ef750e 554
555 if (glGetError() != GL_NO_ERROR)
556 {
557#ifdef RAY_TRACE_PRINT_INFO
558 std::cout << "Error: Failed to get 64-bit handle of OpenGL texture" << std::endl;
559#endif
560 return Standard_False;
561 }
562
563 myTextureHandles.push_back (aHandle);
564 }
565#endif
566
567 return Standard_True;
568}
569
e276548b 570namespace OpenGl_Raytrace
571{
572 // =======================================================================
573 // function : IsRaytracedElement
574 // purpose : Checks to see if the element contains ray-trace geometry
575 // =======================================================================
576 Standard_Boolean IsRaytracedElement (const OpenGl_ElementNode* theNode)
577 {
25ef750e 578 OpenGl_PrimitiveArray* anArray = dynamic_cast<OpenGl_PrimitiveArray*> (theNode->elem);
5322131b 579 return anArray != NULL
871fa103 580 && anArray->DrawMode() >= GL_TRIANGLES;
e276548b 581 }
582
a89742cf 583 // =======================================================================
584 // function : IsRaytracedElement
585 // purpose : Checks to see if the element contains ray-trace geometry
586 // =======================================================================
587 Standard_Boolean IsRaytracedElement (const OpenGl_Element* theElement)
588 {
589 const OpenGl_PrimitiveArray* anArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
590 return anArray != NULL
591 && anArray->DrawMode() >= GL_TRIANGLES;
592 }
593
e276548b 594 // =======================================================================
595 // function : IsRaytracedGroup
596 // purpose : Checks to see if the group contains ray-trace geometry
597 // =======================================================================
d4aaad5b 598 Standard_Boolean IsRaytracedGroup (const OpenGl_Group* theGroup)
e276548b 599 {
d4aaad5b 600 for (const OpenGl_ElementNode* aNode = theGroup->FirstNode(); aNode != NULL; aNode = aNode->next)
e276548b 601 {
602 if (IsRaytracedElement (aNode))
603 {
604 return Standard_True;
605 }
606 }
607 return Standard_False;
608 }
e276548b 609}