Appearance
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.937The 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 from → to 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.
| Property | Type | Description |
|---|---|---|
id | DimensionHandle | The 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 |
length | number | Straight-line distance from from to to, in Snaptrude units |
label | string | The 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 |
placement | PluginDimensionPlacement | How that offset is constrained |
anchor | ComponentHandle | null | Component the first endpoint is anchored to; null for a user-drawn dimension on a non-component host mesh |
anchorTo | ComponentHandle | null | Component the second endpoint is anchored to; equals anchor when both endpoints share a host |
storey | number | Storey the dimension belongs to |
buildingId | string | null | Building it belongs to, when it has one |
isHidden | boolean | The user Hide flag — what hide / show toggle |
isVisible | boolean | Whether it is actually drawn — false when hidden, and also when an anchor component is hidden |
isPlanProjected | boolean | Whether 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.
| Property | Type | Description |
|---|---|---|
affected | DimensionHandle[] | 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 endpointto:Vec3Handle— World-space second endpointanchor: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 thefrom→todirection in plan (default3.937= 1 m)
- Returns:
DimensionHandle— the new dimension line - Throws:
VALIDATIONfor malformed arguments or a degenerate span (fromandtocloser than the engine's minimum);HANDLE_INVALIDfor an unknownanchor/anchorTo;PRECONDITION_FAILEDwhen 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 numbersoptions.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:
VALIDATIONfor malformed filters;HANDLE_INVALIDfor an unknown handle inanchors
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, ornullif it is gone - Throws:
VALIDATIONifdimensionis 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:
VALIDATIONfor an empty or malformed array;HANDLE_INVALIDif any handle is unknown (the whole call rejects before anything is deleted);PRECONDITION_FAILEDif 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:
VALIDATIONfor a malformed array;HANDLE_INVALIDif any handle is unknown;PRECONDITION_FAILEDif 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:
VALIDATIONfor a malformed array;HANDLE_INVALIDif any handle is unknown;PRECONDITION_FAILEDif 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 possible | Why / what to do instead |
|---|---|
| Typed / overridden values | A 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) creation | anchor 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 line | No update yet — delete and re-create with a different offset. (The user's Move tool can still nudge one.) |
| Moving an endpoint | Endpoints are stored relative to their anchors; re-create the dimension instead. |
| Dimensions in the selection API | design.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 measurements | The Angle Measurement tool persists nothing, so there is nothing to read or create. |
Related
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.placedViews—updateStyles(shapeId, "Dimension", …)styles (or hides) dimension lines on a Present sheet.
Errors
Failed calls reject with a typed PluginError — see Error Handling.
| Code | Thrown by | When |
|---|---|---|
VALIDATION | all | Malformed arguments or filters; an empty delete batch; a degenerate create span |
HANDLE_INVALID | create, list, delete, hide, show | An unknown dimension handle, or an unknown anchor / anchorTo / anchors entry |
PRECONDITION_FAILED | create, delete, hide, show | The anchor (of the dimension, or of create's span) is outside the active proposal, or the editor is not mounted |
METHOD_NOT_PERMITTED | create, delete, hide, show | Plugin writes are disabled |