Fragments BIM Data Toolkit

repository·main·Indexed 41 days ago

https://github.com/thatopen/engine_fragment

An 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.

Tokens
16.8K
Snippets
45
Records
81
Agent score
50%

What's inside Fragments

  1. Overview of Fragments

    main
    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.
  2. The Fragments Data Format

    main

    The 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.
  3. Use the IfcImporter to generate Fragments

    main
    The easiest way to generate Fragments data is by using the built-in IfcImporter. This tool is designed to bring IFC (Industry Foundation Classes) data into the Fragments ecosystem and is compatible with both frontend and backend environments.
  4. Use SingleThreadedFragmentsModel for backend 3D data management

    main

    The SingleThreadedFragmentsModel is 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 ready property 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();
  5. Use the @thatopen/fragments core API

    main

    The @thatopen/fragments package 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";
  6. Understand the FragmentsModel class

    main

    The FragmentsModel is 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 (the object property) which represents the model in a Three.js scene.
    • State Management: It tracks loading states (isBusy), visibility (visibleItems), and attribute/relation changes (attrsChanges, relsChanges).
  7. Query user-defined indexes with VirtualIndexesController

    main

    The VirtualIndexesController provides a unified API to access user-defined indexes on a VirtualFragmentsModel. It automatically resolves data from two sources: the underlying FlatBuffer-backed ModelIndex (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).
  8. Manage BIM model edits with the Editor class

    main

    The Editor class 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 of EditRequest actions. 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) and selectRequest() 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
  9. Manage item relationships with ItemRelations

    main

    The ItemRelations class is used to manage relationships between items in a Fragments model. It extends the standard Map<string, Set<number>> structure, where the key is the relation name and the value is a Set of related item IDs.

    Key features include:

    • Change Tracking: If a tracker is provided, the class automatically records additions, deletions, and modifications to relations via the RelsChange type.
    • Guards: You can define a guard function to validate whether a specific relation key and its associated set of IDs are allowed to be set.
    • Asynchronous Item Retrieval: By providing an onItemsRequested handler, you can resolve relation IDs into actual Item objects asynchronously using getItems(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');
  10. Understand the IFC Splitter lifecycle stages

    main

    The IFCSplitter emits progress events during its execution. Monitoring these stages can help track the performance and progress of large file operations. The stages are represented by the IfcSplitterStage type:

    • 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.
  11. Understand attribute change events in Fragments

    main

    When monitoring changes to a model item, attribute updates are represented by the AttrsChange union type. This allows you to react to three specific types of changes:

    • deleted: The attribute was removed.
    • added: New attribute data was provided in the data field (a Record<string, any>).
    • modified: Existing attributes were updated. The added field contains new/updated data, deleted contains keys of removed attributes, and modified contains the updated values.
    // Example of an AttrsModifyChange structure
    const change: AttrsModifyChange = {
      type: "modified",
      added: { newProp: 123 },
      deleted: ["oldProp"],
      modified: { existingProp: "updated value" }
    };
  12. Perform raycasting and snapping operations

    main

    Fragments provides structured interfaces for raycasting to detect objects in the 3D scene:

    • RaycastData: The base input containing the camera, mouse position, and the dom canvas element.
    • SnappingRaycastData: Extends RaycastData with snappingClasses (e.g., SnappingClass.POINT, LINE, or FACE) to enable precision selection.
    • RaycastResult: The output of a successful hit, containing the localId, itemId, intersection point, normal, distance, and the object (THREE.Object3D) hit.
    • RectangleRaycastData: Used for area-based selection, requiring topLeft and bottomRight coordinates.