Skip to main content

Selection and Visibility

Selection​

The selection is what you see highlighted in the scene tree and viewport. The main calls are:

  • rpts.get_selected_nodes() - returns the selected nodes as a list of Node objects. Use rpts.get_selection(as_paths=True) if you only need the paths as strings.
  • rpts.select_nodes(nodes) - adds the given nodes to the current selection.
  • rpts.deselect_nodes(nodes) - removes the given nodes from the selection.
  • rpts.set_selection(nodes) - replaces the whole selection with the given nodes.

select_nodes, deselect_nodes and set_selection accept a single node or a list of nodes, and a node can be given either as a Node object or as its path string.

note

Selecting a node always expands to its entire subtree in the stored selection. rpts.select_nodes([group_node]) also selects every descendant of group_node, including all of its mesh nodes, and get_selected_nodes()/get_selection() already reflect that expanded set. You don't need to walk the hierarchy and select each mesh node individually — see the example below.

Visibility​

Visibility works the same way as selection, but for the viewport:

  • rpts.hide_nodes(nodes) - hides the given nodes and everything beneath them.
  • rpts.show_nodes(nodes) - shows the given nodes, and also their ancestors, since a node cannot render while one of its ancestors is hidden.
  • rpts.get_hidden_nodes() - returns the nodes that are explicitly hidden. Pass effective=True to also include their descendants.
  • rpts.get_visible_nodes() - the complement of get_hidden_nodes().
  • rpts.is_node_visible(path) - returns True if the node's own visibility flag is not hidden. It takes a single path string.
  • rpts.set_nodes_visible(paths, visible) - a lower-level call that takes a list of path strings only, with True to show and False to hide.
note

is_node_visible() only looks at the node's own flag. A node can report as visible while one of its ancestors is hidden, so use get_hidden_nodes(effective=True) when you need the true rendered state.

Deleting nodes​

Three functions remove nodes from the scene:

  • rpts.delete_nodes(nodes) - deletes the given nodes and their subtrees.
  • rpts.delete_empty_nodes() - deletes every node whose subtree contains no mesh at all.
  • rpts.delete_hidden_nodes() - deletes every explicitly hidden node and everything beneath it.

Each of them returns the list of paths it deleted.

danger

Deleting nodes is not undoable. Ctrl+Z will not bring them back. Before running any delete function, save your work or keep a copy of the asset. For delete_hidden_nodes(), you can check what it will remove first with rpts.get_hidden_nodes().

Example: selecting a group also selects its whole subtree​

This script selects a single group node and then reads back the selection, to show that every descendant — including every mesh node underneath it — is already part of the result. There is no manual tree walk.

# this script is written for RPTS 0.9.8

import rpts


def select_group_and_report():
asset = rpts.get_asset()
if asset is None:
print("No model currently loaded.")
return

group_node = asset.root_node # replace with any group node, e.g. one found with a filter

rpts.select_nodes([group_node])

selected = rpts.get_selected_nodes()
print(f"Selected {len(selected)} node(s) after selecting '{group_node.path}'.")
for node in selected:
print(" ", node.path)


select_group_and_report()
tip

Selecting group_node selects its entire subtree in a single call: every descendant node, mesh nodes included, is already in get_selected_nodes(). This is also why scoped processing only needs select_nodes() on the top-level nodes you care about, not on every mesh underneath them.

Example: hide nodes matching a naming convention​

This script filters nodes by name with rpd.NodeFilter and asset.query_nodes, then hides every match. The two patterns below are only placeholders, so adapt them to whatever naming convention your model uses. See Filtering nodes for the full NodeFilter/query_nodes reference.

# this script is written for RPTS 0.9.8

import rpts
import rpd

asset = rpts.get_asset()

filters = [
rpd.NodeFilter(
target=rpd.NodeFilterTarget.NODE_NAME,
match_type=rpd.FilterMatchType.STARTS_WITH,
pattern="Proxy_",
case_sensitive=False,
),
rpd.NodeFilter(
target=rpd.NodeFilterTarget.NODE_NAME,
match_type=rpd.FilterMatchType.ENDS_WITH,
pattern="_COL",
case_sensitive=False,
),
]

matches = asset.query_nodes(
filters, rpd.QueryMode.MATCH_ANY
)

rpts.hide_nodes(matches)

print(f"Hidden {len(matches)} matching nodes.")
tip

rpd.QueryMode.MATCH_ANY matches a node if it matches either filter, so the script hides every node that matches at least one of them. Hiding a node also hides its whole subtree. rpts.hide_nodes() prints how many nodes actually changed state, so nodes that were already hidden are not counted.

To reverse it, run the same query again to collect the nodes and pass them to rpts.show_nodes(). rpts.get_hidden_nodes() lists everything that is currently hidden.

Next steps​

Hidden and selected nodes are often the first step before a material or processing change. See Basics and filtering for walking the hierarchy and reading metadata, and Materials for a complete export and re-import example.