SceneBuilder#

This example plugin builds a Maya shot scenefile by importing all USD assets which are linked to the current shot.

The import can be triggered from a custom menu in the Project Browser.

See the section for Single File Plugins on how to load this example.

# SceneBuilder.py

name = "SceneBuilder"
classname = "SceneBuilder"


from qtpy.QtWidgets import *


class SceneBuilder:
    def __init__(self, core):
        self.core = core
        self.version = "v1.0.0"

        # only in Maya
        if self.core.appPlugin.pluginName == "Maya":
            self.core.registerCallback("onProjectBrowserStartup", self.onProjectBrowserStartup, plugin=self)
            self.core.registerCallback("postInitialize", self.postInitialize, plugin=self)

            if self.core.pb:
                self.onProjectBrowserStartup(self.core.pb)

            if self.core.status != "starting":
                self.postInitialize()

    def postInitialize(self):
        # set the function, which handles the import for USD files
        importKwargs = {"type": "USD Import", "importFunction": self.maya_importUsd}
        self.core.appPlugin.importHandlers[".usd"] = importKwargs
        self.core.appPlugin.importHandlers[".usda"] = importKwargs
        self.core.appPlugin.importHandlers[".usdc"] = importKwargs

    def onProjectBrowserStartup(self, origin):
        # add a Scene Builder menu to the Project Browser
        origin.myMenu = QMenu("Scene Builder")
        origin.myMenu.addAction("Import connected assets", self.onImportTriggered)
        origin.menubar.addMenu(origin.myMenu)

    def onImportTriggered(self):
        # get the entity from the current scenefile
        fileName = self.core.getCurrentFileName()
        currentEntity = self.core.getScenefileData(fileName)

        if currentEntity.get("type") != "shot":
            self.core.popup("You need to be in a shot scenefile to use the scene builder.")
            return

        sm = self.core.getStateManager()
        with self.core.waitPopup(self.core, "Gathering products...") as popup:
            productsToImport = []

            # find out which assets are connected to our current shot
            entities = self.core.entities.getConnectedEntities(currentEntity)

            # find products with the "usd" tag for each entity
            for centity in entities:
                products = self.core.products.getProductsByTags(centity, ["usd"])
                productsToImport += products

            for idx, product in enumerate(productsToImport):
                if "asset_path" not in product:
                    continue

                # update popup text
                text = "Importing %s (%s/%s)" % (product["asset_path"], idx+1, len(productsToImport))
                popup.msg.setText(text)
                QApplication.processEvents()

                # get filepath and import it
                payloadPath = self.core.products.getLatestVersionpathFromProduct(product["product"], entity=product)
                primPath = "/assets/" + product["asset_path"]
                sm.importFile(payloadPath)
                print("added file to stage: %s - %s" % (primPath, payloadPath))

    def maya_importUsd(self, filepath, kwargs):
        mode = "reference"  # can be "layer"
        return self.core.getPlugin("USD").api.maya_importUsdStage(filepath, kwargs, mode=mode)