@@ -23,6 +23,7 @@ __all__ = ['GeometryFlags',
2323 ' CurveEndcapFlags'
2424 ]
2525
26+
2627class GeometryFlags (IntEnum ):
2728 """
2829 Wraps the OptixGeometryFlags enum.
@@ -31,6 +32,9 @@ class GeometryFlags(IntEnum):
3132 DISABLE_ANYHIT = OPTIX_GEOMETRY_FLAG_DISABLE_ANYHIT,
3233 REQUIRE_SINGLE_ANYHIT_CALL = OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL
3334
35+ IF _OPTIX_VERSION_MAJOR == 7 and _OPTIX_VERSION_MINOR > 4 :
36+ DISABLE_TRIANGLE_FACE_CULLING = OPTIX_GEOMETRY_FLAG_DISABLE_TRIANGLE_FACE_CULLING
37+
3438
3539class BuildFlags (IntFlag ):
3640 """
@@ -45,34 +49,29 @@ class BuildFlags(IntFlag):
4549 ALLOW_RANDOM_INSTANCE_ACCESS = OPTIX_BUILD_FLAG_ALLOW_RANDOM_INSTANCE_ACCESS,
4650
4751
48- IF _OPTIX_VERSION > 70300 : # switch to new instance flags
49- class PrimitiveType (IntEnum ):
50- """
51- Wraps the OptixPrimitiveType enum.
52- """
53- CUSTOM = OPTIX_PRIMITIVE_TYPE_CUSTOM,
54- ROUND_QUADRATIC_BSPLINE = OPTIX_PRIMITIVE_TYPE_ROUND_QUADRATIC_BSPLINE,
55- ROUND_CUBIC_BSPLINE = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE,
56- ROUND_LINEAR = OPTIX_PRIMITIVE_TYPE_ROUND_LINEAR,
57- ROUND_CATMULLROM = OPTIX_PRIMITIVE_TYPE_ROUND_CATMULLROM,
58- TRIANGLE = OPTIX_PRIMITIVE_TYPE_TRIANGLE
59-
60- class CurveEndcapFlags (IntEnum ):
52+ class PrimitiveType (IntEnum ):
53+ """
54+ Wraps the OptixPrimitiveType enum.
55+ """
56+ CUSTOM = OPTIX_PRIMITIVE_TYPE_CUSTOM,
57+ ROUND_QUADRATIC_BSPLINE = OPTIX_PRIMITIVE_TYPE_ROUND_QUADRATIC_BSPLINE,
58+ ROUND_CUBIC_BSPLINE = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE,
59+ ROUND_LINEAR = OPTIX_PRIMITIVE_TYPE_ROUND_LINEAR
60+
61+ IF _OPTIX_VERSION > 70300 : # switch to new instance flags
62+ ROUND_CATMULLROM = OPTIX_PRIMITIVE_TYPE_ROUND_CATMULLROM
63+ IF _OPTIX_VERSION > 70400 : # switch to new instance flags
64+ SPHERE = OPTIX_PRIMITIVE_TYPE_SPHERE
65+
66+ TRIANGLE = OPTIX_PRIMITIVE_TYPE_TRIANGLE
67+
68+
69+ class CurveEndcapFlags (IntEnum ):
70+ IF _OPTIX_VERSION > 70300 : # switch to new instance flags
6171 DEFAULT = OPTIX_CURVE_ENDCAP_DEFAULT,
6272 ON = OPTIX_CURVE_ENDCAP_ON
63- ELSE :
64- class CurveEndcapFlags (IntEnum ):
65- DEFAULT = 0 # only for interface. Ignored for Optix versions below 7.4
66-
67- class PrimitiveType (IntEnum ):
68- """
69- Wraps the OptixPrimitiveType enum.
70- """
71- CUSTOM = OPTIX_PRIMITIVE_TYPE_CUSTOM,
72- ROUND_QUADRATIC_BSPLINE = OPTIX_PRIMITIVE_TYPE_ROUND_QUADRATIC_BSPLINE,
73- ROUND_CUBIC_BSPLINE = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE,
74- ROUND_LINEAR = OPTIX_PRIMITIVE_TYPE_ROUND_LINEAR,
75- TRIANGLE = OPTIX_PRIMITIVE_TYPE_TRIANGLE
73+ ELSE :
74+ DEFAULT = 0 # only for interface. Ignored for Optix versions below 7.4
7675
7776
7877class InstanceFlags (IntFlag ):
@@ -325,7 +324,6 @@ cdef class BuildInputCustomPrimitiveArray(BuildInputArray):
325324 return self .build_input.numPrimitives
326325
327326
328-
329327cdef class BuildInputCurveArray(BuildInputArray):
330328 """
331329 BuildInputArray for curve inputs. This class wraps the OptixBuildInputCurveArray struct.
@@ -430,6 +428,109 @@ cdef class BuildInputCurveArray(BuildInputArray):
430428 return self .build_input.numPrimitives
431429
432430
431+ IF _OPTIX_VERSION > 70400 :
432+ cdef class BuildInputSphereArray(BuildInputArray):
433+ """
434+ BuildInputArray for a sphere. This class wraps the OptixBuildInputSphereArray struct.
435+ In Contrast to the behavior of the Optix C++ API, this Python class will automatically convert all numpy.ndarrays
436+ to cupy.ndarrays and keep track of them.
437+
438+ Parameters
439+ ----------
440+ vertex_buffers:
441+ List of vertex buffers (one for each motion step) or a single array.
442+ All arrays will be converted to cupy.ndarrays before any further processing.
443+ index_buffer: ndarray, optional
444+ A single 2d array containing the indices of all triangles or None
445+ num_sbt_records: int
446+ The number of records in the ShaderBindingTable for this geometry
447+ flags: GeometryFlags
448+ Flags to use in this input for each motionstep
449+ sbt_record_offset_buffer: ndarray, optional
450+ Offsets into the ShaderBindingTable record for each primitive (index) or None
451+ pre_transform: ndarray(3,4) or None
452+ A transform to apply prior to processing
453+ primitive_index_offset: int
454+ The offset applied to the primitive index in device code
455+ """
456+ def __init__ (self ,
457+ vertex_buffers ,
458+ radius_buffers ,
459+ num_sbt_records = 1 ,
460+ flags = None ,
461+ sbt_record_offset_buffer = None ,
462+ pre_transform = None ,
463+ primitive_index_offset = 0
464+ ):
465+
466+ self ._d_vertex_buffers = [cp.asarray(vb) for vb in ensure_iterable(vertex_buffers)]
467+ self ._d_vertex_buffer_ptrs.reserve(len (self ._d_vertex_buffers))
468+
469+ self ._d_radius_buffers = [cp.asarray(vb) for vb in ensure_iterable(radius_buffers)]
470+ self ._d_radius_buffer_ptrs.reserve(len (self ._d_radius_buffers))
471+
472+ if len (self ._d_radius_buffers) != len (self ._d_vertex_buffers):
473+ raise ValueError (" Argument radius_buffers must have the same number of arrays as vertex_buffers." )
474+
475+ if len (self ._d_vertex_buffers) == 0 :
476+ raise ValueError (" BuildInputSphereArray cannot be empty." )
477+
478+ dtype = self ._d_vertex_buffers[0 ].dtype
479+ shape = self ._d_vertex_buffers[0 ].shape
480+ strides = self ._d_vertex_buffers[0 ].strides
481+
482+ radius_dtype = self ._d_radius_buffers[0 ].dtype
483+ radius_shape = self ._d_radius_buffers[0 ].shape
484+ strides = self ._d_radius_buffers[0 ].strides
485+
486+ for vb, rb in zip (self ._d_vertex_buffers, self ._d_radius_buffers):
487+ if vb.dtype != dtype or vb.shape != shape or vb.strides != strides:
488+ raise ValueError (" All vertex buffers must have the same size and dtype." )
489+ self ._d_vertex_buffer_ptrs.push_back(vb.data.ptr)
490+
491+ if rb.dtype != dtype or rb.shape != shape or rb.strides != strides:
492+ raise ValueError (" All radius buffers must have the same size and dtype." )
493+ self ._d_radius_buffer_ptrs.push_back(rb.data.ptr)
494+
495+ self .build_input.vertexBuffers = self ._d_vertex_buffer_ptrs.const_data()
496+ self .build_input.radiusBuffers = self ._d_radius_buffer_ptrs.const_data()
497+
498+ self .build_input.vertexStrideInBytes = self ._d_vertex_buffers[0 ].strides[0 ]
499+ self .build_input.radiusStrideInBytes = self ._d_radius_buffers[0 ].strides[0 ]
500+
501+ self .build_input.numVertices = shape[0 ]
502+ self .build_input.singleRadius = 1 if self ._d_radius_buffers[0 ].shape[0 ] == 1 else 0
503+
504+ self .build_input.numSbtRecords = num_sbt_records
505+ self ._flags.resize(num_sbt_records)
506+
507+ if flags is None :
508+ for i in range (num_sbt_records):
509+ self ._flags[i] = OPTIX_GEOMETRY_FLAG_NONE
510+ else :
511+ for i in range (num_sbt_records):
512+ self ._flags[i] = flags[i].value
513+
514+ self .build_input.flags = self ._flags.data()
515+
516+
517+ if sbt_record_offset_buffer is not None :
518+ self ._d_sbt_offset_buffer = cp.asarray(sbt_record_offset_buffer).ravel()
519+ self .build_input.sbtIndexOffsetBuffer = self ._d_sbt_offset_buffer.data.ptr
520+ itemsize = self ._d_sbt_offset_buffer.itemsize
521+ if itemsize > 4 :
522+ raise ValueError (" Only 32 bit allowed at max" )
523+ self .build_input.sbtIndexOffsetSizeInBytes = itemsize
524+ self .build_input.sbtIndexOffsetStrideInBytes = self ._d_sbt_offset_buffer.strides[0 ]
525+ else :
526+ self .build_input.sbtIndexOffsetBuffer = 0
527+ self .build_input.sbtIndexOffsetStrideInBytes = 0
528+ self .build_input.sbtIndexOffsetSizeInBytes = 0
529+
530+ self .build_input.primitiveIndexOffset = primitive_index_offset
531+
532+ __all__ .append(' BuildInputSphereArray' )
533+
433534cdef class Instance(OptixObject):
434535 """
435536 Class representing a single instance (another AccelerationStructure) for use in a Instance level AccelerationStructure.
0 commit comments