Skip to main content

Processing and Reimporting

Listing processing actions​

rpts.list_actions() returns every processing action that RPTS knows about. Each entry is a dict with the action name and its params. Each param is keyed by its snake_case name and holds its display name, a description and its internal dot-path.

# this script is written for RPTS 0.9.8

import rpts


def print_actions():
for action in rpts.list_actions():
print(action["name"])
for key, info in action["params"].items():
print(f" {key} ({info['display_name']}): {info['description']}")


print_actions()
tip

list_actions() never raises. An empty list means the actions folder is set up but contains no actions. If anything goes wrong while reading them, you get a single entry instead, {"name": "<error: ...message...>", "params": {}}. This happens when the actions folder, its version folder (such as v1.2.3) or its processing folder is missing, or when any action's meta.json is unreadable or incomplete, in which case even the valid actions are not returned. Check for it before you use the result:

actions = rpts.list_actions()
if actions and actions[0]["name"].startswith("<error:"):
print(actions[0]["name"])

Running an action by name​

rpts.process_action(action, params=None) runs one action on the loaded asset. The action argument is the action name exactly as list_actions() shows it, for example 'Decimate Mesh'. The params dict can use any of three key styles, and they can be mixed:

Key styleExampleMeaning
snake_case'face_target'The param name in lower case with underscores
Display name'Face Target'The name as shown in the RPTS interface
Dot-path'optimize.3dModel...'The raw internal path of the setting

An unknown key raises a ValueError that lists the available snake_case keys.

# this script is written for RPTS 0.9.8

import rpts


def decimate_to_faces(face_target):
rpts.process_action(
"Decimate Mesh",
params={
"face_target": face_target, # snake_case key
"preserve_topology": True, # snake_case key
},
)
print(f"Decimate Mesh ran with face target {face_target}.")


decimate_to_faces(5000)

Scoping processing to a selection​

Processing already respects the current selection: when the engine runs a processing config and finds a non-empty selection, it processes only the selected nodes, and falls back to the whole asset when nothing is selected. rpts.process_action() is built on this, so scoping a run to part of the scene is just a two-step pattern:

  1. rpts.select_nodes([...]) with the top-level node(s) you want to affect. As covered in Selection and visibility, selecting a node also selects its entire subtree, so selecting a single group node is enough to scope processing to every mesh underneath it.
  2. Call rpts.process_action(action, params) as usual - no extra scoping argument is needed.

The script below reuses the Decimate Mesh config from the example above, but first selects a single node so that only its subtree is decimated:

# this script is written for RPTS 0.9.8

import rpts


def decimate_subtree(group_node, face_target):
asset = rpts.get_asset()
if asset is None:
print("No model currently loaded.")
return

rpts.select_nodes([group_node]) # also selects every node in its subtree

rpts.process_action(
"Decimate Mesh",
params={
"face_target": face_target,
"preserve_topology": True,
},
)
print(f"Decimated the subtree under '{group_node.path}' to face target {face_target}.")


decimate_subtree(rpts.get_asset().root_node, 50000)
note

The API also has a separate rpts.process_asset_selection(nodepaths_or_nodes, invert_selection, config) function, which can scope a single processing call to a given set of nodes (or to everything except them, with invert_selection=True) without changing the visible selection. It takes a full JSON config string rather than the params dict used by process_action(), and unlike the functions on this page it does not accept a bare path string or a single Node - only a list. It is not the pattern documented here, and this page does not cover it in detail; reach for select_nodes() plus process_action() first.

Reimporting a CAD asset with an import config​

rpts.reimport_asset(config) reimports the currently loaded asset using a JSON import config string. It returns the reimported asset, or None if the reimport failed.

The example below sets the CAD tessellation options. The keys match the import section of the CAD tessellation example in the 3D Processor CLI tutorial.

# this script is written for RPTS 0.9.8

import json

import rpts


def reimport_cad(tessellation="fine", max_angle=40, max_surface_deviation=0.4):
import_config = {
"version": 1.5,
"import": {
"CAD": {
"tessellationResolution": tessellation,
"removeTJunctions": False,
"sewTolerance": 0.0,
"maxSurfaceDeviation": max_surface_deviation,
"maxAngle": max_angle,
"maxEdgeLength": 0,
}
},
}

asset = rpts.reimport_asset(json.dumps(import_config))
if asset is None:
print("Reimport failed.")
else:
print("Reimport finished.")
return asset


reimport_cad(tessellation="fine", max_angle=40, max_surface_deviation=0.4)
tip

Reimporting re-reads the asset, so material assignments and other changes made in RPTS may need to be re-applied afterwards. The materials page shows how to save and restore them.