Proper and efficient way to working with large BIM models

Hi everyone, I’m new here :slight_smile:

I am developing a BIM module for planning web applications.
In my case, I get the geometry from the server in the form
indexes: Uint16Array
positions: Float32Array
colors: Float32Array
userData: Record<string, number[ ]> - finds the top to the element

The models come from IFC and are often oversized.

I would like to comply with the following requirements:

  • acceptable FPS (on good hardware)
  • ability to select elements in the grid
  • correct transparency
  • simplicity

I have tried two ways:

  1. Each element of the model is a separate mesh
    :ok_hand: Simplicity
    :ok_hand: Transparency
    :-1: Low FPS
  2. Made 2 meshes opaque and transparent.
    :ok_hand: Partially solved transparency problem
    :ok_hand: High FPS
    :-1: Difficulty

I want to try:

  1. Meshes by the number of elements in the model and merged into 2 by transparency
    So, we will get 2 subMeshes arrays.
    I don’t know how transparency would work in such cases.

  2. One merged opaque mesh and separate transparent ones.

  3. In my cases, the models have hundreds and repeating elements that could use InstancedMeshes.
    but I don’t know about finding duplicate elements by vertices yet.

In this regard, I am interested in possible questions.

  1. Are there other ways I’m missing to render large geometry while keeping it simple?
  2. How can transparent geometry be merged while and working correctly?
  3. Is it possible to search for repeating geometry in mesh?

I would appreciate any ideas and advice :slight_smile:
Thank you in advance!

Most CAD/BIM models I’ve seen, any repeating geometry that might be a candidate for instancing is named the same, just with a different numeric suffix e.g. window300x1000_01, window300x1000_02 etc. Also comparing vertices would be too time consuming, but you could check the name and then compare the bounding box size to verify. That should capture most duplicates.

1 Like

I’m learning too and have made your request completely chatGPT. Here is his information:

There are a few additional techniques you can try for rendering large geometry in Babylon.js:

  1. Level of Detail (LOD) technique: This technique involves using different versions of the same mesh with varying levels of detail. The high-detail version of the mesh is used when the camera is close to the object, and a low-detail version is used when the camera is far away. This can significantly improve performance while maintaining visual quality.
  2. Occlusion culling: This technique involves hiding objects that are not visible to the camera. This can improve performance by reducing the number of objects that need to be rendered. Babylon.js has built-in support for frustum culling, which is a form of occlusion culling.

Regarding your questions:

  1. Merging meshes is a good approach for reducing the number of draw calls and improving performance. To handle transparency correctly, you can sort the meshes based on their distance from the camera, and render the transparent meshes after the opaque ones. This will ensure that the transparent meshes are correctly blended with the background.
  2. Babylon.js provides a utility function called Mesh.MergeMeshes() that can merge multiple meshes into a single mesh. You can set the use32bitsIndices and useVertexColors parameters to true to handle large meshes with vertex colors correctly.
  3. To find duplicate geometry in a mesh, you can use the SimplificationSettings class in Babylon.js. This class provides a createShapeComparer() function that can be used to compare the shapes of different meshes. You can use this function to identify duplicate geometry and merge it using InstancedMeshes.

I hope these suggestions are helpful!

Welcome aboard!

Is there any other way I haven’t found to render large geometries while keeping it simple?

Nothing is simple when it comes to transparency!

If you can afford it, OIT will work best. If you use it, you can use the solution with two meshes, one for the opaque parts and one for the transparent parts.

Otherwise, I don’t think you have any choice but to create one mesh for the opaque parts and one mesh per transparent object if you want to limit rendering artifacts.

One thing you could try is to have a single mesh for the transparent parts and turn on [facet sorting] (Facet Data | Babylon.js Documentation). However, facet sorting is done on every frame on the CPU, which may be too heavy on performance if there are many faces.

From your other thread:

  • ability to select (pick) individual elements
  • ability to hide individual elements

If you want picking to work, you will have to create one mesh per pickable object: picking works at the mesh level.

Or you can try GPU picking: