Skip to content

GEOMETRY_TYPE_TRIANGLE vs GEOMETRY_TYPE_USER BVH build times #444

@mariuszhermansdorfer

Description

@mariuszhermansdorfer

I'm running collision tests between two triangular meshes in embree4. The rtcCollide function only accepts GEOMETRY_TYPE_USER as input. I got it to work and successfully find intersections between my meshes but noticed significant increase in build times for the BVH.

When creating a BVH for raytracing with the same geometry, I can use GEOMETRY_TYPE_TRIANGLE and the BVH is built almost instantaneously.

Here are the results of the rtcCommitScene for a 25k tris mesh

GEOMETRY_TYPE_USER : 14.3882 ms
GEOMETRY_TYPE_TRIANGLE : 0.0342 ms

The relevant code below. Do you have any ideas why this is the case?

Collision:

void createBaseMesh(float vertices[], int verticesLength, int faces[], int facesLength)
{
  RTCDevice device = rtcNewDevice(NULL);
  RTCScene scene = rtcNewScene(device);
  rtcSetSceneBuildQuality(scene, RTC_BUILD_QUALITY_LOW);
  rtcSetSceneFlags(scene, RTC_SCENE_FLAG_DYNAMIC);

  meshes.clear();
  std::unique_ptr<Mesh> baseMesh(new Mesh());
  baseMesh->x_.resize(verticesLength / 3);
  baseMesh->tris_.resize(facesLength / 3);

  int j = 0;
  for (int i = 0; i < verticesLength; i += 3) {
    baseMesh->x_[j].x = vertices[i];
    baseMesh->x_[j].y = vertices[i + 1];
    baseMesh->x_[j].z = vertices[i + 2];
    j++;
  }

  j = 0;
  for (int i = 0; i < facesLength; i += 3) {
    baseMesh->tris_[j].v0 = faces[i];
    baseMesh->tris_[j].v1 = faces[i + 1];
    baseMesh->tris_[j].v2 = faces[i + 2];
    j++;
  }

  RTCGeometry geom = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_USER);
  unsigned int geomID = rtcAttachGeometry(scene, geom);
  rtcSetGeometryUserPrimitiveCount(geom, baseMesh->tris_.size());
  rtcSetGeometryUserData(geom, (void*)(size_t)geomID);
  rtcSetGeometryBoundsFunction(geom, triangle_bounds_func, nullptr);
  rtcSetGeometryIntersectFunction(geom, NULL);
  rtcSetGeometryOccludedFunction(geom, NULL);
  rtcCommitGeometry(geom);
  rtcReleaseGeometry(geom);
  meshes.push_back(std::move(baseMesh));
  rtcCommitScene(scene);
  rtcCollide(scene, scene, CollideFunc, &sim_collisions);
  rtcReleaseScene(scene);
  rtcReleaseDevice(device);
}

Raytracing

void RaytracerTest(float vertices[], int verticesLength, int faces[], int facesLength)
{
  RTCDevice device = rtcNewDevice(NULL);
  RTCScene scene = rtcNewScene(device);
  RTCGeometry geom = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_TRIANGLE);

  float* vb = (float*)rtcSetNewGeometryBuffer(geom,
    RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, verticesLength * sizeof(float), 3);
  memcpy(vb, vertices, verticesLength * sizeof(float));

  unsigned* ib = (unsigned*)rtcSetNewGeometryBuffer(geom,
    RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, facesLength * sizeof(unsigned), 1);  
  memcpy(ib, faces, facesLength * sizeof(unsigned));
  rtcCommitGeometry(geom);
  rtcAttachGeometry(scene, geom);
  rtcReleaseGeometry(geom);
  rtcCommitScene(scene);
  rtcReleaseScene(scene);
  rtcReleaseDevice(device);
}

Here is a benchmark of all the function calls:

rtcNewGeometry: 0.0022 ms
rtcAttachGeometry: 0.0023 ms
rtcSetGeometryUserPrimitiveCount: 0.0003 ms
rtcSetGeometryUserData: 0.0002 ms
rtcSetGeometryBoundsFunction: 0.0002 ms
rtcSetGeometryIntersectFunction: 0.0002 ms
rtcCommitGeometry: 0.0001 ms
rtcReleaseGeometry: 0.0001 ms
meshes: 0.0001 ms
rtcCommitScene: 14.3882 ms
rtcCollide: 1.5581 ms

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions