Scripting API
The project stack
from ArtisanPlugin.Scripting import ReliefApi as relief
A relief project is the recipe a signet face, a textured band or an engraved plaque is built from: a rectangular workbench plane, a sampling grid over it, and an ordered stack of operations that each raise or lower the height field. The project lives in the document (it is written into the .3dm), which is the same project the ArtisanRelief panel edits — so a script can rough out four layers and hand them to the bench for refinement, or pick up what the panel left behind.
If you only need a single-operation relief meshed in one call, the one-shot creators — Create from image, Create from curves and Create from geometry — work on a transient project and leave the document’s saved one untouched.
The stack model
The project holds a list of operations. They are evaluated in order, index 0 first, each one writing into the height field the operations below it have already built. Every operation carries a combine mode saying how its own layer merges into that accumulated height, and an Enabled flag; disabled operations are skipped. Nothing is computed while you build the stack — the field is only evaluated when you bake or export.
Because each mode applies over the running result, order changes the outcome. A Multiply texture placed above a domed profile modulates that dome; the same texture placed below it multiplies a flat zero field and disappears.
Combine modes
Combine modes are plain strings — case-insensitive, no kernel import needed; omitting combine means "Add":
| Mode | Effect on the accumulated height | Typical use |
|---|---|---|
Add | heights += layer (the default) | Stack a motif onto a base |
Subtract | heights -= layer | Engrave a shape out of what is below |
ZMax | Union Highest: keeps whichever is taller | Merge two domes without their overlap doubling |
ZMin | Union Lowest: keeps whichever is lower | Clip the relief down to a lower shape |
Absolute | No merge — the layer’s values are placed as-is inside its own mask, substituting what is underneath | Punch a flat plateau or an exact stamped depth |
Multiply | heights *= layer, the layer acting as a scale factor | Modulate an existing relief with a texture |
Reading the project
info = relief.GetProject()
ops = relief.Operations()
names = relief.ProfileNames()
All three are read-only and take no arguments. None of them throws when the document has no project.
GetProject() returns a ReliefProjectInfo:
| Field | Type | Meaning |
|---|---|---|
Exists | bool | False — with every other field left at zero — when the document has no saved relief project |
WorldWidth | double | Workbench width in millimetres |
WorldHeight | double | Workbench height in millimetres |
Resolution | int | Grid nodes along the larger side |
OutputType | str | "Mesh" (open relief) or "Thickness" (closed solid) |
CapDistance | double | Solid thickness below the base plane, in millimetres |
DeleteBase | bool | True when grid cells no operation touched are trimmed away |
OperationCount | int | Number of operations in the stack, enabled or not |
Operations() returns the stack in apply order as a read-only list of ReliefOperationInfo — an empty list when there is no project:
| Field | Type | Meaning |
|---|---|---|
Id | Guid | The operation id, the handle every editing call takes. See Editing the stack |
Index | int | Position in the stack; 0 is applied first |
Type | str | "profile", "extrude", "image", "texture", "geometry", "sculpt" or "smooth" |
Name | str | The label on the panel’s card |
Enabled | bool | False operations are skipped when the field is evaluated |
CombineMode | str | The mode name, e.g. "Multiply" |
MissingReferences | bool | True when a referenced curve or object no longer resolves, is no longer closed, or a referenced image/texture file is gone |
ProfileNames() returns the names the profile parameter of a profile operation accepts: the four built-in presets — Round, Smooth, Chamfer, Plateau — followed by the profiles saved in the user’s own profile library. Matching is case-insensitive; an unrecognised name throws Unknown relief profile '...'. Use one of: ..., listing the whole set.
The "sculpt" and "smooth" types are created with the panel’s brushes or with AddSculpt / AddSmooth, and can be toggled, reordered and removed like any other operation.
Usage
relief.SetupProject(worldWidth = 0, worldHeight = 0, resolution = 0,
workbench = None, solid = True, capDistance = 0,
deleteBase = False)
| Parameter | Default | Meaning |
|---|---|---|
worldWidth | 0 → 50 | Workbench width in millimetres |
worldHeight | 0 → 50 | Workbench height in millimetres |
resolution | 0 → 512 | Grid nodes along the larger side; must be 0 or between 64 and 4096 |
workbench | None → world XY | The Plane the relief sits on; the grid is centred on its origin. None leaves the project’s current plane untouched when one already exists |
solid | True | True bakes a closed solid (OutputType "Thickness"), False an open mesh |
capDistance | 0 → 1.0 | Solid thickness below the base plane, in millimetres |
deleteBase | False | True trims away grid cells no operation touched |
Returns nothing. It creates the document’s relief project if there is none, or reconfigures the settings of the existing one keeping its operation stack, and saves the result back into the document. Mutations belong inside a Transaction for one-step undo.
0 here means the panel default, not leave what is saved. Calling relief.SetupProject() on a project already set to 20 × 20 at 1024 nodes resets it to 50 × 50 at 512 — pass the values you want to keep. workbench is the one exception: None genuinely leaves the saved plane alone.
Validation throws ArgumentException before anything is written: Workbench size cannot be negative., Resolution must be between 64 and 4096 (0 = default 512). and capDistance cannot be negative.
The natural order works: call SetupProject first to configure the workbench, then add operations — an empty project persists its settings, and every later Add* builds on them instead of auto-fitting its own. (Only when there is no project at all does the first Add* auto-fit one to its inputs.) ClearProject deletes the saved project entirely.
Building a stack
from ArtisanPlugin.Scripting import ReliefApi as relief, Transaction
with Transaction.Begin("Signet relief"):
dome = relief.AddProfile([crest_curve], height = 1.2, profile = "Smooth")
grain = relief.AddTexture("KNURL01.jpg", height = 0.15, tilesU = 8, tilesV = 8,
combine = "Multiply", name = "Grain")
# now that the stack is non-empty, the workbench sticks
relief.SetupProject(worldWidth = 20, worldHeight = 20, resolution = 1024,
solid = True, capDistance = 1.5)
mesh_id = relief.Bake()
The five Add* calls are documented in Operations; each returns the operation id you feed to Editing the stack.