Is it possible to draw proper IFC walls in a web browser? Yes! And in this tutorial I want to show you how.
If you haven’t seen the previous tutorial yet on creating a simple IFC wall using IfcOpenShell WebAssembly, I suggest you check that out first, since we will skip over some of the basics in this tutorial and jump to the good stuff.
If you want to follow along and play with the code yourself, you can find it here on Github.
The first interesting bit is on line 56 to 61 where we load a custom Python class named model.py:
56
57
58
59
60
61
await pyodide.runPythonAsync(`from pyodide.http import pyfetch
response =await pyfetch("./model.py")
with open("model.py", "wb") as f:
f.write(await response.bytes())
`)
Then on lines 63 to 69, we instantiate this new Model class and call its function “create_2pt_wall”. Notice we are feeding this function 2 numpy arrays which represent the start and end points of the wall respectively. The third parameter is the elevation from the storey, which we set to 0 here. 4th parameter is the height of the wall in meters (if you are reading this from America, sorry, you will have to do the conversion to feet yourself…), then the width of the wall, 200mm (0.2m) and lastly the storey we want to associate this wall to:
63
64
65
66
67
68
69
pyodide.runPython(`from model import Model
import numpy as np
modelObject = Model()
modelObject.create_2pt_wall(np.array([0, 0]), np.array([1, 1]), 0, 3., 0.2, modelObject.storey)
model = modelObject.get_model()
`);
Then pretty much the rest of the document is similar to the previous example and it loads the initial Three.js scene, so let’s jump down to lines 254 to 273. Here we find the definition of the onMouseClick event, which fires every time we, you guessed it, click on the viewport:
It first calls the getPoint() function, which gets a point in 3D space by casting a ray from the point where we clicked our mouse towards an invisible flat plane we have defined in 3D space as flat ground:
Back in the mouse click event, we check if this is the first point and if it isn’t, we create a new wall between the previous and current points and add it to the Three.js scene. It’s also being saved to the IFC model automatically in the background… you could uncomment lines 263 & 264 to see the IFC text output in action:
263
264
//let ifc = ifcopenshell.file.from_string(model.to_string()); // DEBUG ONLY
//console.log(ifc.to_string());
What would you like to see us build next? Please let us know on Twitter or Youtube.