Skip to content

Scripting API

Batch render

from ArtisanPlugin.Scripting import RenderApi as render

Point it at a folder of finished designs and it renders each one with whatever render engine is currently active, leaving the image beside the .3dm it came from. This is the unattended version of the ArtisanBatchRendering command: no options dialog, no folder picker, no progress window, and per-file failures come back in the result instead of stopping the run.

Usage

result = render.BatchRender(
    folder,                        # the folder to scan (required)
    includeSubfolders = False,     # recurse into sub-folders
    extension = ".jpg",            # ".jpg" or ".png" only; jpg is the dialog default
    customResolution = False,      # False: each file uses its own saved render size
    width = 1920,                  # only used when customResolution is True
    height = 1080)                 # only used when customResolution is True

print(result.Processed, len(result.Failed), len(result.OutputFiles))

Parameters

ParameterDefaultMeaning
folderRequired. Resolved to a full path; must exist.
includeSubfoldersFalseFalse scans the top directory only; True recurses through every sub-folder.
extension".jpg"The image format. Case-insensitive, and a leading dot is added if you leave it off, so "PNG" is accepted. Only these two formats exist.
customResolutionFalseTrue renders every file at width × height; False renders each file at its own saved render settings.
width1920Pixels. Only read when customResolution is True.
height1080Pixels. Only read when customResolution is True.

Note that the usual house convention does not apply here: 0 is not a “keep the default” value for width or height. When customResolution is True both sides must be between 16 and 20000 pixels or the call throws; when it is False both are ignored entirely, whatever you pass. There is no -1 sentinel anywhere in this call.

Which files are picked up

The scan looks for *.3dm and then filters the results by real extension, so Rhino’s .3dmbak backups are excluded rather than swept in by the legacy wildcard behaviour on Windows. Files are processed in case-insensitive alphabetical order by full path.

Where the images go, and how they are named

Each image is written next to its .3dm, with the same base name and the chosen extension — C:\jobs\ring-A.3dm produces C:\jobs\ring-A.jpg. There is no separate output folder and no naming template, so with includeSubfolders = True the images end up spread through the same tree as the models. An existing image of the same name is overwritten.

The result

BatchRender returns a BatchRenderResult:

FieldTypeContents
ProcessedintHow many .3dm files were opened and attempted. With no exception thrown, this equals the number of files found.
Failedlist of strThe file names (not full paths) whose image was not produced.
OutputFileslist of strThe full paths of the images actually written.

Processed equals len(Failed) + len(OutputFiles). A file counts as a success only when the image exists on disk and its last-write time is newer than before the render — return codes from the render commands are not trusted, because they are unreliable across engines. A stale image left over from an earlier run therefore counts as a failure, which is what you want.

Partial failure does not throw

A file that fails to open, fails to render or produces no image is caught, added to Failed, and the batch carries on. Nothing about a bad file aborts the run, so always inspect Failed rather than relying on the absence of an exception:

result = render.BatchRender(r"C:\jobs\week-42", includeSubfolders=True, extension=".png")
for name in result.Failed:
    print("no image produced for", name)

The validation errors, by contrast, all throw before any file is opened: “A folder is required.”, “Folder not found: …”, “Extension must be “.jpg” or “.png”.”, “Resolution must be between 16 and 20000 pixels per side.”, and “No .3dm files found in the folder.”. It is also a licensed call.

It replaces the active document — save first

This is the one call in the render facade that does not merely mutate the open document; it changes which document is open, so a Transaction is meaningless here and nothing about the run is undoable.

  • Each file is opened with _-Open, replacing whatever was open.
  • Before every open the current document’s modified flag is cleared, so Rhino never prompts to save — which means unsaved changes in the open document are silently discarded.
  • The original document is not restored at the end. The last file rendered stays active when the call returns, exactly as the command behaves.

Save your work before calling this, and re-open your own file afterwards if you need it.