BIM collaboration format

This document describes how to load a BCF file into the HOOPS Web Viewer and query the data.

The BIM Collaboration Format (BCF) is an open file format that contains comments, screenshots and other data for IFC models to facilitate exchanging of data when collaborating on a model. The official documentation for BCF can be found here.

These BCF features are currently supported in the Web Viewer:

  • Loading a BCF via HTTP or ArrayBuffer.

  • Querying the data from a loaded BCF file.

There is currently no support for modifying the BCF data or exporting it. We are planning to add this in a future release.

The full source code for the samples below is available at the bottom of the page.

Loading a BCF file

To run the code examples in this section, start the server from the source package (click on start_server.bat in the quick_start directory).

Once the server is started, load the “arboleda” model in the hoops_web_viewer.html sample page in a browser at the following address: http://localhost:11180/hoops_web_viewer_sample.html?viewer=csr&instance=arboleda

An example BCF file can be downloaded here.

The <a href=”../api_ref/typedoc/classes/communicator.bcfmanager.html”>BCFManager</a> class facilitates loading, removing, and accessing data from a BCF file. To load a file via an HTTP request:

hwv.BCFManager.addBCFFromFile("example.bcf"); // Loads a BCF file named 'example.bcf' via HTTP request.

After a BCF is loaded, the <a href=”../api_ref/typedoc/interfaces/communicator.callbackmap.html#bcfloaded”>bcfLoaded</a> callback is triggered. The callback contains an id that can be used to query the data as well as the BCF filename.

    hwv.setCallbacks({
        // callback triggered after a BCF file has been loaded.
        bcfLoaded: (id, filename) => {
            let bcfData = hwv.BCFManager.getBCFData(id); // Gets the BCFData class for accessing the bcf topics.
        },
    });

How to query BCF data

Each BCF file can contain multiple topics. The topics contained in a BCF file can be accessed through the <a href=”../api_ref/typedoc/classes/communicator.bcfdata.html”>BCFData</a> class. Each topic has a unique id and contains images, camera viewpoints, markup, and comments. The <a href=”../api_ref/typedoc/classes/communicator.bcftopic.html”>BCFTopic</a> class provides access to this data via the <a href=”../api_ref/typedoc/classes/communicator.bcfmarkup.html”>BCFMarkup</a>, <a href=”../api_ref/typedoc/classes/communicator.bcfviewpoint.html”>BCFViewpoint</a>, and <a href=”../api_ref/typedoc/classes/communicator.bcfsnapshot.html”>BCFSnapshot</a> classes.

    let topics = bcfData.getTopics(); // Map associating BCF topic ids to BCF topic data.
    topics.forEach((topic, id) => {
        let markup = topic.getMarkup(); // BCFMarkup class
        let viewpoints = topic.getViewpointMap(); // A map associating viewpoint filenames with viewpoint data.
        let snapshots = topic.getSnapshotMap(); // A map associating snapshot filenames with snapshot data.
    });

The BCFMarkup class contains textual information about the topic. This includes the title, author, description, etc. For a list of all markup data to query see <a href=”../api_ref/typedoc/classes/communicator.bcfmarkup.html”>the webviewer API Reference.</a>

            let markup = topic.getMarkup();
            let title = markup.getTopicTitle();

The <a href=”../api_ref/typedoc/classes/communicator.bcfviewpoint.html”>BCFViewpoint</a> class contains information of components related to the topic, camera settings, and possible markup and clipping information. This class can be used to activate a view, which will change the camera, visibility, cutting planes, colors, and markup.

            let viewpoints = topic.getViewpointMap();

            // for demonstration purposes, iterate through the viewpoints and activate each one
            viewpoints.forEach((viewpoint, filename) => {
                setTimeout(function () {
                    viewpoint.activate();
                }, time);
                time += 1000;
            });

The <a href=”../api_ref/typedoc/classes/communicator.bcfsnapshot.html”>BCFSnapshot</a> class contains image data.

            let snapshots = topic.getSnapshotMap();
            snapshots.forEach((snapshot, filename) => {
                let url = snapshot.getUrl();
            });

Full source

The code snippets above are all combined together below:

let time = 0;
hwv.setCallbacks({
    bcfLoaded: (id, filename) => {
        let bcfData = hwv.BCFManager.getBCFData(id);

        let topics = bcfData.getTopics();
        topics.forEach((topic, id) => {
            //! [BCF_Markup]
            let markup = topic.getMarkup();
            let title = markup.getTopicTitle();
            //! [BCF_Markup]

            //! [BCF_Viewpoint]
            let viewpoints = topic.getViewpointMap();

            // for demonstration purposes, iterate through the viewpoints and activate each one
            viewpoints.forEach((viewpoint, filename) => {
                setTimeout(function () {
                    viewpoint.activate();
                }, time);
                time += 1000;
            });
            //! [BCF_Viewpoint]

            //! [BCF_Snapshot]
            let snapshots = topic.getSnapshotMap();
            snapshots.forEach((snapshot, filename) => {
                let url = snapshot.getUrl();
            });
            //! [BCF_Snapshot]
        });
    },
});

//! [Load_BCF]
hwv.BCFManager.addBCFFromFile("example.bcf"); // Loads a BCF file named 'example.bcf' via HTTP request.
//! [Load_BCF]

The above snippet loops through all BCF topics and activates a new viewpoint every second. This is done for illustrative purposes. Looping through BCF data may be useful for adding data to a user interface. Accessing a viewpoint via ids will be more common (for example, after a user interaction):

let bcfData = hwv.BCFManager.getBCFData(1);
let topic = bcfData.getTopic("5bf3a234-9fde-4c90-b761-117f6e67b584");
let viewpoint = topic.getViewpoint("viewpoint.bcfv");
viewpoint.activate();