Skip to main content

BIM Viewer Tools

The BIM viewer toolbar is built from a list of Tool objects defined in useBimToolbarTools(). Each tool is a React component rendered in a ToolbarSubmenu and activated/deactivated via ToolsContext.

Source: @collabdt/core/components/viewers/bim/src/tools/

Available Tools

Tool IDComponentDescription
bim-clippingClippingToolAdd and remove section planes to cut through the model
bim-camera-fitFitCameraToolFit camera to the loaded model
bim-addAddToBimAdd files, comments, sensors, IFC/BCF/CAD/IDS content
bim-dimensionsMeasureBimToolMeasure length, area, volume and angle in the 3D model
bim-inspectInspectBimToolInspect element properties by clicking
bim-shareShareBimToolShare a link to the current camera position

ClippingTool

Adds section planes to the Three.js scene using @thatopen/components-front. Each plane is rendered with a LineMaterial outline.

ClippingTool is the toolbar UI only. The planes themselves are owned by the ClippingPlanes component (tools/ClippingTool/ClippingPlanes.ts), which wires the Clipper and the cut style once per world and keeps an undo history of every plane change.

Behaviour

  • Activates via ToolsContext dispatch SET-TOOL with tool.id.
  • Sets the viewer cursor to a crosshair while active, and shows the instructions in a persistent toast.
  • On double-click, a clipping plane is added on the front-most face under the cursor. The pick is restricted to model geometry so helper meshes and already-sectioned geometry cannot be picked through.
  • Enter finishes and keeps the planes. Escape clears every plane and exits. Backspace or Delete removes the plane under the cursor.
  • Leaving the mode hides the translucent squares but keeps the arrow gizmos, so an existing section can still be dragged.
  • CTRL+Z / CTRL+Y step through adding, deleting and moving planes. The shortcut is bound in BimViewer, which routes it to whichever of the appearance and clipping histories changed last.
  • Deactivates when another tool is selected — planes persist until explicitly removed.

Dependencies

@thatopen/components (OBC), @thatopen/components-front (OBF), three.js, sonner


AddToBim

Submenu with sub-tools for attaching content to the BIM model:

Sub-toolDescription
bim-add-commentPin a comment to a 3D position
bim-add-fileAttach a file at a 3D position
bim-add-sensorPlace a sensor in the model
bim-add-ifcLoad an additional IFC model
bim-add-bcfImport a BCF topic file
bim-add-cadImport a DXF/CAD file via AddDxf
bim-add-idsImport an IDS validation file

Position is set by clicking in the 3D view, captured as x, y, z coordinates relative to the model.


MeasureBimTool

Measures length, area, volume and angle. The submenu offers five modes, all backed by @thatopen/components-front measurement components rather than hand-rolled raycasting:

ModeComponentInteraction
FreeOBF.LengthMeasurement (mode: 'free')Double-click two points
EdgeOBF.LengthMeasurement (mode: 'edge')Double-click an edge; the measurement spans the whole edge
AreaOBF.AreaMeasurement (mode: 'free')Double-click each corner, then Enter to close the polygon
VolumeOBF.VolumeMeasurementDouble-click each element to add it, then Enter to total the volume
AngleOBF.AngleMeasurementDouble-click three points: start, vertex, end

Delete or Backspace removes the measurement under the cursor. Escape cancels the in-progress shape and leaves measurement mode. Clear removes every measurement of every kind.

BimMeasurementManager

All four components are owned by a single OBC.Component, BimMeasurements/BimMeasurementManager.ts. Activation is exclusive: each measurement component binds its own pointer listeners when enabled, so leaving two enabled at once would make one double-click feed both.

The manager also handles three things the raw components do not:

  • World binding is resolved per activation, not cached in the constructor. Components.get() caches, and the toolbar calls it on its first render — which can land before CurrentWorld.world is published. A constructor snapshot would cache null for the rest of the session.
  • Ordering. Measurement.enabled's setter calls setEvents(), which throws when world is null, so the world and all configuration are applied before enabled = true.
  • Hoverer coordination. The Hoverer is disabled while length, area or angle is active. It is deliberately left alone for volume, because VolumeMeasurement saves, force-enables and restores it itself in order to highlight the items being picked.

Measurements are held in each component's own list and persist across tool switches until Clear is used or the viewer is disposed.

Snap tuning

The library defaults every measurement component to all three snap classes (POINT, LINE, FACE) and to MeasurementPickMode.MOUSE_MOVE. All three classes compete on each pick and the nearest wins, so the snap target flips between three different answers as the cursor moves. The defaults here narrow that:

SettingLibrary defaultCDT default
snappings[LINE, POINT, FACE]One or two classes per mode — [LINE] for edge length, [FACE] for face area, [POINT, LINE] otherwise, undefined for volume
pickModeMOUSE_MOVEMOUSE_STOP — one GPU pick per intentional cursor stop rather than one per animation frame
delay300 ms120 ms
pickerSize6 px10 px
SnapResolvers maxDistance1 m0.5 m
stickyRadiusPx12 px16 px
note

Measurement.snapDistance looks like the snap-range knob but has no effect in components-front 3.4.3 — its setter writes GraphicVertexPicker.maxDistance, which GraphicVertexPicker.get() never reads. The live knob is components.get(OBC.SnapResolvers).get().maxDistance.

Colour, units, decimal places, snap range and marker size are user-editable under Measurements in the BIM sidebar's Settings tab. Values are held on the manager, so they last as long as the viewer's Components instance.


InspectBimTool

Activates element inspection mode. On click, highlights the selected element and reads its IFC properties. Supports line and area inspect types.

Behaviour

  • Sets cursor to a pointer while active.
  • Attaches a click listener to the viewer container's canvas element.
  • Removes the listener on deactivate.

FitCameraTool

Fits the Three.js camera to the bounding box of the loaded model. Single-action tool — no persistent active state.


ShareBimTool

Generates a shareable URL encoding the current camera position. Reads from BimContext.


Activating a tool

Tools are activated and deactivated through ToolsContext:

const { dispatch } = useContext(ToolsContext)

// Activate
dispatch({ type: 'SET-TOOL', payload: { currentToolId: 'bim-clipping' } })

// Deactivate
dispatch({ type: 'SET-TOOL', payload: { currentToolId: null } })

Only one tool is active at a time. When a new tool is activated, the previous tool's component is responsible for cleaning up (removing event listeners, resetting cursor, etc.).

Key Files

FileRole
@collabdt/core/components/viewers/bim/src/tools/bimToolbar.tsTool list definition
@collabdt/core/components/viewers/bim/src/tools/ClippingTool/ClippingTool.tsxClipping plane tool
@collabdt/core/components/viewers/bim/src/tools/AddToBim/index.tsxAdd content sub-menu
@collabdt/core/components/viewers/bim/src/tools/InspectBimTool.tsxElement inspection
@collabdt/core/components/viewers/bim/src/tools/measureBimTool.tsxMeasurement submenu and hint card
@collabdt/core/components/viewers/bim/src/BimMeasurements/BimMeasurementManager.tsOwns the four measurement components; exclusive activation, world binding, event wiring
@collabdt/core/components/viewers/bim/src/BimMeasurements/measurementSettings.tsSnap tuning, units and the per-mode snap-class table
@collabdt/core/components/viewers/bim/src/BimSidebar/src/SettingsTab/src/MeasurementSettings.tsxColour, units, precision, snap range and marker size controls
@collabdt/core/components/viewers/bim/src/tools/FitCameraTool.tsxFit camera
@collabdt/core/components/viewers/bim/src/tools/shareBimTool.tsxShare camera position

Permissions