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:
familynull, empty or whitespace →ArgumentException("A material family is required (see ListMaterialFamilies()).")familynot 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 | |
|---|---|
| Case | Ignored. "metals", "Metals" and "METALS" all resolve to the same folder; the same holds for environment and material names. |
| Leading and trailing whitespace | Trimmed from the argument before matching. " Yellow Gold " finds Yellow Gold. |
| Internal whitespace | Significant. "YellowGold" does not find Yellow Gold. |
| Partial names | Not supported. Matching is whole-name equality, never a prefix or a substring — do the filtering yourself, as in the example above. |
| Unknown name | Throws 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.