class MatUpdater:
    def __init__(self):
        self.project = Project()

    def updateAll(self):
        obj = hou.node("/obj")
        mat = hou.node("/mat")
        for node in obj.allSubChildren():
            if node.isMaterialManager():
                for material in node.children():
                    self.updateOne(material)

        for node in mat.children():
            self.updateOne(node)

        qd.message("Updated all materials")

    def updateOne(self, mat):
        assetList = self.project.list_assets()
        for asset in assetList:
            asset = re.sub(r'\W+', '', asset)

        typeName = mat.type().name()
        if typeName not in assetList:
            return  #not a material from the pipe, move on

        if mat.isLockedHDA():
            mat.allowEditingOfContents()
        mat.matchCurrentDefinition()
        mat.allowEditingOfContents()

        print(mat.name())
Esempio n. 2
0
 def go(self):
     project = Project()
     asset_list = project.list_assets()
     self.item_gui = sfl.SelectFromList(l=asset_list,
                                        parent=maya_main_window(),
                                        title="Select an asset to clone")
     self.item_gui.submitted.connect(self.results)
Esempio n. 3
0
    def export(self):

        project = Project()
        asset_list = project.list_assets()

        self.item_gui = sfl.SelectFromList(
            l=asset_list,
            parent=maya_main_window(),
            title="Select an asset to export to")
        self.item_gui.submitted.connect(passAlong)
class AssetPublisher:
    def __init__(self):
        self.project = Project()

    def publish(self):
        asset_list = self.project.list_assets()

        self.item_gui = sfl.SelectFromList(
            l=asset_list, parent=hou.ui.mainQtWindow(), title="Select an asset to publish")
        self.item_gui.submitted.connect(self.results)
    
    def results(self, value):
        self.asset_name = value[0]

        body = Project().get_asset(self.asset_name)
        if not body:
            body = self.project.create_asset(self.asset_name)
        if not body:
            qd.error("Something broke :'(")
            return
        self.element = body.get_element(Asset.USD)
        self.path = os.path.join(self.element._filepath, "temp.usda")

        selection = hou.selectedNodes()
        if len(selection) != 1:
            qd.error("Please select the last node in the network and try again.")
            return
        
        out = selection[0]

        rop = hou.node("/stage").createNode("usd_rop")
        rop.setInput(0, out)
        rop.parm("lopoutput").set(self.path)
        rop.parm("enableoutputprocessor_simplerelativepaths").set(0)
        rop.parm("execute").pressButton()

        rop.destroy()

        publishes = self.element.list_publishes()
        publishes_string_list = ""
        for publish in publishes:
            label = publish[0] + " " + publish[1] + " " + publish[2] + "\n"
            publishes_string_list += label

        self.input = qd.HoudiniInput(parent=hou.qt.mainWindow(), title="Comment ", info=publishes_string_list)
        self.input.submitted.connect(self.comment_results)

    def comment_results(self, value):
        comment = str(value)
        
        username = Environment().get_user().get_username()
        name = self.asset_name

        self.element.update_app_ext(".usda")
        self.element.publish(username, self.path, comment, name)
    def publish_asset(self, solaris):
        '''
        this is what's called when the button is pushed.
        '''
        project = Project()

        asset_list = project.list_assets()
        self.item_gui = sfl.SelectFromList(l=asset_list,
                                           parent=hou.ui.mainQtWindow(),
                                           title="Select an asset to publish")
        # call asset results function here to be used once selected
        if solaris:
            self.item_gui.submitted.connect(self.solaris_asset_results)
        else:
            self.item_gui.submitted.connect(self.asset_results)
'''
quick utility function to check which assets have published materials
'''
import os

from pipe.pipeHandlers.project import Project
from pipe.pipeHandlers.body import Body
from pipe.pipeHandlers.body import Asset
from pipe.pipeHandlers.body import AssetType
from pipe.pipeHandlers.element import Element
from pipe.pipeHandlers.environment import Environment
from pipe.pipeHandlers import pipeline_io

project = Project()
assets = project.list_assets()
output = "\n\n"
for name in assets:
    asset = project.get_asset(name)
    element = asset.get_element(Asset.MATERIALS)
    if element and element.get_last_version() >= 0:
        path = element.get_last_publish()[3]
        out = name + "\n"#+ " material at " + path + "\n"
        output += out

print(output)
class MaterialPublisher:
    def __init__(self):
        self.project = Project()

    def publish(self):
        asset_list = self.project.list_assets()

        self.item_gui = sfl.SelectFromList(l=asset_list,
                                           parent=hou.ui.mainQtWindow(),
                                           title="Select an asset to publish")
        self.item_gui.submitted.connect(self.results)

    def results(self, value):
        self.asset_name = value[0]

        body = Project().get_asset(self.asset_name)
        if not body:
            body = self.project.create_asset(self.asset_name)
        if not body:
            qd.error("Something broke :'(")
            return
        self.element = body.get_element(Asset.MATERIALS)

        self.path = os.path.join(self.element._filepath, "temp.usda")

        selection = hou.selectedNodes()
        if len(selection) != 1:
            qd.error("Please select only the material node and try again.")
            return
        shader = selection[0]
        if shader.type().name == "materiallibrary":
            qd.error(
                "Changes have been made to this publishing tool. Now you must select the material node itself, NOT the material library, to publish it. Please try again."
            )
            return

        #check where we are and move shader node accordingly
        deleteLib = False
        path = shader.path()
        first = path.split("/")[1]
        if first != "stage":
            lib = hou.node("/stage").createNode("materiallibrary")
            deleteLib = True
            shader = hou.copyNodesTo([shader], lib)[0]
        else:
            lib = shader.parent()

        lib.setInput(0, None)
        lib.parm("matpath1").set(value[0])

        #create and save material hda
        if shader.canCreateDigitalAsset():
            hdaPath = os.path.join(self.element._filepath,
                                   self.asset_name + "_main.hda")
            shader = shader.createDigitalAsset(name=re.sub(
                r'\W+', '', self.asset_name),
                                               description=self.asset_name,
                                               hda_file_name=hdaPath,
                                               min_num_inputs=0,
                                               max_num_inputs=0)
            shaderDef = shader.type().definition()
            shaderOptions = shaderDef.options()
            shaderOptions.setUnlockNewInstances(True)
            shaderOptions.setSaveInitialParmsAndContents(True)
            shaderDef.setOptions(shaderOptions)
            shaderDef.save(hdaPath, shader, shaderOptions)
        elif shader.type().name() == re.sub(r'\W+', '', self.asset_name):
            shader.type().definition().updateFromNode(shader)
            shader.type().definition().save(
                shader.type().definition().libraryFilePath())
        else:
            qd.error("Error creating/saving hda. Continuing to save USDA...")

        shader.setName(value[0])

        rop = hou.node("/stage").createNode("usd_rop")
        rop.setInput(0, lib)
        rop.parm("lopoutput").set(self.path)
        rop.parm("enableoutputprocessor_simplerelativepaths").set(0)
        rop.parm("execute").pressButton()

        rop.destroy()
        if deleteLib:
            lib.destroy()

        publishes = self.element.list_publishes()
        publishes_string_list = ""
        for publish in publishes:
            label = publish[0] + " " + publish[1] + " " + publish[2] + "\n"
            publishes_string_list += label

        self.input = qd.HoudiniInput(parent=hou.qt.mainWindow(),
                                     title="Comment ",
                                     info=publishes_string_list)
        self.input.submitted.connect(self.comment_results)

    def comment_results(self, value):
        comment = str(value)

        username = Environment().get_user().get_username()
        name = self.asset_name

        self.element.update_app_ext(".usda")
        self.element.publish(username, self.path, comment, name)
class ObjPublisher:
    def __init__(self):
        self.project = Project()

    def publish(self):
        asset_list = self.project.list_assets()

        self.item_gui = sfl.SelectFromList(l=asset_list,
                                           parent=hou.ui.mainQtWindow(),
                                           title="Select an asset to publish")
        self.item_gui.submitted.connect(self.results)

    def results(self, value):
        self.asset_name = value[0]

        body = Project().get_asset(self.asset_name)
        if not body:
            body = self.project.create_asset(self.asset_name)
        if not body:
            qd.error("Something broke :'(")
            return
        self.element = body.get_element(Asset.GEO)
        self.usdElem = body.get_element(Asset.GEO)
        path = self.element._filepath

        selectedNodes = hou.selectedNodes()
        if len(selectedNodes) != 1:
            qd.error("Select one node to publish its geometry")
            return
        geo = selectedNodes[0]
        if geo.type().name() != "geo":
            qd.error("You can only publish from geo nodes")
            return

        for child in geo.children():
            if child.isDisplayFlagSet():
                #print("hello there from " + child.name())
                cache = geo.createNode("filecache")
                cache.setInput(0, child)
                usd = geo.createNode("usdexport")
                usd.setInput(0, child)

                cache.parm("filemode").set(2)
                cache.parm("file").set(os.path.join(path, "temp.obj"))
                cache.parm("trange").set(0)
                cache.parm("execute").pressButton()

                usd.parm("authortimesamples").set("Never")
                usd.parm("lopoutput").set(os.path.join(path, "temp.usda"))
                usd.parm("execute").pressButton()

                usd.destroy()
                cache.destroy()

                publishes = self.element.list_publishes()
                publishes_string_list = ""
                for publish in publishes:
                    label = publish[0] + " " + publish[1] + " " + publish[
                        2] + "\n"
                    publishes_string_list += label

                self.input = qd.HoudiniInput(parent=hou.qt.mainWindow(),
                                             title="Comment ",
                                             info=publishes_string_list)
                self.input.submitted.connect(self.comment_results)

    def comment_results(self, value):
        comment = str(value)

        username = Environment().get_user().get_username()
        name = self.asset_name
        basePath = self.element._filepath

        #usdElem = self.element.deepcopy()

        path = os.path.join(basePath, "temp.obj")
        self.element.update_app_ext(".obj")
        self.element.publish(username, path, comment, name)

        path = os.path.join(basePath, "temp.usda")
        self.usdElem.update_app_ext(".usda")
        self.usdElem.publish(username, path, comment, name)
Esempio n. 9
0
class Exporter:
    def __init__(self):
        pass

    def go(self, alembic=False, usd=False, obj=False, mb=False, camera=False):
        self.alembic = alembic
        self.usd = usd
        self.obj = obj
        self.mb = mb
        self.camera = camera

        self.project = Project()
        self.chosen_asset = None

        if self.camera and self.alembic:  #previs publish case
            shot_list = self.project.list_shots()

            self.item_gui = sfl.SelectFromList(
                l=shot_list,
                parent=maya_main_window(),
                title="What shot is this camera in?")
            self.item_gui.submitted.connect(self.shot_results)

        else:
            asset_list = self.project.list_assets()

            self.item_gui = sfl.SelectFromList(
                l=asset_list,
                parent=maya_main_window(),
                title="Select an asset to export to")
            self.item_gui.submitted.connect(self.asset_results)

    def export(self):
        publish_info = []
        if self.obj:  #modeling publish case
            publish_info.append(ObjExporter().exportSelected(
                self.chosen_asset))
            #self.publish(publish_info)

            if self.usd:  #modeling publish case
                publish_info.append(USDExporter().exportSelected(
                    self.chosen_asset))
                self.publish(publish_info)

        if self.alembic:  #animation publish case
            shot_list = self.project.list_shots()

            self.item_gui = sfl.SelectFromList(
                l=shot_list,
                parent=maya_main_window(),
                title="What shot is this animation in?")
            self.item_gui.submitted.connect(self.shot_results)

        if self.mb:  #rigging publish case
            publish_info.append(MbExporter().export(self.chosen_asset))
            self.publish(publish_info)

    def asset_results(self, value):
        self.chosen_asset = value[0]

        #check if asset already exists
        #if not, create it
        self.project.create_asset(name=self.chosen_asset)

        self.export()

    def shot_results(self, value):
        self.chosen_shot = value[0]
        print(self.chosen_shot)

        shot = self.project.create_shot(self.chosen_shot)

        #if the shot didn't exist already, set the frame range
        if shot is not None:
            pass

        else:
            print("we're here")
            shot = self.project.get_shot(self.chosen_shot)

        if shot is None:
            print("uh oh stinky")
            return

        #pre-vis publish
        publish_info = []
        if self.camera:
            camera_num = int(shot.get_camera_number())
            if camera_num == 1:  #only one camera in the shot
                self.chosen_asset = "camera1"
                publish_info.append(AlembicExporter().exportSelected(
                    asset_name=self.chosen_asset,
                    shot_name=self.chosen_shot,
                    camera=self.camera))
                self.publish(publish_info)
            else:  #pick which camera to publish
                cam_list = []
                for number in range(1, camera_num + 1):
                    camera_name = "camera" + str(number)
                    cam_list.append(camera_name)

                self.item_gui = sfl.SelectFromList(
                    l=cam_list,
                    parent=maya_main_window(),
                    title="Which camera are you publishing?")
                self.item_gui.submitted.connect(self.camera_results)

        #animation publish
        else:
            publish_info.append(AlembicExporter().exportSelected(
                asset_name=self.chosen_asset,
                shot_name=self.chosen_shot,
                camera=self.camera))
            self.publish(publish_info)

    def camera_results(self, value):
        publish_info = []
        self.chosen_asset = value[0]
        publish_info.append(AlembicExporter().exportSelected(
            asset_name=self.chosen_asset,
            shot_name=self.chosen_shot,
            camera=self.camera))
        self.publish(publish_info)

    def publish(self, publishes):
        publish_info = publishes[0]

        element = publish_info[0]
        path = publish_info[1]

        self.publishes = element.list_publishes()
        publishes_string_list = ""
        for publish in self.publishes:
            label = publish[0] + " " + publish[1] + " " + publish[2] + "\n"
            publishes_string_list += label

        # get comment and update element file with publish info
        comment = qd.input(title="Comment for publish",
                           label=publishes_string_list)
        if comment is None or comment == "":
            comment = "No comment."
        username = Environment().get_user().get_username()

        for pub_info in publishes:
            element = pub_info[0]
            path = pub_info[1]
            element.publish(username, path, comment, self.chosen_asset)
class LayoutUpdater:
    def __init__(self):
        self.project = Project()
        self.assetList = self.project.list_assets()
        for asset in self.assetList:
            asset = re.sub(r'\W+', '', asset)

    def updateAll(self):
        obj = hou.node("/obj")
        for node in obj.children():
            if node.type().name() == "cenoteLayoutNet":
                self.updateLayout(node)

    def updateLayout(self, layout):
        print("updating " + layout.name())
        #reload its usd reference node
        self.reloadUsd(layout)
        #update all materials in the layout's library
        lib = None
        for node in layout.children():
            if node.type().name() == "matnet":
                lib = node

        matList = []
        for mat in lib.children():
            self.reloadMaterial(mat)
            matList.append(mat.name())

        #undo all material assignments (set to 0)
        layout.parm("num_materials").set(0)
        #parse through the material bindings again
        matDict = self.getMatDict(layout)
        self.assignMats(layout, matDict, matList, lib)

        qd.message("Successfully updated " + layout.name())

    def reloadUsd(self, layout):
        refNodePath = layout.parm("loppath").eval()
        refNode = hou.node(refNodePath)
        refNode.parm("reload").pressButton()

    def reloadMaterial(self, matNode):
        typeName = matNode.type().name()
        if typeName not in self.assetList:
            return  #not a material from the pipe, move on

        if matNode.isLockedHDA():
            matNode.allowEditingOfContents()
        matNode.matchCurrentDefinition()
        matNode.allowEditingOfContents()

    def getMatDict(self, layout):
        refNodePath = layout.parm("loppath").eval()
        refNode = hou.node(refNodePath)
        stage = refNode.stage()
        matDict = {}

        for prim in stage.Traverse():
            #print(prim.GetName() + " " + prim.GetTypeName())

            mat_path = prim.GetRelationship("material:binding")
            #we decide what to copy into it's own geometry node by what has its own material
            if mat_path:
                #print(prim.GetName() + " has a material at path " + str(mat_path.GetForwardedTargets()[0]))

                primPaths = ""
                if prim.GetTypeName() == "Mesh":
                    primPaths = primPaths + "@path=" + str(
                        prim.GetPath()) + " "
                else:
                    children = self.getDescendants(prim)
                    for child in children:
                        if child.GetTypeName() == "Mesh":
                            primPaths = primPaths + "@path=" + str(
                                child.GetPath()) + " "

                mat_path = mat_path.GetForwardedTargets()
                if mat_path[0].IsPrimPath():
                    #print(mat_path[0])
                    mat_name = os.path.basename(str(mat_path[0]))
                    #print("\t" + mat_name)

                    if mat_name in matDict.keys():
                        matDict[mat_name] += primPaths
                    else:
                        matDict[mat_name] = primPaths

        return matDict

    def assignMats(self, layout, matDict, matList, library):

        layout.parm("num_materials").set(len(matDict.keys()))
        index = 1

        for mat in matDict.keys():
            if re.sub(r'\W+', '', mat) in matList:
                #this material is already up to date
                matNode = hou.node(library.path() + "/" + mat)

            else:
                #clone in that material's hda to the network
                asset = self.project.get_asset(mat)
                if not asset:
                    print("Well there's your problem :/")
                    continue

                element = asset.get_element(Asset.MATERIALS)
                matNode = None
                if element.get_last_version() >= 0:
                    path = element.get_last_publish()[3]
                    hdaPath = path.split(".")[0] + ".hda"
                    try:
                        hou.hda.installFile(hdaPath)

                        matNode = library.createNode(re.sub(r'\W+', '', mat))
                        matNode.setName(mat, 1)
                        matNode.setMaterialFlag(True)
                    except Exception as e:
                        qd.error(
                            "The material for " + mat +
                            " needs to be republished. Sorry for the inconvenience."
                        )
                        #print(e)

            #assign the material to all the paths
            layout.parm("group" + str(index)).set(matDict[mat])
            if matNode:
                layout.parm("shop_materialpath" + str(index)).set(
                    matNode.path())

            index += 1

    def getDescendants(self, prim):
        all = []
        children = prim.GetChildren()
        all.extend(children)
        for child in children:
            all.extend(self.getDescendants(child))

        return all


#the only part that should need to be redone is the material stuff
#so first, make sure to reload the usda file
#from there, the lop import should be fine, so don't mess with that
#parse through the usda to get the material assignments
#and apply the materials like before

#updating the materials might also be a problem, they won't update automatically but
#there might be a way to force it to update from the hda file, which should take
#care of it.

#for each material node
#check if it's an hda
#check if it's unlocked, if not then unlock it
#call hou.Node.matchCurrentDefinition()
#unlock it again