Search code examples
python-2.7maya

import objects from references in maya


I have scenes with multiple references that I want to import in the current scene
I have found how to do it when I have only 1 level of referencing, like this :

scene
...|_reference

but it doesn't work when I have multiple referencing level because the hierachy isn't respected

my hierarchy :

scene
...|_reference
.........|_reference1
..............|_reference2

here is my code :

import maya.cmds as cmds
refs = cmds.ls(type='reference')
print refs
for ref in refs:
    rFile = cmds.referenceQuery(ref, f=True)
    cmds.file(rFile, importReference=True)

it returns this in multiple level of referencing :

line 8: The specified reference file cannot be imported because its parent file is not the top-level scene file. # 

how can I import all my references in my scene with python, with multiple levels of references ?

thank you


Solution

  • There's a few rules Maya needs you to follow:

    1. You can only import top-level references. If it's a nested reference it will throw an error.
    2. The reference must be loaded or it will throw an error.

    The issue with calling cmds.ls(type='reference') is that it will return ALL references, including nested ones, which would break rule #1.

    It's a bit of a gotcha to get it to work because I thought there was a simple parameter you can pass to importReference to import its whole chain of nested references, but there doesn't seem to be any. So this is how to do it: Iterate through all top-level references only and import them. This will cause all direct children references to become top-level now, so re-iterate to import those. Rinse and repeat until there is no more to iterate with.

    Here's how that can be done (this will skip all unloaded references):

    import maya.cmds as cmds
    
    
    all_ref_paths = cmds.file(q=True, reference=True) or []  # Get a list of all top-level references in the scene.
    
    for ref_path in all_ref_paths:
        if cmds.referenceQuery(ref_path, isLoaded=True):  # Only import it if it's loaded, otherwise it would throw an error.
            cmds.file(ref_path, importReference=True)  # Import the reference.
    
            new_ref_paths = cmds.file(q=True, reference=True)  # If the reference had any nested references they will now become top-level references, so recollect them.
            if new_ref_paths:
                for new_ref_path in new_ref_paths:
                    if new_ref_path not in all_ref_paths:  # Only add on ones that we don't already have.
                        all_ref_paths.append(new_ref_path)