Skip to main content

πŸ“ƒ Properties

Introduction#

🧬🧬🧬️ Although virtually all BIM models have geometry, almost everyone agrees that what is really important is the "I" in BIM, i.e. Information. IFC.js can traverse any IFC file from top to bottom at native speed and with almost no code.

πŸ’Ύ This not only makes it possible to create web applications that read information from IFC files directly on the client side, but also to transfer that information into relational or non-relational databases and process it on the backend.

πŸ“š There are several types of properties in the IFC scheme, each with a specific purpose, and IFC.js can get all of them. Some of the most common are:

Native properties

Specific to each IFC class.

Type properties

Describe properties of all elements of the same type (e.g. all envelope walls of a particular type).

Material properties

Describes all the materials that make up the layers of that element.

Property sets

Arbitrary sets of user-defined properties. There may be multiple sets of properties associated with one or more elements. Each property set contains an arbitrary group of properties related to each other.

Quantity sets

Sets of properties describing the dimensions of the elements to which they refer. Although it would also be possible to infer element dimensions implicitly from the geometry definition, this explicit description makes it much easier to create applications that measure IFC models.

πŸš΄β€β™‚οΈ But enough theory! Let's get down to work.

How to do it#

Hello properties#

πŸ‘©β€πŸ« The basic way to extract properties from an IFC is from the ID of an element. In many cases, when the user selects an element, we will want to get its direct and indirect properties. Previous tutorials have shown how to get that ID easily.

☝ Now that we have that ID, how hard it is to get the properties of an element? You only need to add one line of code to what we saw in the picking tutorial to be able to see the properties of the selected element when double clicking.

// Event that gets executed when an item is picked
function pick(event) {
const found = cast(event)[0];
if (found) {
const index = found.faceIndex;
const geometry = found.object.geometry;
const ifc = ifcLoader.ifcManager;
const id = ifc.getExpressId(geometry, index);
const modelID = found.object.modelID;
const props = ifc.getItemProperties(modelID, id);
output.innerHTML = JSON.stringify(props, null, 2);
}
}

🀨 But what are these properties?

They are native properties, that is, the basic properties inherent to each ifc element type. The properties are given as a JavaScript object, so they are super easy to traverse.

πŸ€” Why do some properties have numbers as values?

These are not numbers, but express IDs! This means that you can use getItemProperties() again using that ID, and you'll get the properties of that referenced element.

That is how IFC works: each element has properties, and each property can be the reference to other element. So you can basically traverse the whole IFC navigating through references.

πŸ˜‘ References? But I want all the information directly!

Don't worry, we got you covered! You can use an optional third parameter of getItemProperties(), which is a boolean that is false by default. If you set it to true, we will get all referenced elements recursively and give you everything nicely packed in a single JavaScript object.

Nonetheless, we usually recommend avoiding this in order to avoid runtime overheads. Much better is to use getItemProperties() only for those IDs you need when you need them.

πŸ™„ How can I get other types of properties?

The IFC.js API has other similar methods for all other property types: getTypeProperties(), getMaterialProperties() and getPropertySets(). This last method fetches both property sets and quantity sets.

😨 Is getItemProperties() the only way to traverse the IFC?

Not at all! We'll see how to traverse the whole spatial structure next.

Traverse the IFC#

πŸ”₯ You can now browse the IFC information from the ID of an element, and you also know how to get the ID by clicking on objects in the scene. However, we know that this is not enough.

  • What if you want to get the properties of elements that have no geometric representation (e.g. IfcSite)?

  • What if you want to traverse the entire spatial structure of the IFC?

🌈 Of course, all this is really easy with the IFC.js API.

Spatial tree#

🌳🌲🌴 As you may know, all IFCs have a general structure called Spatial Element Structure (we'll refer to it as spatial tree). It is composed of elements that define the relative position of all products (physical objects) in the project.

You can get the spatial structure of the project simply calling getSpatialStructure(), where the only parameter is the modelID. This method will return the whole spatial structure of the project as a JavaScript object.

🚧 Does this means that you get all the properties of all the products of the project? Nope, because that would be computationally expensive. Instead, you get a tree of items with the following information:

interface Node {
expressID: number;
type: string;
children: Node[];
}

πŸ‘©β€πŸ« Notice that you only get the type (e.g. IfcWall) and the express ID. If you want to get the properties of an element, you'll have to traverse the tree and call the abovementioned property getter methods over all the IDs.

If your goal is to display properties to users, it's generally better to only get the properties when the user requests it (e. g. clicks on a specific item in your GUI).

For instance, if you request the spatial structure of a project, you might get something like this:

{
expressID: 100,
type: "IfcProject",
children: [{
expressID: 101,
type: "IfcSite",
children: [{
expressID: 102,
type: "IfcBuilding",
children:[
{
expressID: 103,
type: "IfcBuildingStorey",
children: {...}
},
{
expressID: 104,
type: "IfcBuildingStorey",
children: {...}
}
]
}]
}]
}

Get items by type#

πŸ‘©β€πŸ« Sometimes you'll want to retrieve all elements of a certain type (e.g. all IfcWall instances in the project). In these cases it is not useful to select elements by clicking on them or to get the spatial tree of the project.

🎸πŸͺ•πŸŽ» That's what the getAllItemsOfType method is for. Using it is really easy, and you can import the types directly from web-ifc. For instance, to get the properties of all the IfcSlab instances of the project, you can do the following:

import { IFCSLAB } from "web-ifc";
const ifc = ifcLoader.ifcManager;
const modelID = 0;
const slabsID = ifc.getAllItemsOfType(modelID, IFCSLAB);
slabsID.forEach(slabID => {
console.log(ifc.getItemProperties(0, slabID))
});

Next steps#

πŸŽ‰πŸŽ‰πŸŽ‰ Congratulations! You should now be able to traverse any IFC and extract the properties you are looking for.

πŸ±β€πŸ‘€ However, what can we do with these properties? One possible application can be found in the following tutorial, where we will see how to hide and isolate elements.