Skip to content

Scripting API

Render Studio catalogs

from ArtisanPlugin.Scripting import RenderStudioApi as studio

Render Studio is the ArtisanRenderAndAnimation panel: a scene environment, the studio material library, and a raytraced render pipeline that goes through Rhino’s current renderer (Cycles unless the user changed it). It renders the Rhino document itself, so what comes out is what the renderer sees. That is a different thing from the Realtime Render viewer, which is a separate web window with its own scene, its own camera and its own materials, and which never touches the document.

These three methods are the entry point to everything else on this side of the API. ApplyEnvironment and ApplyMaterial take names, not ids, and the only place those names exist is on disk — environments are .renv files in <user>\Render\Environments, materials are .rmtl files in <user>\Render\Materials\<Family>. The name is the file name without its extension. Rather than hard-coding a string that may not be installed on the next machine, list first and apply from the list.

Usage

names    = studio.ListEnvironments()          # -> environment names, A-Z
families = studio.ListMaterialFamilies()      # -> "Gems", "Grounds", "Metals", "Misc", ...
metals   = studio.ListMaterials("Metals")     # -> material names inside one family, A-Z

All three are read-only: they read the folders and return, they do not touch the document, they need no Transaction, and unlike the rest of RenderStudioApi they do not run the licence check.

Discover, then apply

The round trip these lists exist for:

from ArtisanPlugin.Scripting import RenderStudioApi as studio, Transaction

env = next(n for n in studio.ListEnvironments() if "Studio" in n)
gold = next(n for n in studio.ListMaterials("Metals") if "Yellow" in n)

with Transaction.Begin("Stage the scene"):
    studio.ApplyEnvironment(env)
    studio.ApplyMaterial("Metals", gold, objectIds)

Every string that comes out of a list is guaranteed to be accepted by ApplyEnvironment and ApplyMaterial verbatim.

ListEnvironments

names = studio.ListEnvironments()

The environment tiles in the panel’s Environment tab — every .renv file in the user’s Environments folder, file extension stripped, sorted alphabetically with a case-insensitive comparison. Returns an IReadOnlyList<string>, which arrives in Python as a normal read-only sequence.

If the folder is missing or unset, the method returns an empty list; it does not throw. An empty result therefore means “nothing installed”, not “something went wrong”.

ListMaterialFamilies

families = studio.ListMaterialFamilies()

One entry per sub-folder of the Materials folder, sorted the same way. On a stock installation that is Metals, Gems, Grounds and Misc — the panel’s four material tabs. Because a family is just a folder, a custom folder dropped in beside them shows up here and works everywhere a family name is accepted.

Same empty-list-not-an-exception behaviour as ListEnvironments when the Materials folder is missing.

ListMaterials

names = studio.ListMaterials(family)          # family is required

The .rmtl files inside one family, extension stripped, sorted alphabetically. This is the one catalog method that throws, because it has to resolve the family first:

  • family null, empty or whitespace → ArgumentException("A material family is required (see ListMaterialFamilies()).")
  • family not found → ArgumentException("No material family named 'X'. Available: Gems, Grounds, Metals, Misc.") — the message lists what is actually installed, or (none installed) when the Materials folder holds no families at all.

A family that exists but holds no .rmtl files returns an empty list.

How names are matched

Everywhere a name or a family is accepted, the same rules apply, and they are looser than the strings the lists hand back:

Behaviour
CaseIgnored. "metals", "Metals" and "METALS" all resolve to the same folder; the same holds for environment and material names.
Leading and trailing whitespaceTrimmed from the argument before matching. " Yellow Gold " finds Yellow Gold.
Internal whitespaceSignificant. "YellowGold" does not find Yellow Gold.
Partial namesNot supported. Matching is whole-name equality, never a prefix or a substring — do the filtering yourself, as in the example above.
Unknown nameThrows ArgumentException, with the available names listed in the message.

The family name is also canonicalised on the way through: ApplyMaterial("metals", ...) resolves the folder and then works with the folder’s real name, Metals, so error messages and the material’s internal tag always read the same regardless of how you spelled the argument.

Nothing here is cached. Each call re-reads the folder, so a material dropped into the library mid-session is picked up by the next call without a restart.