1

I followed the tutorials from the Forge Data Visualization extension documentation: https://forge.autodesk.com/en/docs/dataviz/v1/developers_guide/quickstart/ on a IFC file and everything seems to work except for the coloring of the rooms, which appear like in the image below, instead of being colored.

IFC room

I also tested on Revit files and the rooms are being colored properly, so this issue is specific to IFC files.

The question is what could be the cause for this behavior for the IFC files and how can I solve it?

Edit: The solution is in the comments of the accepted post.

AN00
  • 325
  • 4
  • 13
  • Sorry for the late reply. Could you consider provide a non-confidential reproducible case demonstrating this issue for our investigation and send it to `forge[DOT]help[AT]autodesk[DOT]com`? The non-confidential reproducible case contains a non-confidential reproducible IFC model and a minimum viewer app with codes to test this problem. – Eason Kang May 05 '21 at 04:58
  • Update my reply, please see below – Eason Kang May 05 '21 at 06:31

1 Answers1

1

Sorry for the late reply. After some search, I managed to reproduce a similar behavior to yours and found a solution to fix it.

In my case, the sensorType values I passed to DataVisualization#registerSurfaceShadingColors, DataVisualization#renderSurfaceShading, and devices' sensorType in my levelRoomMap manually created by this tutorial are not using the same character case. For example, Temperature vs temperature. After fixing the character case issue, my heatmap is redered as expected. Here is the snapshot:

DataViz heapmap on a IFC model

And here is my code snippet for your reference:

async function getBoxAsync(dbId) {
    return new Promise((resolve, reject) => {
        const tree = viewer.model.getInstanceTree();
        const frags = viewer.model.getFragmentList();
        tree.enumNodeFragments(dbId, function(fragid) {
            let bounds = new THREE.Box3();
            frags.getWorldBounds(fragid, bounds);
            return resolve(bounds);
        }, true);
    });
}

function getLevel(box) {
    const floors = viewer.getExtension("Autodesk.AEC.LevelsExtension").floorSelector.floorData;
    const currentElevation = box.min.z;

    if (currentElevation < floors[0].zMin) {
        return floors[0];
    } else if (currentElevation > floors[floors.length - 1].zMax) {
        return floors[floors.length - 1];
    } else {
        return floors.find(f => f.zMin <= currentElevation && f.zMax >= currentElevation );
    }
}

async function getPropAsync(dbId) {
    return new Promise((resolve, reject) => {
        viewer.getProperties(dbId, result => resolve(result));
    });
}

async function getRoomName(dbId) {
    const result = await getPropAsync(dbId);
    const nameProp = result.properties.find(p => p.attributeName === 'lcldrevit_parameter_Pset_ProductRequirements_tab:lcldrevit_parameter_Name(Pset_ProductRequirements)_PG_IFC');

    return nameProp.displayValue;
}

async function getRoomDbIds() {
    return new Promise((resolve, reject) => {
        viewer.search( 'Rooms', resolve, reject, ['lcldrevit_parameter_Pset_SpaceCommon_tab:lcldrevit_parameter_Category(Pset_SpaceCommon)_PG_IFC'])
    });
}

async function buildRoomMap() {
    const dbIds = await getRoomDbIds();
    const DataVizCore = Autodesk.DataVisualization.Core;
    let levelRoomsMap = new DataVizCore.LevelRoomsMap();


    for ( let i = dbIds.length - 1; i >= 0; i-- ) {
        const dbId = dbIds[i];
        const box = await getBoxAsync( dbId );
        const level = getLevel( box );
        const name = await getRoomName( dbId );

        let room = new DataVizCore.Room(
            dbId, //Room's DbId
            name,
            box
        );

        levelRoomsMap.addRoomToLevel(level.name, room);
    }

    return levelRoomsMap;
}

async function initHeatmap() {
    const DataVizCore = Autodesk.DataVisualization.Core;
    const dataVizExtn = viewer.getExtension('Autodesk.DataVisualization');
    const levelRoomsMap = await buildRoomMap();
    const devices = [];

    for(let lvl in levelRoomsMap) {
        const rooms = levelRoomsMap[lvl];
        for (let i = rooms.length - 1; i >= 0; i--) {
            const room = rooms[i];
            const center = room.bounds.center();
            const device = {
                id: `${room.name} Device`, // An ID to identify this device
                position: center, // World coordinates of this device
                sensorTypes: ["temperature"], // The types/properties this device exposes
            }

            devices.push(device);
            room.addDevice(device);
        }
    }

    const structureInfo = new DataVizCore.ModelStructureInfo(viewer.model);
    let shadingData = await structureInfo.generateSurfaceShadingData(devices, levelRoomsMap);

    await dataVizExtn.setupSurfaceShading(viewer.model, shadingData);

    // Set heatmap colors for temperature
    dataVizExtn.registerSurfaceShadingColors("temperature", [0x00ff00, 0xff0000]);

    function getSensorValue() {
        return Math.random(); // Your random function 
    }

    // Generate the heatmap graphics (do this one time, this is heavier)
    dataVizExtn.renderSurfaceShading(Object.keys(levelRoomsMap), "temperature", getSensorValue);
    // Do this as many times as you want (this is lightweight)
    dataVizExtn.updateSurfaceShading(getSensorValue);

    viewer.getExtension("Autodesk.AEC.LevelsExtension").floorSelector.selectFloor(0);
}

await initHeatmap();
Eason Kang
  • 6,155
  • 1
  • 7
  • 24
  • Hello, sorry for replying so late, I only had time to test this today. So I tried your suggestion, but changing the case of the sensorType didn't solve the problem. Then I thought to just try with your code. I adapted it and made some changes to the loading of the "Autodesk.AEC.LevelsExtension" and to the filter condition for room dbids and names, but it still "colors" the rooms in the same way as before. Could the ifc files I am using be the issue? Is the file you used public, so I could test it for reference? – AN00 May 12 '21 at 11:07
  • Maybe, but without looking into the file, I cannot say they are similar. Could you consider providing a non-confidential reproducible IFC model to `forge[dot]help[at]autodesk[dot]com`? I will catch you there, or you can test my model here: https://autode.sk/3uHFojc – Eason Kang May 14 '21 at 02:07
  • Unfortunately, I don't have a non-confidential IFC model to share, so I tried the one you provided and I encounter the same issue as with my models. I also noticed that when selecting the Model Browser, I have only 5531 elements as compared to 6110 from your image above. Also, my elements don't have this attribute that you used for filtering: "lcldrevit_parameter_Pset_SpaceCommon_tab:lcldrevit_parameter_Category(Pset_SpaceCommon)_PG_IFC". Could these 2 differences have anything to do with the problem? – AN00 May 17 '21 at 12:56
  • Which IFC pipeline are you using? If there is no `lcldrevit_parameter_Pset_SpaceCommon_tab:lcldrevit_parameter_Category(Pset_SpaceCommon)_PG_IFC` attribute in your model, you can try to replace it with the correct one where its value is Rooms while querying properties with `viewer.getProperties`. – Eason Kang May 17 '21 at 13:14
  • I am using the Revit pipeline. I tried to replace it as you said, but the corresponding fields to what you have, i.e., "Space_Pset_SpaceCommon" and "Space_Pset_ProductRequirements" are under "displayCategory", not "attributeName", and the filtering in viewer.search cannot be done with categories. I still tried with only the second filtering, but still no luck. – AN00 May 17 '21 at 13:40
  • Hi, I'm also using the modern (Revit) pipeline. I mean: you need to find out the attribute name that its value is `Rooms` in your model, then replace `lcldrevit_parameter_Pset_SpaceCommon_tab:lcldrevit_parameter_Category(Pset_SpaceCommon)_PG_IFC` in my code. – Eason Kang May 19 '21 at 09:31
  • The attribute name with the value `Rooms` is `LcIFCProperty:IFCString`, which is very common among the properties. That's why I tried with the categories that resembled the values you used. But I tried with this `LcIFCProperty:IFCString` too and still no difference. But since the program correctly identifies the rooms (it just doesn't color them) and from what you say it seems that having this exact `lcldrevit_parameter_Pset_SpaceCommon_tab:lcldrevit_parameter_Category(Pset_SpaceCommon)_PG_IFC` is not crucial, maybe the problem lies elsewhere. Could it be from the `surfaceShading` functions? – AN00 May 19 '21 at 12:51
  • 1
    In the end the issue was indeed with the IFC pipeline. I was using the old pipeline instead of the modern one. After changing that parameter during the conversion process and adding the `spaces: show` parameter, the model renders the colors as expected. Here is more detailed information about the parameters: https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/job-POST/ – AN00 Oct 13 '21 at 11:17