Skip to content

Dimension lines (Measuring Tape)

Draw, read, delete and hide the measurement annotations the Measuring Tape tool leaves in the scene. Accessed via snaptrude.design.dimensions.

A dimension line is a scene object, not a property: two endpoints anchored to the geometry they were measured on, an offset that pushes the drawn line clear of the span, and a label showing the distance in the project's units. Because the endpoints are anchored, the line follows its host when the host is moved, edited or resized, and it goes away with the host when the host is deleted. Dimension lines are storey-scoped, draw in both plan and 3D, and are carried into Present-mode sheets — style them there with presentation.placedViews.updateStyles(shapeId, "Dimension", …).

This namespace is not an entity's width/height/depth. For those see design.windows.getDimensions, design.query.measure, or the dimensions option on design.create.staircase.

Targets are DimensionHandles — the dimension line's own stable id, distinct from a ComponentHandle. Get one from create, or from a record's id field via list.

Units

Every length here — the offset option and a record's length — is in Snaptrude's internal storage unit ("babylon" in core.units.convert): 1 unit = 10 in = 0.254 m. Convert before you pass a real-world number in, and after you read one out:

ts
const oneMetre = await snaptrude.core.units.convert(1, "meters", "babylon"); // 3.937

The record's label is the text drawn on the canvas, already formatted in the project's display units — a bare number for metric/inch projects, 27' 7" style for feet-inches. length is always the straight-line distance between from and to; for a skewed span (x, y and z all differ) the drawn line is the plan projection, so label can read a shorter, horizontal distance.

The anchor is required

create takes a component to anchor to, and there is no free-point form: a dimension drawn on empty canvas anchors to a scene helper mesh whose id is not stable across reloads, so it comes back dropped, mislabelled or hidden when the project is reopened — the host rejects a non-component anchor rather than write a record that silently disappears. Pass options.anchorTo when the second endpoint belongs to a different component.

Measuring Tape dimensions the user drew on empty canvas still exist in the project; list reports them with anchor: null (and they are not proposal-scoped).

Offset convention

options.offset is a signed distance in Snaptrude units: positive pushes the drawn line to the left of the fromto direction in plan (cross(up, direction)), negative to the right. It defaults to 3.937 (1 m). Plugin-created dimensions always use the "across" placement mode — the tape tool's perpendicular placement, which re-perpendicularises itself when the host geometry is edited. Axis-locked placements ("x" / "y" / "z") are read-only for now: list reports them for user-drawn dimensions, but you cannot ask for one.

Undo, autosave and collaboration

create, delete, hide and show each commit through the engine's command manager: one call is one undo entry (a whole batch is a single entry), is autosaved, and replays to everyone else in the session. Undo with core.history.undo or Ctrl/Cmd+Z — both restore the same state.

Hidden vs visible

isHidden is the user Hide flag, the one hide and show toggle. isVisible is whether the line is actually drawn. They are not inverses: a dimension whose anchor component is itself hidden stays off screen with isHidden: false and isVisible: false, so show is not a promise that anything appears. Filter on isHidden to find what you hid; read isVisible to know what a user can see.

Types

PluginDimensionPlacement

How a dimension line's drawn offset is constrained. "across" is perpendicular to the span (the tape tool's default, and what every plugin-created dimension uses); "x" / "y" / "z" lock the offset to that world axis; "none" is a plain world-space offset with no mode recorded.

"across" | "x" | "y" | "z" | "none"

PluginDimensionLine

One dimension line. Lengths are in Snaptrude units.

PropertyTypeDescription
idDimensionHandleThe dimension line's handle
from{ x, y, z }Live world position of the first endpoint
to{ x, y, z }Live world position of the second endpoint
lengthnumberStraight-line distance from from to to, in Snaptrude units
labelstringThe text drawn on the canvas, in the project's display units (27' 7" style for feet-inches)
offset{ x, y, z }World vector from the measured span to the drawn line
placementPluginDimensionPlacementHow that offset is constrained
anchorComponentHandle | nullComponent the first endpoint is anchored to; null for a user-drawn dimension on a non-component host mesh
anchorToComponentHandle | nullComponent the second endpoint is anchored to; equals anchor when both endpoints share a host
storeynumberStorey the dimension belongs to
buildingIdstring | nullBuilding it belongs to, when it has one
isHiddenbooleanThe user Hide flag — what hide / show toggle
isVisiblebooleanWhether it is actually drawn — false when hidden, and also when an anchor component is hidden
isPlanProjectedbooleanWhether it is drawn flattened onto the storey base (2D Measuring Tape dimensions are; plugin-created ones are not)

PluginDimensionsChangeResult

Shared result of the batch mutations (delete / hide / show) — the dimensions actually affected. hide / show skip dimensions already in the target state, so affected can be shorter than the input; delete echoes the whole batch. Errors throw (the RPC rejects); there is no Result<> wrapper in the SDK.

PropertyTypeDescription
affectedDimensionHandle[]The dimension lines the call changed

Functions

create(from, to, anchor, options?)

Draw one dimension line between two world points, anchored to a component — the scriptable Measuring Tape. Undoable.

The dimension is created flat (never plan-projected), so the same call produces the same record whatever the current camera; it still draws in plan.

  • Parameters:
    • from: Vec3Handle — World-space first endpoint
    • to: Vec3Handle — World-space second endpoint
    • anchor: ComponentHandle — Component the first endpoint anchors to (required — see The anchor is required)
    • options.anchorTo: ComponentHandle — Component for the second endpoint (default: anchor)
    • options.offset: number — Signed perpendicular offset in Snaptrude units, positive = left of the fromto direction in plan (default 3.937 = 1 m)
  • Returns: DimensionHandle — the new dimension line
  • Throws: VALIDATION for malformed arguments or a degenerate span (from and to closer than the engine's minimum); HANDLE_INVALID for an unknown anchor / anchorTo; PRECONDITION_FAILED when the anchor is outside the active proposal or the editor is not mounted; or if plugin writes are disabled
ts
// Dimension every wall on level 2, along its centreline.
const { design, core } = snaptrude;
const v = core.math.vec3;
const curve = core.geom.query.curve;

for (const wall of await design.query.listWalls({ storeys: [2] })) {
  const centerline = await design.query.geometry.getCenterline(wall);
  if (!centerline) continue;
  const a = await curve.getStartPoint(centerline);
  const b = await curve.getEndPoint(centerline);
  await design.dimensions.create(await v.new(a.x, a.y, a.z), await v.new(b.x, b.y, b.z), wall);
}

list(options?)

List the dimension lines in the project as full records. Filters combine with AND; omit them all to list everything.

  • Parameters:
    • options.storeys: number[] — Only dimensions on these storey numbers
    • options.anchors: ComponentHandle[] — Only dimensions anchored to these components (either endpoint; an instance's source component matches too)
    • options.isHidden: boolean — Only dimensions whose user Hide flag equals this
  • Returns: PluginDimensionLine[] — the matching records ([] when nothing matches)
  • Throws: VALIDATION for malformed filters; HANDLE_INVALID for an unknown handle in anchors
ts
// Flag every dimension shorter than 600 mm.
const min = await snaptrude.core.units.convert(600, "millimeters", "babylon");
const short = (await snaptrude.design.dimensions.list()).filter((d) => d.length < min);
console.log(short.map((d) => `${d.label} on storey ${d.storey}`));

get(dimension)

Read one dimension line by handle. Returns null — rather than throwing — when the dimension no longer exists, so a handle kept across a delete or an undo can be polled safely.

  • Parameters:
    • dimension: DimensionHandle — The dimension line to read
  • Returns: PluginDimensionLine | null — the record, or null if it is gone
  • Throws: VALIDATION if dimension is not a non-empty id string
ts
const dim = await snaptrude.design.dimensions.get(handle);
if (dim) console.log(dim.label, dim.length, dim.storey);

delete(dimensions)

Delete dimension lines — the same hard removal as selecting them and pressing Delete. Undoable as a single entry for the whole batch. Deleted handles are stale afterwards: get returns null for them and the other mutators throw HANDLE_INVALID.

  • Parameters:
    • dimensions: DimensionHandle[] — The dimension lines to delete (at least one — an empty array is a caller error, not a no-op)
  • Returns: PluginDimensionsChangeResult{ affected }, the deleted handles
  • Throws: VALIDATION for an empty or malformed array; HANDLE_INVALID if any handle is unknown (the whole call rejects before anything is deleted); PRECONDITION_FAILED if any dimension's anchor is outside the active proposal; or if plugin writes are disabled
ts
// Clear the dimensions on one wall.
const dims = snaptrude.design.dimensions;
const onWall = await dims.list({ anchors: [wall] });
if (onWall.length > 0) await dims.delete(onWall.map((d) => d.id));

hide(dimensions)

Hide dimension lines from the viewport — the same as the right-click Hide action (it sets the user Hide flag, isHidden). Undoable. Already-hidden dimensions are skipped and are not reported in affected.

  • Parameters:
    • dimensions: DimensionHandle[] — The dimension lines to hide
  • Returns: PluginDimensionsChangeResult{ affected }, the dimensions actually hidden (can be shorter than the input)
  • Throws: VALIDATION for a malformed array; HANDLE_INVALID if any handle is unknown; PRECONDITION_FAILED if any dimension's anchor is outside the active proposal; or if plugin writes are disabled
ts
// Hide the dimensions on level 3 while presenting.
const dims = snaptrude.design.dimensions;
const onLevel3 = await dims.list({ storeys: [3] });
const { affected } = await dims.hide(onLevel3.map((d) => d.id));
console.log(`Hid ${affected.length} dimension lines`);

show(dimensions)

Reveal hidden dimension lines — clear the user Hide flag, the inverse of hide. Undoable. Already-visible dimensions are skipped and are not reported in affected. Clearing the flag does not guarantee the line is on screen: see Hidden vs visible.

  • Parameters:
    • dimensions: DimensionHandle[] — The dimension lines to reveal
  • Returns: PluginDimensionsChangeResult{ affected }, the dimensions actually revealed (can be shorter than the input)
  • Throws: VALIDATION for a malformed array; HANDLE_INVALID if any handle is unknown; PRECONDITION_FAILED if any dimension's anchor is outside the active proposal; or if plugin writes are disabled
ts
// Bring back everything you hid.
const dims = snaptrude.design.dimensions;
const hidden = await dims.list({ isHidden: true });
await dims.show(hidden.map((d) => d.id));

Not possible

The product itself does not offer these, or they are deferred to a later release:

Not possibleWhy / what to do instead
Typed / overridden valuesA dimension always shows the measured distance — the Measuring Tape's value box is read-only in the product too. Annotate a custom string with presentation.annotate.text instead.
Free-point (unanchored) creationanchor is required; unanchored dimensions do not survive a reload. Deferred until the loaders keep them.
Axis-locked placement (x/y/z)create always uses "across". Readable on existing dimensions via placement; requestable in a later release.
Re-offsetting an existing lineNo update yet — delete and re-create with a different offset. (The user's Move tool can still nudge one.)
Moving an endpointEndpoints are stored relative to their anchors; re-create the dimension instead.
Dimensions in the selection APIdesign.selection.setByFilter({ types: ["dimensionLine"] }) does select them in the viewport, but affected omits them (they are not components), and selection.get() never returns a DimensionHandle.
Angle measurementsThe Angle Measurement tool persists nothing, so there is nothing to read or create.
  • design.transform — moving, rotating or mirroring a host carries its anchored dimension lines along.
  • design.update — wall / slab / roof / storey edits re-derive the dimension lines anchored to them.
  • presentation.placedViewsupdateStyles(shapeId, "Dimension", …) styles (or hides) dimension lines on a Present sheet.

Errors

Failed calls reject with a typed PluginError — see Error Handling.

CodeThrown byWhen
VALIDATIONallMalformed arguments or filters; an empty delete batch; a degenerate create span
HANDLE_INVALIDcreate, list, delete, hide, showAn unknown dimension handle, or an unknown anchor / anchorTo / anchors entry
PRECONDITION_FAILEDcreate, delete, hide, showThe anchor (of the dimension, or of create's span) is outside the active proposal, or the editor is not mounted
METHOD_NOT_PERMITTEDcreate, delete, hide, showPlugin writes are disabled