Appearance
Materials
The project material library + material assignment. Accessed via snaptrude.design.materials.
Materials are MaterialHandles (entity-style, name-addressed). Reads return a MaterialHandle/PluginMaterialInfo; apply/reset mutate the scene (undoable via save, default true). create mints a material from a PluginMaterialSpec (idempotent by name). list reads the materials loaded in the project; listPresets reads the browsable preset/library catalog — handle-less PluginPresetMaterial records that become scene materials via create/apply.
get is the whole-object read (the eyedropper): the material on a component as a whole. Per-face assignment (applyToFaces / resetFaces) and per-face reads (getByFace / listByFace) target individual BREP faces by index. copy lands in a later pass.
Types
PluginMaterialInfo
A material's descriptor.
| Property | Type | Description |
|---|---|---|
name | string | Material name (== the handle token) |
id | string | Engine material id |
colorHex | string | Diffuse color as #rrggbb |
alpha | number | Opacity 0..1 |
materialType | string (optional) | Material type tag |
textureUrl | string (optional) | Diffuse texture URL |
PluginMaterialSpec
A material construction spec (input DTO — NOT a handle).
| Property | Type | Description |
|---|---|---|
name | string (optional) | Name (generated if omitted) |
color | string (optional) | Diffuse color #rrggbb |
textureUrl | string (optional) | Diffuse texture URL (wins over color) |
alpha | number (optional) | Opacity 0..1 |
materialType | string (optional) | Material type tag |
PluginMaterialResult
Result of a material mutation — the count of targets affected.
| Property | Type | Description |
|---|---|---|
count | number | Number of targets affected |
PluginFaceMaterial
One face's material assignment, returned by listByFace.
| Property | Type | Description |
|---|---|---|
faceIndex | number | BREP face index (a nonnegative integer) |
material | MaterialHandle | null | The face's material, or null when unpainted |
PluginComponentMaterial
The material on a component as a whole, returned by get.
| Property | Type | Description |
|---|---|---|
material | MaterialHandle | The whole-object material — chain into apply / getInfo |
id | string | Engine material id |
name | string | Material name (== the handle token) |
source | 'default' | 'applied' | Whether it is the type default or an explicitly-applied one |
PluginPresetMaterial
A preset material library entry (value record — NOT a handle), returned by listPresets.
| Property | Type | Description |
|---|---|---|
name | string | Display name of the library entry |
category | string | Library category (camelCase, e.g. "wood", "colors", "brick") |
textureUrl | string | Texture/swatch image URL — feed to PluginMaterialSpec.textureUrl |
Functions
list()
List the materials loaded in the project — every named material in the live scene (applied finishes, plugin-created materials, and type defaults in use). For the browsable preset/library catalog, use listPresets.
The former
scopeparameter ('project' | 'preset') was removed: it was silently ignored — both values returned this same scene list. Preset/library entries are not scene materials and cannot beMaterialHandles; they now come fromlistPresetsas handle-less specs.
- Returns:
MaterialHandle[]— The materials ([]when empty)
ts
const materials = await snaptrude.design.materials.list();
for (const material of materials) {
const info = await snaptrude.design.materials.getInfo(material);
if (info) console.log(info.name, info.colorHex);
}listPresets()
List the preset material library — the same catalog the app's material browser shows (the built-in finishes plus the workspace's uploaded materials), fetched from the material library service (session-cached; /getgeneralmaterials/ + /getusermaterials/ on a cache miss). Library entries are not scene materials and carry no handle; each is a named texture record. To use one, feed it to create / apply as a PluginMaterialSpec: { name, textureUrl, materialType: category }.
- Returns:
PluginPresetMaterial[]— The library entries ([]when the library service is unreachable)
ts
const presets = await snaptrude.design.materials.listPresets();
const brick = presets.find((p) => p.category.toLowerCase().includes("brick"));
if (brick) {
const walls = await snaptrude.design.query.listWalls();
await snaptrude.design.materials.apply(walls, {
name: brick.name,
textureUrl: brick.textureUrl,
materialType: brick.category
});
}getInfo(material)
Read a material's descriptor.
- Parameters:
material:MaterialHandle— The material to read
- Returns:
PluginMaterialInfo— The descriptor. An unresolvable material handle rejects withHANDLE_INVALID(see Errors) rather than returningnull
get(component)
Read the material applied to a component as a whole — the eyedropper. For a uniformly-painted component this is that single material; for a per-face-painted one it is the material on the component's base/first face. Use getByFace / listByFace for the per-face breakdown.
- Parameters:
component:ComponentHandle— The component to sample
- Returns:
PluginComponentMaterial| null— The whole-object material (handle + id + name +default/appliedsource), ornullif the component carries no material. An unresolvable component handle rejects withHANDLE_INVALID.
ts
const [component] = await snaptrude.design.selection.get();
const sampled = await snaptrude.design.materials.get(component);
if (sampled) {
console.log(sampled.name, sampled.source); // e.g. "Brick Red" "applied"
// eyedropper → paintbrush: reuse the sampled material elsewhere
const walls = await snaptrude.design.query.listWalls();
await snaptrude.design.materials.apply(walls, sampled.material);
}apply(targets, material, save?)
Apply a material (by handle or spec) to one or more components. Write-gated and proposal-scoped like the other mutations — all targets are resolved and scope-checked before any is painted (a bad handle in the batch paints nothing). Undoable (save, default true).
- Parameters:
targets:ComponentHandle[]— Components to paintmaterial:MaterialHandle | PluginMaterialSpec— Material handle, or an inline specsave:boolean(optional, defaulttrue) — Commit as an undoable command
- Returns:
PluginMaterialResult— The number of targets the material was applied to
ts
const selected = await snaptrude.design.selection.get();
const result = await snaptrude.design.materials.apply(selected, {
color: "#c0ffee",
alpha: 0.8
});
console.log(`painted ${result.count} components`);reset(components, save?)
Reset one or more components to their default material. Undoable. Paired with apply.
- Parameters:
components:ComponentHandle[]— Components to resetsave:boolean(optional, defaulttrue) — Commit as an undoable command
- Returns:
PluginMaterialResult— The number of components reset
create(spec)
Create (or get, idempotent by name) a material from a spec.
- Parameters:
spec:PluginMaterialSpec— The material construction spec
- Returns:
MaterialHandle— The new material
ts
const brick = await snaptrude.design.materials.create({
name: "Brick Red",
color: "#8b2f2f"
});
const walls = await snaptrude.design.query.listWalls();
await snaptrude.design.materials.apply(walls, brick);getDefault(component)
Get the default material for a component's type.
- Parameters:
component:ComponentHandle— The component whose type default to look up
- Returns:
MaterialHandle | null— The default material, ornull
isDefault(component)
Test whether a component carries its (type) default material.
- Parameters:
component:ComponentHandle— The component to test
- Returns:
boolean—trueif default, otherwisefalse
isUniform(component)
Test whether a component has a single (uniform) material across all faces.
- Parameters:
component:ComponentHandle— The component to test
- Returns:
boolean—trueif uniform, otherwisefalse
hasTexture(material)
Test whether a material has a texture.
- Parameters:
material:MaterialHandle— The material to test
- Returns:
boolean—trueif it has a diffuse texture, otherwisefalse
applyToFaces(component, faces, material, save?)
Paint specific BREP faces of a component. BREP-only; face indices must be in range. Undoable (save, default true).
- Parameters:
component:ComponentHandle— The BREP component to paintfaces:number[]— Face indices to paint (nonnegative integers)material:MaterialHandle | PluginMaterialSpec— Material handle, or an inline specsave:boolean(optional, defaulttrue) — Commit as an undoable command
- Returns:
PluginMaterialResult— The number of faces painted - Throws: for a non-BREP component, an out-of-range face index (
RangeError), or a locked component
ts
const [mass] = await snaptrude.design.query.listMasses();
await snaptrude.design.materials.applyToFaces(mass, [0, 1], { color: "#c0ffee" });resetFaces(component, faces, save?)
Reset specific BREP faces back to the component/type default — the inverse of applyToFaces. Same BREP-only / range / lock guards; undoable.
- Parameters:
component:ComponentHandle— The BREP componentfaces:number[]— Face indices to reset (nonnegative integers)save:boolean(optional, defaulttrue) — Commit as an undoable command
- Returns:
PluginMaterialResult— The number of faces reset
getByFace(component, face)
Read the material on a single BREP face.
- Parameters:
component:ComponentHandle— The BREP componentface:number— Face index (a nonnegative integer)
- Returns:
MaterialHandle | null— The face's material, ornullfor a non-BREP / out-of-range / unpainted face
listByFace(component)
Read the per-face material of every BREP face, in face-index order.
- Parameters:
component:ComponentHandle— The BREP component
- Returns:
PluginFaceMaterial[]—[]for a non-BREP component
Errors
Failed calls reject with a typed PluginError — see Error Handling. Conditions specific to this namespace:
| Code | Thrown by | When | details |
|---|---|---|---|
HANDLE_INVALID | getInfo, hasTexture, apply (handle form) | The material handle no longer resolves — material handles are name-addressed, so this means no material of that name exists in the scene | — |
HANDLE_INVALID | apply, reset, get, getDefault, isDefault, isUniform | A component handle cannot be resolved | — |
PRECONDITION_FAILED | apply, reset, applyToFaces, resetFaces | A target component is outside the active proposal, or plugin writes are disabled | — |
Engine failures inside material creation/application (MaterialFactory/MaterialManager) are untyped today and surface as a generic INTERNAL error (report it with its errorId) — a known gap.