Skip to main content

πŸš€ Multithreading

Introduction#

πŸ₯ΆπŸ₯ΆπŸ₯Ά Everything seen so far is very cool, but we have a problem: when we load a very large model the application freezes for some seconds. This problem also happens when we want to extract many properties from the model. Is there any way to avoid this?

πŸ”₯ Of course, IFC.js has foreseen this situation and has implemented multithreading. This means that heavy operations will be carried out in a parallel process that will not block the application, which will be updated asynchronously when the process concludes.

πŸ‘Œ This sounds complicated, and it is. But don't worry: we've got it all set up so you can have this in your BIM applications in a couple of lines of code.

You can find the full example of this tutorial here.

How to do it#

Set up the webworker#

πŸ‘©β€πŸ« In order to enable multithreading, the webworker must be configured. But what is a webworker? The webworker is the mechanism that web browsers have to be able to work with multithreading. But don't worry if you haven't heard of them before, you don't need them to use multithreading in IFC.js.

πŸ“¦πŸ“¦πŸ“¦ If you work with npm, yarn or another package manager in your project there should be a folder called node_modules, with all the folders of the libraries your project is using. In node_modules/web-ifc-three you will find the two files needed to use webworkers: IFCWorker.js and IFCWorker.js.map.

You have to copy these two files to a directory in your project that will be served with the final application. This varies depending on the technology you are using (vanilla JS, React, Angular, etc). You can use the same directory you are using for the wasm files.

🌍 Then you have to specify where this file is located, in the same way as with the wasm file. This can be done like this:

async function setUpMultiThreading() {
const manager = ifcLoader.ifcManager;
// These paths depend on how you structure your project
await manager.useWebWorkers(true, "IFCWorker.js");
await manager.setWasmPath("../../../");
}
setUpMultiThreading();

πŸ₯Άβ›” And, voi lΓ‘! Believe it or not, you have already enabled multithreading in your project. If you now try to load a file in your application or try to get many properties at once, you will see that the application does not freeze.

πŸ€–β“πŸ“š Keep in mind that the version of the webworker has to match the version of the library you are using. This means that if you update the version of web-ifc-three in the future, you'll need to copy these files again. You can automate this using a command-line library to copy files like cpy.

Loading progress#

πŸ”₯ Using multithreading in your BIM application has numerous advantages. The most immediate is that we can now show the user the loading progress of a model. First we'll add a simple HTML message to show the progress:

div id="text-container">
<p>Progress:</p>
<p id="progress-text">0</p>
<p>%</p>
/div>

✨✨✨ Next we are going to link this HTML element to the model load event. This can be easily done with the setOnProgress() method. Let's also apply some basic math to convert progress into a percentage.

function setupProgressNotification() {
const text = document.getElementById("progress-text");
ifcLoader.ifcManager.setOnProgress((event) => {
const percent = (event.loaded / event.total) * 100;
const result = Math.trunc(percent);
text.innerText = result.toString();
});
}
setupProgressNotification();

🌈 If you have done everything correctly, we should be able to see the following viewer. If you try to load an IFC model, not only you will see that the loading process does not block the 3D view, but the html text shows the loading progress in real time.

Next steps#

πŸŽ‰πŸŽ‰πŸŽ‰ Congratulations! You can now create multithreaded BIM applications that never freeze.

😎 You are now familiar with some advanced tools of IFC.js, but there's much more to learn. In later tutorials we will see how to not only read, but also edit and create IFC files.