-
Notifications
You must be signed in to change notification settings - Fork 420
Description
I've been working on writing some python binding code for an algorithm that relies on Embree. I ran into an issue when I found I needed to be able to efficiently add geometries to the Embree scene that the algorithm processes. When wrapping the Embree objects for Python, I found that many attributes are settable but not gettable through the API. This gets in the way of providing an object oriented binding for object oriented languages. The frustrating part is that I can see that most of these missing functions are exposed methods on the internal Embree objects that the C API wraps.
While making this I noticed the pyembree branch that @dopitz has been working on. Personally, I'm disappointed that it is a transliteration rather than a Pythonic API. But I suspect he has run into the issues I've had with getting data back out of Embree, and doing something more user friendly is difficult.
I went through the v4.3 C API and made a list of functions that, in my opinion, should be added to the API:
/**
* Buffer
*/
bool rtcIsBufferShared(RTCBuffer buffer);
size_t rtcGetBufferSize(RTCBuffer buffer);
/**
* Device
* (These seem less necessary)
*/
RTCErrorFunction rtcGetDeviceErrorFunction(RTCDevice device);
void* rtcGetDeviceErrorFunctionUserPtr(RTCDevice device);
RTCMemoryMonitorFunction rtcSetDeviceMemoryMonitorFunction(RTCDevice device);
void* rtcSetDeviceMemoryMonitorFunctionUserPtr(RTCDevice device);
/**
* Geometry
*/
enum RTCGeometryType rtcGetGeometryType(RTCGeometry geometry);
bool rtcIsGeometryCommitted(RTCGeometry geometry);
void rtcEnableGeometry(RTCGeometry geometry, bool enable); // Overload
bool rtcIsGeometryEnabled(RTCGeometry geometry);
struct RTCAccessor {
RTCFormat format;
RTCBuffer buffer;
size_t byteOffset;
size_t byteStride;
size_t itemCount;
};
void rtcSetGeometryBuffer(RTCGeometry geometry, RTCBufferType type, unsigned int slot, RTCAccessor accessor);
RTCAccessor rtcGetGeometryBufferAccessor(RTCGeometry geometry, RTCBufferType type, unsigned int slot);
void rtcGetGeometryBufferAccessors(RTCGeometry geometry, RTCBufferType type, unsigned int* numSlots, RTCAccessor* accessors = nullptr); // like vulkan
void rtcGetGeometryInstancedScenes(RTCGeometry geometry, size_t* numScenes, RTCScene* scenes = nullptr); // like vulkan
bool rtcGetGeometryTransform(RTCGeometry geometry, unsigned int timestep, enum RTCFormat format, void* xfm); // overload
unsigned int rtcGetGeometryTimeStepCount(RTCGeometry geometry);
void rtcGetGeometryTimeRange(RTCGeometry geometry, float* startTime, float* endTime);
unsigned int rtcGetGeometryVertexAttributeCount(RTCGeometry geometry);
unsigned int rtcGetGeometryMask(RTCGeometry geometry);
unsigned int rtcGetGeometryUserPrimitiveCount(RTCGeometry geometry);
float rtcGetGeometryTessellationRate(RTCGeometry geometry);
unsigned int rtcGetGeometryTopologyCount(RTCGeometry geometry);
enum RTCSubdivisionMode rtcGetGeometrySubdivisionMode(RTCGeometry geometry, unsigned int topologyID);
unsigned int rtcGetGeometryVertexAttributeTopology(RTCGeometry geometry, unsigned int vertexAttributeID);
bool rtcIsGeometryFilterFunctionFromArguments(RTCGeometry geometry);
RTCFilterFunctionN rtcGetGeometryIntersectFilterFunction(RTCGeometry geometry);
RTCFilterFunctionN rtcGetGeometryOccludedFilterFunction(RTCGeometry geometry);
RTCPointQueryFunction rtcGetGeometryPointQueryFunction(RTCGeometry geometry);
RTCBoundsFunction rtcGetGeometryBoundsFunction(RTCGeometry geometry);
RTCIntersectFunctionN rtcGetGeometryIntersectFunction(RTCGeometry geometry);
RTCOccludedFunctionN rtcGetGeometryOccludedFunction(RTCGeometry geometry);
RTCDisplacementFunctionN rtcGetGeometryDisplacementFunction(RTCGeometry geometry);
/**
* Scene
*/
void rtcGetGeometryIDs(RTCScene scene, size_t* numGeomIDs, unsigned int* geomIDs = nullptr); // like vulkan
bool rtcIsSceneCommitted(RTCScene scene);
RTCProgressMonitorFunction rtcGetSceneProgressMonitorFunction(RTCScene scene);
void* rtcGetSceneProgressMonitorFunctionUserPtr(RTCScene scene);
enum RTCBuildQuality rtcGetSceneBuildQuality(RTCScene scene);One larger change that I listed was adding an RTCAccessor struct based on the glTF Accessor so that the buffer binding parameters could be returned as a single structure. I would suggest returning a zero initialized structure for unpopulated but assignable slots on a geometry.
As a side note, what I mean by // like vulkan is that it returns a vector by two successive calls. The first call with the output pointer set to nullptr just gets the size of the resulting array. The user then allocates that memory, and calls the function again with the allocated pointer to get the array values. The default value would need to be wrapped in a macro controlled by EMBREE_API_NAMESPACE.
I'd also like to see a C++ header with compile time information. Some good information would be the buffer types attached to each geometry type, the number of slots for each buffer type, and the buffer formats allowed for each buffer type. But this is not necessary.