Materials
The rpts.materials functions work with the TS material library, which is a folder of .mtlx files, and with the materials attached to the loaded asset. They list materials, assign them to meshes, and export and import material assignments. Access them as rpts.materials.<name>().
Listing materials
list_library()
Returns every material currently scanned into the TS material library. The library is the folder of .mtlx files under <exe_dir>/materials. The category of each entry comes from the material's immediate parent folder, and it is empty for materials that sit directly in the library root.
Returns: a list of dicts, each with these keys:
name(str): the sanitized name authored in the.mtlxfile.path(str): the disk path of the.mtlxfile.category(str): the parent folder name, or an empty string.original_name(str): the scene material's real, unsanitized name, as stored byexport_scene_as_library(). For libraries exported without it, this equalsname.
[
{
"name": "Rusty Metal",
"path": "C:/.../materials/metal/rusty.mtlx",
"category": "metal",
"original_name": "Rusty Metal",
},
]
list_scene_materials()
Returns every material attached to the loaded asset itself. These are materials that came with the model's source file, such as a character's per-part materials. This is different from the external library returned by list_library().
Returns: a list of dicts with the keys name, path, and category. Each path is a scene:// reference to an existing material in the scene, and you can pass it directly to assign().
[
{"name": "body", "path": "scene://Materials/body", "category": "Surface Materials"},
]
Assigning materials
assign(nodes, material_path)
Assigns a material to one or more nodes or meshes. The whole batch is a single undoable operation, so Ctrl+Z reverts all of it at once. Any node that is not itself a mesh is expanded to all of its mesh descendants.
nodes(str, Node, or iterable of either): a single path, a singlerpd.Node, or an iterable of either.material_path(str or dict): one of the following:- a
.mtlxdisk path, which is thepathvalue fromlist_library(); - a dict as returned by
list_library(), in which case itspathfield is used; - a
scene://material path, as returned bylist_scene_materials().
- a
Returns: an int, the number of meshes whose material binding actually changed. Meshes that were already bound to this material are skipped and not counted. This is not the number of nodes passed in.
export_assignments_to_csv(csv_path)
Exports the current mesh-to-material assignment of every mesh node in the scene to a CSV file. You can edit that file by hand and load it again with assign_from_csv().
Only mesh nodes are written. Non-mesh nodes, such as groups, are skipped. Only material slot 0 is considered.
csv_path(str): the destination path. An existing file at this path is overwritten.
Returns: an int, the number of rows written. This is the number of mesh nodes found.
assign_from_csv(csv_path, library=None)
Reads a CSV file with node and material_name columns, as written by export_assignments_to_csv(), and assigns the named material to each listed node. Rows that resolve to the same material are batched into one assign() call.
Each material_name is matched against two sources, in this order:
- The asset's own scene materials, by exact name.
- If not found there, the external library. The name is matched against the material's
original_name, then against the library name and file name, then against the CSV name after sanitizing.
Matching scene materials first lets an unedited export and import round-trip succeed, including for a model's own materials that have no entry in the external library.
If the same name exists in more than one library category, the name is treated as ambiguous and the row is skipped. To pick a category, pass it in library.
csv_path(str): the path to the CSV file to read.library(str): the name of one library category, from thecategoryvalue inlist_library(). Default:None. When set, scene materials are not searched, and names are resolved only against that category. Use this to pick up a library material whose name is the same as a current scene material's name.
Returns: a tuple (assigned, skipped):
assigned(int): the number of rows that resulted in an assignment.skipped(list of tuples): each tuple is(node_path, material_name, reason)for a row that was not assigned. Thereasonis one of these:"no material specified":material_nameis empty."node not found":node_pathis not in the current scene."material not found": the name matched neither the scene materials nor the library. This can only happen whenlibraryisNone."material not found in library '<library>'": the name was not found in the given library category."ambiguous material name (matches libraries: A, B)": the name matches library materials in two or more categories, and nolibrarywas given to choose one."ambiguous material name within library '<library>'": the name matches two or more different materials inside the same category.
export_scene_as_library(library_name)
Exports every material currently used in the scene as a new library folder under the TS material library root. Each export captures the material's current edited values, including colors, roughness, textures and UV transforms, not only the assignment. Use this to save materials edited in the app as reusable library entries. export_assignments_to_csv() and assign_from_csv() only round-trip which material is assigned to which mesh. They do not save material values.
The new folder appears as a category in the material library panel. This call triggers the scan itself, so the new category shows up without restarting the app. The scene itself is not changed.
library_name(str): the name of the new library folder, which becomes a new category.
Returns: a list of dicts, one for each scene material that was processed:
[
{"name": "body", "success": True, "path": "C:/.../MyLibrary/body.usda"},
{"name": "mouth", "success": False, "path": "", "error": "..."},
]
Each dict has name, success, and path. A failed entry also has an error key.