Fragments BIM Data Toolkit
repository·main·Indexed 41 days ago
https://github.com/thatopen/engine_fragmentAn open-source library and binary data format for storing, displaying, and editing massive BIM (Building Information Modeling) datasets. Built with FlatBuffers for efficient serialization and Three.js for high-performance 3D visualization, it supports millions of elements with features like raycasting, filtering, and transactional editing via the Editor class. Version 3.4.0.
What's inside Fragments
- Fragments is an open-source library and format designed for storing, displaying, navigating, and editing massive amounts of BIM (Building Information Modeling) data with high efficiency across any device. It provides a high-performance 3D viewer built on Three.js capable of handling millions of elements, supporting features like highlighting, filtering, raycasting, and snapping.
The Fragments Data Format
mainThe Fragments format is an open BIM format optimized for large datasets. It is binary, compact, and free/open-source. It supports geometries, properties, and relationships.
Technical Implementation
- Serialization: Built using Google's FlatBuffers, allowing for efficient cross-platform serialization. Developers can implement their own importers/exporters in any language by following the FlatBuffers specification.
- Schema: The data structure is defined by a FlatBuffers schema. You can find the schema definition in the repository to understand the supported data types.
Use the IfcImporter to generate Fragments
mainThe easiest way to generate Fragments data is by using the built-inIfcImporter. This tool is designed to bring IFC (Industry Foundation Classes) data into the Fragments ecosystem and is compatible with both frontend and backend environments.Use SingleThreadedFragmentsModel for backend 3D data management
mainThe
SingleThreadedFragmentsModelis the primary class for managing 3D model data in a single-threaded environment (such as Node.js). It is optimized for data querying and manipulation rather than 3D visualization.Key Characteristics:
- Asynchronous Setup: The constructor initiates an asynchronous setup process. You must await the
readyproperty before attempting to access model data. - Data-Centric: It provides extensive APIs for querying geometry, metadata, transforms, materials, and custom indices, but does not contain 3D rendering logic.
- Edit Capabilities: It supports an edit pipeline (
edit,save,undo,redo) that allows you to apply changes and generate delta buffers without needing a full 3D engine/scene.
import { SingleThreadedFragmentsModel } from '@thatopen/fragments'; // modelData is a Uint8Array (raw or deflated) const model = new SingleThreadedFragmentsModel('my-model-id', modelData); await model.ready; // Now you can safely query data const metadata = model.getMetadata(); const items = model.getItemsIds();- Asynchronous Setup: The constructor initiates an asynchronous setup process. You must await the
Use the @thatopen/fragments core API
mainThe
@thatopen/fragmentspackage provides the core components for working with 3D fragments, including geometry engines, IFC parsing utilities, schema definitions, and importers. The library is organized into several functional modules:- GeometryEngine: Core logic for handling 3D geometry.
- Importers: Tools for bringing external data into the fragment ecosystem.
- FragmentsModels: Data models representing fragment structures.
- Schema: Type definitions and structural schemas.
- Utils: Specialized utilities for IFC processing, including streaming and splitting.
To use the library, import the required modules from the main entrypoint.
import { GeometryEngine, Importers, FragmentsModels, Schema, // Utils are available via specialized entrypoints } from "@thatopen/fragments";Understand the FragmentsModel class
mainThe
FragmentsModelis the central class for managing a 3D model loaded from a fragments file. It orchestrates specialized managers to handle geometry, materials, visibility, highlighting, sections, and more.Key characteristics:
- Orchestration: It acts as a facade for various managers (e.g.,
MeshManager,DataManager,VisibilityManager). - Asynchronous Data: Model data is processed asynchronously, often across multiple threads via
FragmentsConnection. - Three.js Integration: It maintains a
THREE.Object3D(theobjectproperty) which represents the model in a Three.js scene. - State Management: It tracks loading states (
isBusy), visibility (visibleItems), and attribute/relation changes (attrsChanges,relsChanges).
- Orchestration: It acts as a facade for various managers (e.g.,
Query user-defined indexes with VirtualIndexesController
mainThe
VirtualIndexesControllerprovides a unified API to access user-defined indexes on aVirtualFragmentsModel. It automatically resolves data from two sources: the underlying FlatBuffer-backedModelIndex(stored data) and pending edit requests (CREATE, UPDATE, or DELETE operations that shadow the stored data).Key features:
- Unified API: Access data regardless of whether it is stored or currently being edited in a pending request.
- Performance: Forward lookups are $O(1)$ after an initial $O(N)$ build of a key map. Inverse lookups are $O(N)$ on the first call and $O(1)$ thereafter.
- Automatic Synchronization: The controller rebuilds its internal overlay whenever the model's request list changes (e.g., during push, undo, or redo).
Manage BIM model edits with the Editor class
mainThe
Editorclass is the primary interface for performing transactional edits on Fragments models. It allows you to perform a series of actions, manage undo/redo history, and persist changes to the model.Key workflows include:
- Performing Edits: Use
edit()to apply a batch ofEditRequestactions. This is an asynchronous operation that returns the IDs of the modified elements. - Saving Changes: Use
save()to commit pending edits to the model, similar to saving changes in a BIM application. - History Management: Use
getModelRequests()to retrieve the list of edit requests (useful for building undo/redo menus) andselectRequest()to jump to a specific state in the model's history. - Resetting: Use
reset()to discard all pending edits for a specific model.
// Example of performing an edit and saving it await editor.edit(modelId, [/* EditRequest array */], { removeRedo: true }); await editor.save(modelId); // Example of managing history const requests = await editor.getModelRequests(modelId); await editor.selectRequest(modelId, 0); // Revert to the state after the first request- Performing Edits: Use
Manage item relationships with ItemRelations
mainThe
ItemRelationsclass is used to manage relationships between items in a Fragments model. It extends the standardMap<string, Set<number>>structure, where the key is the relation name and the value is aSetof related item IDs.Key features include:
- Change Tracking: If a
trackeris provided, the class automatically records additions, deletions, and modifications to relations via theRelsChangetype. - Guards: You can define a
guardfunction to validate whether a specific relation key and its associated set of IDs are allowed to be set. - Asynchronous Item Retrieval: By providing an
onItemsRequestedhandler, you can resolve relation IDs into actualItemobjects asynchronously usinggetItems(key).
import { ItemRelations } from './path-to-item-relations'; // Initialize with a local ID for the item owning these relations const relations = new ItemRelations(123); // Add an item to a specific relation relations.add('children', 456); // Set a whole new set of related items relations.set('parents', new Set([789, 101])); // Remove an item from a relation relations.remove('children', 456); // Delete an entire relation relations.delete('parents');- Change Tracking: If a
Understand the IFC Splitter lifecycle stages
mainThe
IFCSplitteremits progress events during its execution. Monitoring these stages can help track the performance and progress of large file operations. The stages are represented by theIfcSplitterStagetype:relations: Occurs during the collection of relational dependencies.resolve: Occurs during the resolution of styles and dependencies.write: Occurs during the final writing of the split files to disk.
Understand attribute change events in Fragments
mainWhen monitoring changes to a model item, attribute updates are represented by the
AttrsChangeunion type. This allows you to react to three specific types of changes:deleted: The attribute was removed.added: New attribute data was provided in thedatafield (aRecord<string, any>).modified: Existing attributes were updated. Theaddedfield contains new/updated data,deletedcontains keys of removed attributes, andmodifiedcontains the updated values.
// Example of an AttrsModifyChange structure const change: AttrsModifyChange = { type: "modified", added: { newProp: 123 }, deleted: ["oldProp"], modified: { existingProp: "updated value" } };Perform raycasting and snapping operations
mainFragments provides structured interfaces for raycasting to detect objects in the 3D scene:
RaycastData: The base input containing thecamera,mouseposition, and thedomcanvas element.SnappingRaycastData: ExtendsRaycastDatawithsnappingClasses(e.g.,SnappingClass.POINT,LINE, orFACE) to enable precision selection.RaycastResult: The output of a successful hit, containing thelocalId,itemId, intersectionpoint,normal,distance, and theobject(THREE.Object3D) hit.RectangleRaycastData: Used for area-based selection, requiringtopLeftandbottomRightcoordinates.