Appearance
Groups
Read and edit the group hierarchy of the active project. Accessed via snaptrude.core.groups.
A group is a named, lockable container that bundles components (and other groups) so they can be selected and transformed as one. This namespace is the plugin-facing view of that hierarchy: a group's identity, name, member count, lock state, and parent — never the underlying meshes.
Reads return plain records and never throw for a missing group (get returns null, list returns [], isLocked returns false). Ids are stable public strings, never engine mesh handles. Members are moved and copied through the design operations by group id (snaptrude.design.transform.move, design.create.copy) and locking likewise routes through design.lock — not through a method here.
At a glance
| Method | What it does | Mutates? |
|---|---|---|
list() | List every group | — |
get(groupId) | One group by id, or null | — |
getForComponent(componentId) | The innermost group containing a component | — |
listMembers(groupId) | A group's direct members (components + subgroups) | — |
isLocked(groupId) | Whether a group is locked | — |
getBounds(groupId) | World-space bounds of the group's contents | — |
create(componentIds, name?) | Group components into a new group | ✓ |
update(groupId, options?) | Rename / change membership (sparse) | ✓ |
delete(groupId) | Dissolve a group (members survive) | ✓ |
Types
PluginCoreGroupRef
A group in the active project.
| Property | Type | Description |
|---|---|---|
id | string | Stable public group id (e.g. "group-12") — never a mesh handle |
name | string | Display name (auto-generated fallback until the user sets one) |
memberCount | number | Number of direct members (components + nested groups) |
isLocked | boolean | Whether the group is locked against edits |
parentId | string | undefined | Parent group id when nested, else absent |
PluginCoreGroupMember
A direct member of a group.
| Property | Type | Description |
|---|---|---|
id | string | Component.id for a component member, or the group id for a nested group |
type | "component" | "group" | Whether this member is a component or a nested group |
PluginCoreGroupsGetBoundsResult
The group's world-space axis-aligned bounds, in internal units — { min, max, center } where each is { x, y, z }, or null when the group is missing or has no meshes.
Functions
list()
List every group in the active project — each group's identity, member count, lock state, and parent (when nested).
- Returns:
{ groups: PluginCoreGroupRef[] }— empty when the project has none.
ts
const { groups } = await snaptrude.core.groups.list();
for (const g of groups) console.log(g.name, g.memberCount, g.isLocked);get(groupId)
Get a single group by id.
- Parameters:
groupId:string— the id of the group to read
- Returns:
PluginCoreGroupRef | null—nullif no group has that id.
ts
const group = await snaptrude.core.groups.get("group-12");
if (group) console.log(group.name, group.memberCount);getForComponent(componentId)
Get the innermost group directly containing a component, or null if it is ungrouped or does not exist.
- Parameters:
componentId:ComponentHandle— theComponent.idto look up
- Returns:
PluginCoreGroupRef | null
ts
const group = await snaptrude.core.groups.getForComponent("cmp_42");
console.log(group ? group.name : "ungrouped");listMembers(groupId)
List the direct members of a group — each as an id + kind. Nested groups are returned as members, not flattened.
- Parameters:
groupId:string— the id of the group whose members to read
- Returns:
{ members: PluginCoreGroupMember[] }— empty when the group is empty or missing.
ts
const { members } = await snaptrude.core.groups.listMembers("group-12");
for (const m of members) console.log(m.type, m.id);isLocked(groupId)
Report whether a group is locked. A predicate — never mutates, never throws; an unknown group id returns false.
- Parameters:
groupId:string— the id of the group to test
- Returns:
boolean—trueif the group exists and is locked, otherwisefalse.
ts
if (await snaptrude.core.groups.isLocked("group-12")) {
console.log("locked — unlock it first");
}getBounds(groupId)
Get the axis-aligned world-space bounds of everything in the group, in internal units. Returns null for a missing or mesh-less group (a clean miss — never a fake box).
- Parameters:
groupId:string— the id of the group to measure
- Returns:
{ min, max, center } | null— each corner an{ x, y, z }point, ornullwhen the group is missing or empty.
ts
const bounds = await snaptrude.core.groups.getBounds("group-12");
if (bounds) console.log(bounds.center.x, bounds.center.y, bounds.center.z);create(componentIds, name?)
Group components into a new group. Pass a name to label it; otherwise it gets an auto-generated fallback name you can change later with update. Undoable.
- Parameters:
componentIds:ComponentHandle[]— the components to group (at least one)name:string | undefined— display name (auto-generated if omitted)
- Returns:
{ groupId: string }— id of the new group (read the full record back withget). - Throws: If a component id is invalid, or the group could not be created.
ts
const { groupId } = await snaptrude.core.groups.create(["cmp_1", "cmp_2"], "Kitchen");update(groupId, options?)
A sparse update of a group's name and/or membership — omitted fields are left unchanged. addComponentIds and removeComponentIds are applied as membership deltas (add before remove); name renames the group. Undoable.
- Parameters:
groupId:string— the id of the group to updateoptions.name:string | undefined— new display name (unchanged if omitted)options.addComponentIds:ComponentHandle[] | undefined— components to addoptions.removeComponentIds:ComponentHandle[] | undefined— components to remove
- Returns:
PluginCoreGroupRef— the updated record. - Throws: If no group has the given id, or a component id is invalid.
ts
const group = await snaptrude.core.groups.update("group-12", {
name: "Kitchen",
addComponentIds: ["cmp_9"]
});delete(groupId)
Delete (dissolve) a group. The member elements are not deleted — they are returned to the group's parent (or ungrouped at the top level). Undoable.
- Parameters:
groupId:string— the id of the group to dissolve
- Returns:
{ deleted: true } - Throws: If no group has the given id.
ts
await snaptrude.core.groups.delete("group-12");Errors
Failed calls reject with a typed PluginError — see Error Handling. Conditions specific to this namespace:
| Code | Thrown by | When | details |
|---|---|---|---|
HANDLE_INVALID | update, delete | No group has the given id | kind: "group" |
HANDLE_INVALID | create, update | One or more component ids cannot be resolved — thrown before any mutation, so the write is atomic | kind: "component", handles — every unresolvable id |
Reads never throw: get, getForComponent, and getBounds return null on a miss, list and listMembers return empty, isLocked returns false.