Appearance
Transform
Rigid transforms on scene entities. Accessed via snaptrude.design.transform.
Migrated from the removed tools.transform.*. All operations are undoable and return a PluginDesignChangeResult; failures throw (the RPC rejects).
Performance
Every transform is array-based: pass all targets in one call (one host round-trip). Never loop a transform per entity. See Performance.
getPosition/setPosition(andscale, an engine gap) are not part of this surface yet — they land in a later pass.
Types
PluginDesignChangeResult
The committed-state record shared by scene-mutating design ops.
| Property | Type | Description |
|---|---|---|
affected | ComponentHandle[] | The entities the op acted on |
PluginAlignEdge
Which bounding-box edge align snaps to a common world-axis value.
| Value | Axis | Snaps |
|---|---|---|
'left' | X | Min X (left edges) |
'center' | X | Centre X |
'right' | X | Max X (right edges) |
'top' | Z | Max Z (top/back edges) |
'middle' | Z | Centre Z |
'bottom' | Z | Min Z (bottom/front edges) |
PluginTransformMirrorAxis
The horizontal axis mirror flips across (world axes, Y up).
| Value | Mirrors across | In plan (Y up) |
|---|---|---|
'x' | World X | Front ↔ back flip (reflects Z) |
'z' | World Z | Left ↔ right flip (reflects X) |
Vertical ('y') mirroring is not exposed.
Functions
move(components, displacement, options?)
Translate entities by a relative displacement vector (added to the first component's absolute position as the anchor). Undoable.
- Parameters:
components:ComponentHandle[]— Entities to move (≥1)displacement:Vec3Handle— Relative translationoptions:object(optional) —is2D?: boolean,trackParentChange?: boolean
- Returns:
PluginDesignChangeResult - Throws: if any handle is unknown/forged, or the engine move fails
ts
const { vec3 } = snaptrude.core.math;
await snaptrude.design.transform.move(["space-id"], vec3.new(10, 0, 0));rotate(components, angleInDegrees, options?)
Rotate entities by a signed angle in DEGREES (positive = CCW about +Y). The pivot defaults to the combined bounding-box centre; pass options.pivot to rotate about an explicit world-space point instead. Undoable.
Contract change from tools.transform.rotate
The removed tools.transform.rotate took radians; this canonical form takes degrees. The rotation axis moves into options.axis (defaults to world +Y), and the pivot moves into options.pivot (defaults to the combined bbox centre).
- Parameters:
components:ComponentHandle[]— Entities to rotate (≥1)angleInDegrees:number— Signed rotation angle in degreesoptions:object(optional) —axis?: Vec3Handle(defaults to world +Y),pivot?: Vec3Handle(world-space rotation centre; defaults to the combined bbox centre),is2D?: boolean
- Returns:
PluginDesignChangeResult - Throws: if any handle is unknown/forged, or the engine rotate fails
ts
// About the selection's own bbox centre (default)
await snaptrude.design.transform.rotate(["space-id"], 90);
// About an explicit pivot point (here, the world origin)
const { vec3 } = snaptrude.core.math;
await snaptrude.design.transform.rotate(["space-id"], 90, { pivot: vec3.new(0, 0, 0) });align(components, edge, options?)
Snap a set of components' bounding-box edges to a common world-axis value — the classic Left / Center / Right / Top / Middle / Bottom align. With options.reference the target is that component's edge (it stays put); without it, the components align among themselves. World axes only (the UI's camera-relative remap is bypassed). Doors and windows are rejected in v1 — if any component in components (or the reference) is a door or window, the whole call throws; nothing is silently dropped. A group aligns as one rigid body. Undoable.
- Parameters:
components:ComponentHandle[]— Entities to align (≥1; doors/windows rejected)edge:PluginAlignEdge— Which bounding-box edge to snapoptions:object(optional) —reference?: ComponentHandle— the component whose edge is the fixed target
- Returns:
PluginDesignChangeResult - Throws: if any handle is unknown/forged, a door/window is included (in
componentsor as thereference), or the engine align fails
ts
// Left-align three masses to the leftmost one.
await snaptrude.design.transform.align(["m1", "m2", "m3"], "left");
// Align two spaces to a reference's right edge.
await snaptrude.design.transform.align(["s1", "s2"], "right", { reference: "s1" });mirror(components, axis)
Mirror components in place about a horizontal axis — flip their geometry across that axis through the combined bounding-box centre (world-matrix flip + brep inversion + CAD / dimension-line / parametric handling, committed atomically). Nothing moves off-centre; this is the toolbar "flip", not a translate-and-reflect. axis names the axis the geometry mirrors across: 'x' reflects the Z coord (a front ↔ back flip in plan), 'z' reflects the X coord (a left ↔ right flip). Vertical ('y') mirroring is not exposed. Locked, bucket-locked and ineligible entries (terrain, plinths, reference / dimension lines, neighbourhood buildings) are silently dropped — the call only throws when nothing mirrorable remains. Undoable.
- Parameters:
components:ComponentHandle[]— Entities to mirror (≥1)axis:PluginTransformMirrorAxis— Horizontal axis to mirror across ('x'|'z')
- Returns:
PluginDesignChangeResult—affectedechoes the supplied handles - Throws: if any handle is unknown/forged, or nothing mirrorable remains
ts
const rooms = await snaptrude.design.selection.get();
await snaptrude.design.transform.mirror(rooms, "x");Errors
Failed calls reject with a typed PluginError — see Error Handling. Conditions specific to this namespace:
| Code | Thrown by | When | details |
|---|---|---|---|
VALIDATION | move, rotate | components is empty — both ops require at least one entity | — |
VALIDATION | align | Fewer than 2 components without a reference, or an unknown edge | — |
HANDLE_INVALID | move, rotate | A component handle, the displacement vec3, or rotate's options.axis / options.pivot cannot be resolved | — |
HANDLE_INVALID | align | A component or reference handle cannot be resolved | — |
PRECONDITION_FAILED | align | A component or the reference is a door/window (unsupported in v1), or targets a foreign proposal | — |
OPERATION_FAILED | move, rotate | The engine move/rotate fails | engineCode — the engine's failure code |
OPERATION_FAILED | align | The engine align operation fails | — |
VALIDATION | mirror | components is empty, or axis is not 'x' / 'z' (schema) | — |
HANDLE_INVALID | mirror | A component handle cannot be resolved | — |
PRECONDITION_FAILED | mirror | A component targets a foreign proposal | — |
OPERATION_FAILED | mirror | Nothing mirrorable remains (all locked/ineligible) or the engine flip fails | engineCode — e.g. NO_COMPONENTS |