How to get IFC property data from selected mesh object

Continue developing your own viewer and use this simple script to show the IFC property data.

Explore the benefits of the Tridify BIM Publishing Service and start a FREE 14-day trial (no credit card required)

Prerequisite

Before you start with this tutorial you need to set up the Tridify API samples. Check our tutorial How to develop your first BIM viewer.

Get IFC property data

To get the IFC property data you need a specific hash code.

Go to your Project, select the Published links tab and click Show link. Copy the Share key.

Insert the following URL and your Share key to your web browser:

http://ws.tridify.com/api/v1/published-links/SHAREKEY

 

Open the browser developer tools and select Network tab. In the Name column select your Share key and in the Preview tab navigate through hierarchy to locate the Hash code.

 

Get_property_data_1

You need a simple script to show the IFC property data. First pick Objects script, check if an object is hit and then that the data of the object is printed into the console.

 

scene.onPointerUp = () => {
const pickResult = scene.pick(scene.pointerX, scene.pointerY);

if(pickResult && pickResult.pickedMesh) getMeshInfo(pickResult, ifcData);

 

The Tridify API loads meshes as a group of same IfcType and assigns mesh with referred type. Abstract meshes has property IfcType which makes it easy to get the type.

 

// Here we open the object
function getIdsOfRoofChildren(ifcObject: object, id: string, accumulator: string[] = []) {
// Here we validate if object has right property and value and save it to accumulator array
if (ifcObject && ifcObject.hasOwnProperty('@id') && ifcObject.hasOwnProperty('@Name') && ifcObject['@id'].includes(id)) {
accumulator.push(ifcObject['@Name']);

}

// Here we check if the object has child objects
const childObjects = Object.values(ifcObject).filter(x => typeof x === 'object');
// Here we iterate found child objects and already found properties
childObjects.forEach(x => getIdsOfRoofChildren(x, id, accumulator));
return accumulator;
}

 

Set up the Tridify API samples and insert your port address and the hash code to your browser:

http://localhost:8080/index.html#HASH

 

Click on any object in your BIM model while the browser console is open; the IfcType and the name of the picked object will be printed to the console.

 

Get_property_data_2

 

Full index.ts script:

import {
   Engine,
  Scene,
  SceneLoader,
  ArcRotateCamera,
  PickingInfo,


} from '@babylonjs/core';

import * as Utilities from '@tridify/babylonjs-utilities';


const run = async () => {


   const canvas: HTMLCanvasElement = <HTMLCanvasElement>document.getElementById('renderCanvas');

  // Create engine
  const engine: Engine = new Engine(canvas, true, {
      // Options
  });

   // Minimal hash routing. Use the hash from conversion service to open different models.
  const conversionID: string = document.location.hash ? window.location.hash.replace("#", "") : null;  

   // Events
  window.addEventListener('resize', () => engine.resize());

   //initialize ifc data
  let ifcData;

   // Load Scene
  const scene = await SceneLoader.LoadAsync('./scene/', 'scene.babylon', engine).then(async (scene: Scene) => {

    // Load model
    const hashes = await Utilities.loadModel(scene, conversionID);

     // This load Ifc data of the model, you can also use it to get parts you like. loadIfc(conversionID, "decomposition")
    ifcData = await Utilities.loadIfc(hashes);

     // Create environment
    scene.createDefaultEnvironment({
      createGround: false,
      createSkybox: false,
    })

     // Attach camera
    const camera: ArcRotateCamera = Utilities.createOrbitCamera(scene);
    scene.activeCamera = camera;
    scene.activeCamera.attachControl(canvas, true);

     // Frame scene so that models are properly in view
    Utilities.frameScene(scene, camera);

    return scene;  

  });

   scene.onPointerUp = () => {
    const pickResult = scene.pick(scene.pointerX, scene.pointerY);
    if(pickResult && pickResult.pickedMesh) getMeshInfo(pickResult, ifcData); 
   }

   // Run render loop
  engine.runRenderLoop(() => {
    scene.render();
  });
}

run();

function getMeshInfo(pickInfo: PickingInfo, ifcData) {
  //we need to slice _primitive part off if object_id has it
  const objectId = pickInfo.pickedMesh.id.slice(0,22)
  //If user has more than one model in scene
  const listOfObjectNames : string[] = ifcData.map(x => getIdsOfRoofChildren(x.ifc.decomposition, objectId));
  console.log("data: ",listOfObjectNames);
}

function getIdsOfRoofChildren(ifcObject: object, id: string, accumulator: string[] = []) {
  if (ifcObject && ifcObject.hasOwnProperty('@id') && ifcObject.hasOwnProperty('@Name') && ifcObject['@id'].includes(id)) {
    accumulator.push(ifcObject['@Name']);
   
     const types = Object.keys(ifcObject).filter(x => x.includes("Ifc") && x.includes("Type"));
    console.log("Types:: ", types);
  }
  const childObjects = Object.values(ifcObject).filter(x => typeof x === 'object');
  childObjects.forEach(x => getIdsOfRoofChildren(x, id, accumulator));
   return accumulator;

}

 

Detailed information about the Tridify API can be found in our Swagger documentation.