Last active
October 11, 2023 07:05
-
-
Save BigRoy/d3f982819176291dd5ec1a88898c3313 to your computer and use it in GitHub Desktop.
Convert Maya USD Ufe Material selection to bound objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from maya import cmds | |
import mayaUsd.ufe | |
from pxr import Usd, UsdShade | |
from collections import defaultdict | |
def pairwise(iterable): | |
it = iter(iterable) | |
return zip(it, it) | |
def iter_ufe_usd_selection(): | |
for path in cmds.ls(selection=True, | |
ufeObjects=True, | |
long=True, | |
absoluteName=True): | |
if "," not in path: | |
continue | |
node, ufe_path = path.split(",", 1) | |
if cmds.nodeType(node) != "mayaUsdProxyShape": | |
continue | |
yield path | |
def get_ufe_path(proxy, prim): | |
prim_path = str(prim.GetPath()) | |
return "{},{}".format(proxy, prim_path) | |
def convert_ufe_paths_to_bound_geo( | |
ufe_paths=None, | |
material_purpose=UsdShade.Tokens.allPurpose | |
): | |
"""Convert USD material selection or ufe material node paths to bound objects. | |
Arguments: | |
ufe_paths (Optional[list]): UFE material paths to operate on. | |
If not provided current selection will be used. | |
material_purpose (UsdShade.Token): Material purpose | |
to return bounds for. Defaults to all purposes. | |
Returns: | |
list: UsdPrim UFE paths for objects bound to input materials. | |
""" | |
if ufe_paths is None: | |
ufe_paths = list(iter_ufe_usd_selection()) | |
targets = [] | |
prims_per_proxy = defaultdict(set) | |
for path in ufe_paths: | |
prim = mayaUsd.ufe.ufePathToPrim(path) | |
if not prim: | |
continue | |
proxy, _prim_path = path.split(",", 1) | |
prims_per_proxy[proxy].add(prim) | |
bindings = defaultdict(set) | |
for proxy, prims in prims_per_proxy.items(): | |
stage = next(iter(prims)).GetStage() | |
stage_prims = list(stage.Traverse()) | |
bounds = UsdShade.MaterialBindingAPI.ComputeBoundMaterials(stage_prims, material_purpose) | |
for stage_prim, material, relationship in zip(stage_prims, *bounds): | |
material_prim = material.GetPrim() | |
if not material_prim.IsValid(): | |
continue | |
bindings[material_prim].add(stage_prim) | |
for prim in prims: | |
for geo_prim in bindings.get(prim, []): | |
ufe_path = get_ufe_path(proxy, geo_prim) | |
targets.append(ufe_path) | |
return targets | |
targets = convert_ufe_paths_to_bound_geo() | |
if targets: | |
cmds.select(targets, replace=True, noExpand=True) |
For those curious - this is what HoudiniUsdBridge does to Select All Bound Geometry. Originally came up on SideFX Forums for this question.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The reverse can be found here: objects to bound material
Written for Maya USD issue: Select objects bound to material #3328