Skip to content

MeasurementService

Manages 3D measurements (distance, angle, area, multi-point, bounding box, volume, circle, arc) using a descriptor-based type system. Owns measurement state, raycasting, and point interaction; rendering and label layout are owned by the per-type descriptors.

Access

Registered under the name "measurement" on ViewerCore.

ts
import { MeasurementService } from "@optellix/xviewr-sdk";

await viewer.ready();
const measurement = viewer.getService<MeasurementService>("measurement");

Public API

Lifecycle

  • activate(): void — turn on pointer-driven measurement placement.
  • deactivate(): void — turn off placement and detach listeners.
  • reset(): void — clear all measurements and pending points.

Configuration

  • getConfig(): MeasurementConfig
  • updateConfig(config: Partial<MeasurementConfig>): void
  • setMeasurementMode(mode: string): void"distance", "angle", "area", "multipoint", "aabb", "obb", "volume", "circle", "arc", or any registered descriptor name.
  • getMeasurementMode(): string

Points

  • addPoint(point: THREE.Vector3, hitMesh?: THREE.Mesh | null, hitFace?: number | null): void
  • setTemporaryPoint(point: THREE.Vector3 | null): void
  • getAllPoints(): THREE.Vector3[]
  • getCurrentPoints(): THREE.Vector3[]
  • getTemporaryPoint(): THREE.Vector3 | null
  • updatePointer(x: number, y: number): void — canvas-relative coords.
  • raycast(): THREE.Intersection | null

Measurements

  • createMeasurement(points: THREE.Vector3[], type?: string): Measurementtype defaults to "distance".
  • createMeasurementWithResult(points: THREE.Vector3[], type: string, result: MeasurementResultValue): Measurement
  • measureVolume(objects: THREE.Object3D[], options?: VolumeMeasurementOptions): Measurement | null
  • completeMeasurement(): Promise<void> — manual finalize for variable-point modes (area, multipoint).
  • getMeasurements(): Measurement[]
  • removeMeasurement(id: string): boolean
  • setMeasurementVisibility(id: string, visible: boolean): boolean
  • updateMeasurementPoint(measurementId: string, pointIndex: number, point: THREE.Vector3): boolean

Descriptors

  • registerDescriptor(descriptor: MeasurementTypeDescriptor): void
  • getDescriptor(name: string): MeasurementTypeDescriptor | undefined

Built-in descriptors exported from the SDK: distanceDescriptor, angleDescriptor, areaDescriptor, multiPointDescriptor, aabbDescriptor, obbDescriptor, volumeDescriptor, circleDescriptor, arcDescriptor. Bounding-box computers: AABBComputer, OBBComputer. Volume helpers: computeVolumeMeasurement(objects, options), normalizeVolumeOptions(options).

Events

EventPayload
measurement:activatednull
measurement:deactivatednull
measurement:config-updated{ config: MeasurementConfig }
measurement:point-added{ point, totalPoints }
measurement:temporary-point-changed{ point }
measurement:created{ measurement }
measurement:volume-created{ measurement, options }
measurement:removed{ measurement }
measurement:visibility-changed{ id, visible }
measurement:reset{ clearedMeasurements }
measurement:in-progress{ mode, pointCount, canComplete }
measurement:mode-changed{ mode, requiredPoints }
measurement:point-updated{ measurement }
measurement:hover-point{ measurementId, pointIndex } | null

Example

ts
const measurement = viewer.getService<MeasurementService>("measurement");

measurement.setMeasurementMode("distance");
measurement.activate();

viewer.eventBus.on("measurement:created", ({ measurement: m }) => {
  if (m.result.type === "distance") {
    console.log(`distance: ${m.result.distance.toFixed(2)}`);
  }
});

// Programmatic volume measurement on a selection.
const volume = measurement.measureVolume(selectedObjects, {
  method: "auto",
  voxelResolution: 64,
});

Configuration

ts
interface MeasurementConfig {
  textScalingFactor: number;       // label scale base
  raycastThreshold: number;
  sectionEnabled: boolean;         // limit raycast to contour objects
  contourObjects: THREE.Object3D | THREE.Object3D[] | null;
  selectableOnly: boolean;         // only raycast userData.isSelectable
  measurementMode: string;
  autoCreateMeasurements: boolean; // finalize when requiredPoints reached
  showComponents: boolean;         // render dx/dy/dz legs on 2-point distance
  surfaceSnap: boolean;            // drape distance/multipoint along mesh
  volumeMeasurement: VolumeMeasurementOptions;
}

interface VolumeMeasurementOptions {
  method?: "auto" | "tetrahedron" | "voxel";
  voxelResolution?: number;        // default 48
  voxelMaxCells?: number;          // default 250000
  voxelSampleMode?: "center" | "corners";
  voxelAxisVotes?: boolean;        // 3-axis parity voting
  watertightTolerance?: number;    // default 1e-5
}

Result types

MeasurementResultValue is the union of DistanceResult, AngleResult, AreaResult, MultiPointResult, BoundingBoxResult, VolumeResult, CircleResult, ArcResult. Each carries a type discriminator matching the descriptor name.

XViewr SDK and xConvert CLI documentation.