Skip to content

Instantly share code, notes, and snippets.

  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save BigRoy/3873421057d9b8bf717b470dd28cdd4c to your computer and use it in GitHub Desktop.
OpenPype v3 query the representations from a published file path
from openpype.pipeline import legacy_io, Anatomy
path = r"/path/to/representation/file.abc"
anatomy = Anatomy()
success, rootless_path = anatomy.find_root_template_from_path(path)
assert success
for result in legacy_io.find({"files.path": rootless_path, "type": "representation"}):
print(result)
@BigRoy
Copy link
Author

BigRoy commented May 23, 2023

Example from Felix (Normaal Animation) as shared on Ynput discord here:

That's code for Blender, but could be used in other cases I think. The idea is to retrieve the representation from the filename and resolve the path with the local root. That's for multi-site purpose, when broken.

from pathlib import Path
import re

import bpy

from openpype.pipeline.anatomy import Anatomy
from openpype.pipeline.legacy_io import Session, find_one


print("Conforming lib filepaths...")

paths_fixed = []

# Retrieve representations by file name
for lib in bpy.data.libraries:
    regex = re.compile(f"{re.escape(Path(lib.filepath).name)}$")
    repre_doc = find_one({"files.path": regex, "type": "representation"})

    anatomy = Anatomy()
    remapped_path = Path(anatomy.fill_root(repre_doc["files"][0]["path"])).resolve()
    if remapped_path != Path(lib.filepath).resolve():
        paths_fixed.append((lib.filepath, remapped_path))
        lib.filepath = remapped_path

@BigRoy
Copy link
Author

BigRoy commented May 23, 2023

Example for Maya to "recontainerise" references as if they were using the ReferenceLoader loader.

import json
from maya import cmds
from openpype.hosts.maya.api import lib
from openpype.hosts.maya.api import pipeline

from openpype.pipeline import (
    registered_host,
    legacy_io,
    Anatomy
)


def get_representation_from_path(path, anatomy=None):
    """Return representation from any of its absolute filepaths"""
    if anatomy is None:
        anatomy = Anatomy()
        
    _success, rootless_path = anatomy.find_root_template_from_path(path)
    return legacy_io.find_one({"files.path": rootless_path, "type": "representation"})


def is_in_a_container(node):
    """Return whether node is member of a container"""
    sets = cmds.listSets(o=node) or []
    if any(
        s for s in sets 
        if cmds.attributeQuery("id", node=s, exists=True)
        and cmds.getAttr(f"{s}.id") == "pyblish.avalon.container"
    ):
        return True
    else:
        return False
        
        

anatomy = Anatomy()
for reference in cmds.ls(references=True):
    try:
        filepath = cmds.referenceQuery(reference, filename=True, withoutCopyNumber=True)
    except Exception:
        # Ignore invalid reference nodes
        continue
    
    if is_in_a_container(reference):
        # Ignore references that are already in a container
        continue
        
    filepath = os.path.normpath(filepath)
    representation = get_representation_from_path(filepath, anatomy=anatomy)
    if representation is None:
        # No representation found
        continue
    
    namespace = cmds.referenceQuery(reference, namespace=True).strip(":")
    subset_name = representation["context"]["subset"]
    
    # Build fake context since containerise only requires the representation
    context = {"representation": representation}
    
    pipeline.containerise(
        name=subset_name,
        namespace=namespace,
        nodes=[reference],
        context=context,
        loader="ReferenceLoader"
    )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment