Appearance
Design Query
Read-only enumeration and inspection of scene-committed BIM entities. No query mutates the scene. Accessed via snaptrude.design.query.
Every list* method returns a snapshot ComponentHandle[] ([], never null) filtered by the shared PluginEntityFilter; per-entity reads take a ComponentHandle and return primitive records / child handles, or null when the entity is gone. Resolve details of a returned handle with getProperties / measure / design.query.geometry.*.
Entity Queries
Discovery and inspection of BIM entities by kind, plus identity, hierarchy, property, and metric reads. Accessed via snaptrude.design.query.
Types
PluginEntityType
The kind of a BIM entity — the discovery/filter vocabulary for the whole design.query.* surface. Values are clean lowerCamel tokens; the host maps each to the engine's internal type (whose raw strings are case-inconsistent — never surfaced here).
| Value | Entity |
|---|---|
"wall" | Wall |
"space" | Space (a room mass) |
"mass" | Generic mass (non-room) |
"door" | Door |
"window" | Window |
"floor" | Floor |
"slab" | Slab |
"roof" | Roof |
"column" | Column |
"beam" | Beam |
"ceiling" | Ceiling |
"staircase" | Staircase |
"furniture" | Furniture |
"referenceLine" | Reference line |
"curtainWall" | Parametric curtain wall |
"mullion" | Curtain-wall mullion |
"panel" | Curtain-wall panel |
PluginEntityFilter
The single filter shared by every design.query.list* method, so filtering is identical across all BIM object types. Every field is optional and AND-combined: a component must satisfy all provided fields. Plural fields are arrays (match any of); singular fields are scalars. A field that names a type-specific dimension (massTypes/spaceTypes/departmentId) excludes components that lack that dimension.
| Field | Type | Keeps components where |
|---|---|---|
types | PluginEntityType[] | entity kind ∈ types (ignored by per-type list* — the method fixes the kind) |
storeys | number[] | storey/floor level ∈ storeys (negative = basement) |
buildingIds | string[] | building ∈ buildingIds |
structureIds | string[] | structure ∈ structureIds |
label | string | label (room_type ?? mesh label) === label |
massTypes | PluginMassType[] | mass-type ∈ (masses only) |
spaceTypes | PluginSpaceType[] | space-type ∈ (spaces only) |
departmentId | PluginDepartmentId | department === |
isSelected | boolean | current selection state === |
isLocked | boolean | lock flag === |
isHidden | boolean | user-hidden flag === |
within | BBoxComponents | the entity's bounding box intersects the region |
overlaps | ComponentHandle | the entity's plan footprint overlaps the given space's bottom-face footprint — non-zero intersection area, so fully-inside, boundary-nested, and partially-overhanging entities all match; edge-touching with zero interior overlap does not. Exact polygon intersection (holes respected). Tested in plan — storey height is ignored; compose with storeys to scope a floor. Hidden entities are excluded by default — pass isHidden explicitly to override. The reference space itself is never returned. Throws on an unknown id. Entities without a brep footprint use their bounding-box plan rectangle. |
ids | ComponentHandle[] | id ∈ ids (restrict to a known set) |
PluginEntityProperties
The common property record returned by getProperties — a partial object (a field is present only when it applies to the entity). Type-specific and geometry reads live on measure and design.query.geometry.*, keeping this record generic across every type.
| Property | Type | Description |
|---|---|---|
id | string | The entity id |
type | PluginEntityType | Entity kind |
label | string | room_type ?? mesh label ?? "" |
storey | number | Storey/floor level |
buildingId | string | Owning building |
structureId | string | Owning structure |
massType | string | Mass-type (masses only) |
spaceType | PluginSpaceType | Space-type (spaces only) |
areaClass | PluginAreaClass | Area classification (spaces only) |
departmentId | string | Department (masses only) |
buildingType | string | Assigned building type NAME (walls / slabs / floors / roofs / ceilings only) — the Object Properties panel's Wall/Slab/Floor/Roof/Ceiling Type dropdown value, matching the names from design.types.list(kind) |
isLocked | boolean | Lock flag |
isHidden | boolean | User-hidden flag |
isSelected | boolean | Current selection state |
boundingBox | BBoxComponents | World-space AABB |
adjacency | { spaceId: string, value: number }[] | Adjacency relationships (spaces/masses only). value: 2 Direct (required), 1 Indirect or physical contact, -1 Restricted; 0 entries are filtered out. [] when adjacency has never been computed — see Adjacency. |
PluginEntityMeasurements
The multi-metric bundle returned by measure. boundingBox is always present; the numeric metrics appear only when the entity's type computes them (area: floors/masses/slabs/roofs/beams/columns; volume: all; length: walls/beams). Values are in Snaptrude units — convert with snaptrude.core.units.convert(value, from, to).
thickness and height are the Object Properties panel's dimension reads — the same getMeshDimensions engine seam the panel and the design.update.wall / .slab / .floor / .roof / .ceiling write side use, in engine units. thickness is present for walls (the plan thickness — straight orthogonal walls only, exactly when the panel shows it) and for the slab family (the vertical extent the panel calls Thickness); height for walls only.
| Property | Type | Description |
|---|---|---|
area | number (optional) | Bottom-face area |
volume | number (optional) | Solid volume |
length | number (optional) | Running length (linear elements) |
thickness | number (optional) | Panel Thickness — walls (straight orthogonal only) and slabs/floors/roofs/ceilings |
height | number (optional) | Panel Height — walls only |
boundingBox | BBoxComponents | World-space AABB (always present) |
PluginStaircaseParams
The parametric fields of a staircase, returned by getStaircaseParams. Dimensions are in Snaptrude (engine) units — the same units the design.update.staircase write side takes. The three type-specific fields (wellSize / landingWidth / flightStartDistAfterTurn) are omitted when the preset doesn't use them.
| Property | Type | Description |
|---|---|---|
staircaseType | string | Type token (straight, dogLegged, lShaped, …) |
staircasePreset | string | Preset token |
staircaseHeight | number | Total rise |
steps | number | Step count |
riser | number | Riser height |
tread | number | Tread depth |
width | number | Flight width |
depth | number | Flight depth |
baseOffset | number | Base offset from the storey |
isStoreyHeightUnlocked | boolean | Whether height is decoupled from the storey |
isStaircaseHeightUnlocked | boolean | Whether height is decoupled from steps × riser |
storey | number | Storey/floor level |
wellSize | number? | Well size (well-based presets only) |
landingWidth | number? | Landing width (landing-based presets only) |
flightStartDistAfterTurn | number? | Flight start distance after a turn (turn presets only) |
Functions
listEntities(filter?)
List all BIM entities in the project matching the filter.
- Parameters:
filter:PluginEntityFilter(optional) — The shared entity filter
- Returns:
ComponentHandle[]— Matching entities ([]if none)
ts
const doorsAndWindows = await snaptrude.design.query.listEntities({
types: ["door", "window"],
storeys: [0]
});listByType(type, filter?)
List entities of a single PluginEntityType, plus filter.
- Parameters:
type:PluginEntityType— The entity kind to listfilter:PluginEntityFilter(optional) — The shared entity filter
- Returns:
ComponentHandle[]— Matching entities
ts
const lockedSlabs = await snaptrude.design.query.listByType("slab", { isLocked: true });listWalls(filter?)
List all walls, filtered. The types field of the filter is ignored (this method fixes the kind).
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]— Wall handles
ts
const groundFloorWalls = await snaptrude.design.query.listWalls({ storeys: [0] });listSpaces(filter?)
List all spaces (room masses), filtered. See listWalls.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
ts
// Which spaces sit on a bigger floor-plate space? Exact plan intersection —
// fully-inside, boundary-nested, and partially-overhanging spaces all match;
// outside and merely edge-touching spaces don't, and the plate itself is excluded.
const [plate] = await snaptrude.design.query.listSpaces({ label: "Bigger floorplate" });
const onPlate = await snaptrude.design.query.listSpaces({ overlaps: plate });listMasses(filter?)
List all generic masses (non-room masses), filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listDoors(filter?)
List all doors, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listWindows(filter?)
List all windows, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listFloors(filter?)
List all floors, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listSlabs(filter?)
List all slabs, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listRoofs(filter?)
List all roofs, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listColumns(filter?)
List all columns, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listBeams(filter?)
List all beams, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listCeilings(filter?)
List all ceilings, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listStaircases(filter?)
List all staircases, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listFurniture(filter?)
List all furniture, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listReferenceLines(filter?)
List all reference lines, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
listMullions(filter?)
List all curtain-wall mullions, filtered.
- Parameters:
filter:PluginEntityFilter(optional)
- Returns:
ComponentHandle[]
getById(id)
Look an entity up by id — returns the same handle if it still resolves live, else null. A cheap validity probe (distinct from exists).
- Parameters:
id:ComponentHandle— The entity id to look up
- Returns:
ComponentHandle | null— The handle, ornullif it no longer resolves
exists(id)
Test whether an entity id resolves to a live scene entity.
- Parameters:
id:ComponentHandle— The entity id to test
- Returns:
boolean—trueif it exists, otherwisefalse
getEntityType(component)
Get an entity's PluginEntityType.
- Parameters:
component:ComponentHandle— The entity to read
- Returns:
PluginEntityType | null— The kind, ornullif the entity is gone / its type is unknown
getLabel(component)
Get an entity's human label (room_type for spaces/masses, else the mesh label; "" when unlabelled). The write side is design.update (setLabel).
- Parameters:
component:ComponentHandle— The entity to read
- Returns:
string— The label
getEntityRef(component)
Get a serializable, persistable reference to an entity. Under the all-handle model a ComponentHandle already IS the ref (raw Component.id), so this is the identity passthrough — provided for API completeness.
- Parameters:
component:ComponentHandle— The entity
- Returns:
ComponentHandle— The entity's handle
listChildren(component)
List an entity's direct child entities.
- Parameters:
component:ComponentHandle— The parent entity
- Returns:
ComponentHandle[]— Child handles ([]if none)
getHost(component)
Get an entity's host/parent entity (e.g. the wall a door is cut into).
- Parameters:
component:ComponentHandle— The entity
- Returns:
ComponentHandle | null— The host, ornullif top-level
getProperties(component)
Read an entity's common properties as a PluginEntityProperties record (only applicable fields are present). For spaces/masses this includes adjacency — the per-entity adjacency read (bulk form: program.adjacency.getMatrix). For walls and the slab family (slab/floor/roof/ceiling) this includes buildingType — the assigned building type NAME the panel's type dropdown shows, matching the names from design.types.list(kind).
- Parameters:
component:ComponentHandle— The entity to read
- Returns:
PluginEntityProperties— The property record
ts
const [wall] = await snaptrude.design.query.listWalls();
const props = await snaptrude.design.query.getProperties(wall);
console.log(props.type, props.storey, props.buildingType);measure(component)
Measure an entity — the multi-metric bundle (area/volume/length + bbox). For walls this also carries the panel's thickness (straight orthogonal walls only) and height; for the slab family (slab/floor/roof/ceiling) the panel's thickness — the read side of design.update.wall / .slab / .floor / .roof / .ceiling, in engine units.
- Parameters:
component:ComponentHandle— The entity to measure
- Returns:
PluginEntityMeasurements| null— The metrics, ornullif the entity is gone
ts
const [space] = await snaptrude.design.query.listSpaces();
const m = await snaptrude.design.query.measure(space);
console.log(m?.area, m?.volume);
const [wall] = await snaptrude.design.query.listWalls();
const wm = await snaptrude.design.query.measure(wall);
console.log(wm?.thickness, wm?.height); // the panel's Thickness / HeightgetBoundingBox(components)
Get the union axis-aligned bounding box enclosing a set of entities.
- Parameters:
components:ComponentHandle[]— The entities to enclose
- Returns:
BBoxComponents | null— The union box, ornullif the set is empty / none resolve
ts
const walls = await snaptrude.design.query.listWalls();
const box = await snaptrude.design.query.getBoundingBox(walls);getStaircaseParams(staircase)
Read the parametric fields of a staircase. The write counterpart is design.update.staircase; a read → write round-trips exactly.
- Parameters:
staircase:ComponentHandle— The staircase to read
- Returns:
PluginStaircaseParams| null—nullwhen the handle is gone or is not a staircase
ts
const [stair] = await snaptrude.design.query.listStaircases();
const params = stair ? await snaptrude.design.query.getStaircaseParams(stair) : null;
console.log(params?.steps, params?.riser);Geometry
Read the geometry of scene BIM entities. Accessed via snaptrude.design.query.geometry.
This is the bridge from the BIM/scene layer (design.*, keyed by ComponentHandle) into the geometry kernel (core.geom.query.*, keyed by value/topology handles). getBrep mints a BrepHandle for a component's boundary-representation mesh; getBottomContour mints a ContourHandle for its footprint outline; getCenterline mints a CurveHandle for a wall's core curve.
Returned handles are session-ephemeral and go stale on undo/redo/re-topologize — re-fetch a fresh one after edits.
Functions
getBrep(component)
Get the boundary-representation (BREP) mesh of a scene component.
- Parameters:
component:ComponentHandle— The scene component to read
- Returns:
BrepHandle | null— The brep, ornullif the component has no brep geometry
ts
const brep = await snaptrude.design.query.geometry.getBrep(component);
if (brep) {
const faces = await snaptrude.core.geom.query.brep.listFaces(brep);
}getBottomContour(component)
Get the bottom-face contour of a component — the footprint outline (outer profile + holes) of its lowest horizontal face, as a reusable ContourHandle.
Extracted from the component's B-rep; robust to inverted face normals. Read its geometry via snaptrude.core.geom.query.contour.*, or feed it back into design.create.* / core.geom.*.
- Parameters:
component:ComponentHandle— The scene component to read
- Returns:
ContourHandle | null— The footprint contour, ornullif the component has no extractable bottom face (e.g. it carries no B-rep)
ts
const [wall] = await snaptrude.design.query.listWalls();
const contour = await snaptrude.design.query.geometry.getBottomContour(wall);
if (contour) {
const area = await snaptrude.core.geom.query.contour.getArea(contour);
}getCenterline(component)
Get the centerline (core curve) of a wall — the single curve running down the middle of the wall, as a reusable CurveHandle (a Line for a straight wall, an Arc for a curved wall).
For a parametric wall this is its stored core curve; otherwise it is derived from the wall's B-rep bottom face. Read its geometry via snaptrude.core.geom.query.curve.*, or feed it into design.create.*.
Only walls have a centerline. As with all get* reads it never throws: a non-wall component, or a wall with no derivable centerline, yields null.
- Parameters:
component:ComponentHandle— The scene component to read (only walls yield a centerline)
- Returns:
CurveHandle | null— The centerline curve, ornullif the component is not a wall or the wall has no derivable centerline (e.g. it carries no B-rep or has an unsupported profile)
ts
const [wall] = await snaptrude.design.query.listWalls();
const centerline = await snaptrude.design.query.geometry.getCenterline(wall);
if (centerline) {
const length = await snaptrude.core.geom.query.curve.getLength(centerline);
}Spaces
Space-specific reads (a space is a room mass). Accessed via snaptrude.design.query.spaces.
Only the space queries feasible against the engine today are exposed here. getFloor / listBoundingWalls (space↔wall topology) are deferred — they need engine work that does not exist yet. listAdjacent stays deferred because the shipped surfaces already answer it with value semantics: per-space via the adjacency field of getProperties, in bulk via program.adjacency.getMatrix.
Functions
get(space, properties)
Get selected properties of a space — the selective multi-property read. Only the properties listed in properties are returned; unlisted properties are undefined in the result. This is the canonical home of the read formerly at entity.space.get (now removed). Adjacency is not part of this read — it is an entity property: read it via the adjacency field of getProperties.
- Parameters:
space:ComponentHandle— The space (room mass) to readproperties:PluginDesignQuerySpacesGetProperty[]— Property names to retrieve (value tables below).
- Returns:
PluginDesignQuerySpacesGetResult— Partial record containing only the requested properties - Throws: If the space does not exist or the component is not a space/mass
ts
const [space] = await snaptrude.design.query.listSpaces();
const info = await snaptrude.design.query.spaces.get(space, ["name", "area", "position"]);
console.log(info.name, info.area, info.position);Available properties (PluginDesignQuerySpacesGetProperty):
Basic:
| Value | Return Type | Description |
|---|---|---|
"id" | string | Unique space identifier |
"type" | string | Component type |
"room_type" | string | Room type classification |
"name" | string | Display name of the space |
Derived from parametric data:
| Value | Return Type | Description |
|---|---|---|
"area" | number | Bottom face area (from areas_bottomFace) |
"breadth" | number | Breadth dimension |
"depth" | number | Depth dimension |
"height" | number | Height dimension |
"massType" | string | null | Mass type classification |
"spaceType" | PluginSpaceType | null | Space type classification (Room, Balcony, etc.) |
"areaClass" | PluginAreaClass | Effective area classification ("NET", "GROSS", or "EXCLUDED"), resolving any per-space override then the space-type default. Never null. |
"storey" | number | null | Story the space belongs to |
"departmentId" | string | null | Assigned department ID |
"departmentName" | string | Assigned department name |
"departmentColor" | string | Assigned department color (hex/CSS) |
Derived from mesh:
| Value | Return Type | Description |
|---|---|---|
"position" | Vec3Components | Local position relative to parent |
"absolutePosition" | Vec3Components | Absolute position in the scene |
"rotation" | Vec3Components | Euler rotation angles (radians) |
"rotationQuaternion" | QuatComponents | null | Quaternion rotation, or null if unset |
Derived from brep:
| Value | Return Type | Description |
|---|---|---|
"planPoints" | Vec3Components[] | Bottom outer profile points in world space with y = 0 (2D plan). No closing duplicate point. |
"profile" | CurveHandle[] | Bottom outer profile curves in world space, as opaque curve handles. Read coordinates via the core.geom.curve read API. |
"innerProfiles" | CurveHandle[][] | Inner (hole) profile curve loops in world space — one loop per hole, [] when the space has none. Each curve is an opaque handle. |
"innerPlanPoints" | Vec3Components[][] | Inner (hole) profile points in world space with y = 0 — one loop per hole, no closing duplicate, [] when none. |
getFootprint(space)
Get the footprint of a space — its bottom-face contour (outer profile + holes) as a reusable ContourHandle. Equivalent to getBottomContour narrowed to spaces.
- Parameters:
space:ComponentHandle— The space (room mass) to read
- Returns:
ContourHandle | null— The footprint contour, ornullif the space has no extractable footprint
ts
const [space] = await snaptrude.design.query.listSpaces();
const footprint = await snaptrude.design.query.spaces.getFootprint(space);Errors
Failed calls reject with a typed PluginError — see Error Handling. Conditions specific to this namespace:
| Code | Thrown by | When | details |
|---|---|---|---|
HANDLE_INVALID | getLabel, getEntityRef, listChildren, getHost, getProperties, geometry.*, spaces.getFootprint | The component handle cannot be resolved | — |
HANDLE_INVALID | all list* | filter.overlaps names an unresolvable id — this fails loudly rather than silently returning [] | — |
HANDLE_INVALID | spaces.get | The id does not resolve to a live space/mass (not-found and wrong-kind collapse to the one code) | — |
PRECONDITION_FAILED | spaces.get | A brep-derived property (planPoints, innerPlanPoints) is requested on a space without B-rep geometry; or the not-yet-wired profile/innerProfiles properties are requested | property — the offending property, handles — the space |
The probe-style reads are deliberately total: getById/getEntityType/measure return null and exists returns false for a gone id, getBoundingBox skips unresolvable members (null only when none resolve), and the geometry.* / getFootprint reads return null for a resolvable component that lacks the requested geometry (no B-rep, no bottom face, no derivable centerline) — none of these throw.