ThatOpen / web-ifc-viewer

Graphics engine and toolkit for client applications.
MIT License
951 stars 236 forks source link

IFC to GLTF - possible enhancement using EXT_mesh_features and EXT_structural_metadata #140

Open sweco-sekrsv opened 2 years ago

sweco-sekrsv commented 2 years ago

I really like the idea of being able to convert/export the IFC files to GLTF and reuse them later instead of loading the original IFC file. Great job! I think this can possibly be improved further by collapsing meshes together (saving draw calls) and also simplified by skipping storing the properties in an external json file. Instead of having the attributes in separate json files these can be added directly to the gltf file itself.

EXT_mesh_features: Features for structured data Basically allows to merge geometry to save draw calls but be able to keep original ID's to the objects/faces even after being merged. This will allow for picking/selecting even if the orginal objects have been merged together. https://github.com/KhronosGroup/glTF/pull/2082 https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_mesh_features

EXT_structural_metadata: Properties for structured data Defines how fine-grained metadata can be stored within a glTF asset https://github.com/KhronosGroup/glTF/pull/2151

These extensions are already being used in 3D Tiles next https://github.com/CesiumGS/3d-tiles/tree/main/next

Some examples: https://github.com/javagl/3d-tiles-samples/blob/gltf-metadata-samples/glTF/README.md

gltfpack It seems that gltfpack will possibly add support for these extension, this will allow compressing the gltf files further. Gltfpack can really make a big difference in both drawcalls but also to squeeze file size. I have seen file sizes 10 times smaller than the original gltf file. https://meshoptimizer.org/gltf/

This would also make it possible to load the gltf files easier with all the properties into other gltf vievers (such as babylon.js, Unity3D etc) as long as they add support for these extensions. By using these extensions, other tools would also be able to produce gltf files with standardized properties which could be consumed directly by the ifc.js ecosystem.

agviegas commented 2 years ago

Hey @sweco-sekrsv thanks a lot for all this useful pointers! The truth is that we are now decoupling our geometry API from the rest of the library. They goal is to be able to use this not only with IFC, but to create any BIM tool with Three.js. You can find our first sketches here.

Right now we have something similar to the glTF features: we store the ID of each element as a number as a vertex attribute and we use that to retrieve back elements. The big advantage is that we can save a lot of draw calls, but, as you can imagine, it's not very efficient memory wise.

For this reason we have decided to try to mix this merging strategy with an instancing strategy. The idea is that items like a chair, a window or a door could be instanced (thus consuming minimum memory), whereas walls, floor and other low-poly (usually unique) items could be merged. That way we could find a sweet point between draw calls and memory usage designed especifically for BIM.

This is something we started this week and we are open to ideas, so if you want to participate (e.g. consider the possibility of using existing standards like the ones you pointed out), we'd love to hear it / see you participate!

sweco-sekrsv commented 2 years ago

Great, I agree that there will probably be a sweet spot between using instances and collapsing geometry! In general I'm voting for using standards (if they are available ), this makes it easier for other tools to consume the output. For example when using gltf-extensions it would make it easier to integrate/load the exported gltf-files into 3D engines other than three.js

For instanced meshes saved to Gltf you could likely use the extension EXT_mesh_gpu_instancing: https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md

Deduplication Another idea is to have functions for deduplication based on mesh contents. If the original scene is lacking instancing for nodes that refer to the same original mesh this function could be run to deduplicate the meshes so they can be instanced. Imagine a scene with 100 chairs that have been collapsed to a single mesh. This scene will use quite alot of memory if being served as is. After a deduplication checking/cleanup all of the 100 chairs can be instanced to a single chair mesh. In this case all the chairs would have the same properties as the orginal mesh. Some BIM/3d-tools might only export to file formats that lacks instancing support or the instances have been collapsed based on export settings. Being able to re-instance them again would be a win in these cases.

There is a dedup function for gltf-files in the gltf-transform library: https://gltf-transform.donmccurdy.com/functions.html

3D tiles Another idea is when collapsed meshes is over a certain memory/triangle limit or the geograhical bound of the meshes is very large (like in infrastructure BIM-models) the IFC.js toolset could probably utilize the 3D tiles specification to further optimize/chop up the data for efficient data delivery.

https://github.com/CesiumGS/3d-tiles https://github.com/CesiumGS/3d-tiles/tree/main/next

Here is a tool that can create 3D-tiles (not 3D tiles next) from a obj: https://github.com/OpenDroneMap/Obj2Tiles