π§© The schema
πΈ Before you startβ
Before reading this page, keep in mind that we've built a whole JavaScript / TypeScript tech stack on top of Fragments to make the heavy lifting for you. If you just want to build BIM software with our libraries, you can happily treat Fragments as a black box without worrying about its internal structure. π¦
If you want to build your custom importers / exporters, want to build Fragments custom tools in another programming languages or are just curious about it, go ahead! π«‘
πΎ Introductionβ
Fragments is a format built on top of Flatbuffers, an open source libraries to easily create binary formats that are compatible with any programming language. π
The way flatbuffers work is simple:
-
βπ» We create a schema. It's just a text file containing description of the data structures inside your file. The syntax is very simple and similar to C. The extension is .fbs (stands for flatbuffers schema). You can out the fragments schema below.
-
π₯ You use that schema file and the flatbuffers library to automatically create an importer / exporter of that file in any programming language. This is covered in the flatbuffers docs. We already did it for TypeScript/JavaScript and included it in our libraries, so you don't have to worry about that one! π
Flatbuffers is extensible, so even if we make changes (evolutions) to the schema in the future, it will be backwards compatible! πβΆοΈπ¦
This is the schema file we created for fragments. Don't worry, we will cover it piece by piece in this page!
π Check it outβ
Before going in detail into each piece of the Fragments schema, let's check out a minimal Fragments file containing just a simple wall. In this example, you'll be able to see its data following the schema above, which might be useful for understanding how the schema works. You can even load your own IFC STEP files too to see their Fragments schema! π
Keep in this example we are serializing ALL the data of the file to a JSON just to display it in the screen, which is very, very inneficient, beating Fragments performance benefits. Don't expect this demo to have the same performance as a production Fragmetns app. Avoid loading huge IFCs here if you don't want to see your browser freeze. ππ»
You might want to revisit this example as a reference when trying to generate your own fragment files from IFC STEP or other data sources to have a reference of how it should look like: ππ»
βπ» General notesβ
There are some decisions we've taken when definining the Fragments data schema whose motivation might not be obvious at first sight. We will cover them here.
π± Data structuresβ
In some parts of the schema you might find data structured in a specific way. They are not arbitrary: it's the way to be able to open gigabytes of BIM data in seconds. Keep in mind that we designed Fragments for performance, so every indirection decision that you see follows that purpose. π
πππ String arraysβ
You will see that in various places we are using string arrays (categories, attributes, relations, etc). This might seem inefficient memory-wise at first sight, as when we have an array with multiple strings, each string occupies size, regardless of whether it's duplicated or not. π€
However, flatbuffers allow to define unique strings, automatically deduplicating its size. So this array is as efficient as an array with unique strings and an index to relate them. π±
π§© Modelβ
The Model is the main object and the entry point of all Fragment files. Each Fragments file has just one model, and it contains all the information of the file. It has the following structure (we'll cover it step by step): ππ»
table Model {
metadata: string; // JSON string for generic data about the file
guids: [string] (required); // An array of Global Unique Identifiers of items. Not all items may have a guid.
guids_items: [uint] (required); // An array that works as an indexation matching localIds indices with guids.
max_local_id: uint; // The smallest localID available when serializing. Used to know the next localID when adding a new item.
local_ids: [uint] (required); // File specific identification for each item.
categories: [string] (required); // An array of all item categories found in the file, stored as strings.
meshes: Meshes (required); // The object containing all explicit geometries of the model.
unique_attributes: [string]; // An array of unique item attributes in this model.
attributes: [Attribute]; // An array of items data stored as an array of arrays.
relation_names: [string]; // An array of unique relation names in this model.
relations: [Relation]; // An array of relations between different items stored as arrays of arrays.
relations_items: [int]; // An array that works as an indexation matching localIds indices with relations.
guid: string (required); // An global ID that identifies this model uniquely.
spatial_structure: SpatialStructure; // A tree representing the spatial relation between elements.
}
π Metadataβ
JSON string for generic data about the file itself. For example: {"schema":"IFC4"}". πππ
π¦ Guidsβ
An array of Global Unique Identifiers of items. Not all items may have a guid. They should be consistent across exports from authoring applications. πͺ¨