Skip to content

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.

PropertyTypeDescription
namestringMaterial name (== the handle token)
idstringEngine material id
colorHexstringDiffuse color as #rrggbb
alphanumberOpacity 0..1
materialTypestring (optional)Material type tag
textureUrlstring (optional)Diffuse texture URL

PluginMaterialSpec

A material construction spec (input DTO — NOT a handle).

PropertyTypeDescription
namestring (optional)Name (generated if omitted)
colorstring (optional)Diffuse color #rrggbb
textureUrlstring (optional)Diffuse texture URL (wins over color)
alphanumber (optional)Opacity 0..1
materialTypestring (optional)Material type tag

PluginMaterialResult

Result of a material mutation — the count of targets affected.

PropertyTypeDescription
countnumberNumber of targets affected

PluginFaceMaterial

One face's material assignment, returned by listByFace.

PropertyTypeDescription
faceIndexnumberBREP face index (a nonnegative integer)
materialMaterialHandle | nullThe face's material, or null when unpainted

PluginComponentMaterial

The material on a component as a whole, returned by get.

PropertyTypeDescription
materialMaterialHandleThe whole-object material — chain into apply / getInfo
idstringEngine material id
namestringMaterial 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.

PropertyTypeDescription
namestringDisplay name of the library entry
categorystringLibrary category (camelCase, e.g. "wood", "colors", "brick")
textureUrlstringTexture/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 scope parameter ('project' | 'preset') was removed: it was silently ignored — both values returned this same scene list. Preset/library entries are not scene materials and cannot be MaterialHandles; they now come from listPresets as 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 with HANDLE_INVALID (see Errors) rather than returning null

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:
  • Returns: PluginComponentMaterial | null — The whole-object material (handle + id + name + default/applied source), or null if the component carries no material. An unresolvable component handle rejects with HANDLE_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 paint
    • material: MaterialHandle | PluginMaterialSpec — Material handle, or an inline spec
    • save: boolean (optional, default true) — 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 reset
    • save: boolean (optional, default true) — 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, or null

isDefault(component)

Test whether a component carries its (type) default material.

  • Parameters:
    • component: ComponentHandle — The component to test
  • Returns: booleantrue if default, otherwise false

isUniform(component)

Test whether a component has a single (uniform) material across all faces.

  • Parameters:
    • component: ComponentHandle — The component to test
  • Returns: booleantrue if uniform, otherwise false

hasTexture(material)

Test whether a material has a texture.

  • Parameters:
    • material: MaterialHandle — The material to test
  • Returns: booleantrue if it has a diffuse texture, otherwise false

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 paint
    • faces: number[] — Face indices to paint (nonnegative integers)
    • material: MaterialHandle | PluginMaterialSpec — Material handle, or an inline spec
    • save: boolean (optional, default true) — 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 component
    • faces: number[] — Face indices to reset (nonnegative integers)
    • save: boolean (optional, default true) — 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 component
    • face: number — Face index (a nonnegative integer)
  • Returns: MaterialHandle | null — The face's material, or null for 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:

CodeThrown byWhendetails
HANDLE_INVALIDgetInfo, 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_INVALIDapply, reset, get, getDefault, isDefault, isUniformA component handle cannot be resolved
PRECONDITION_FAILEDapply, reset, applyToFaces, resetFacesA 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.