Beispiel #1
0
    def dcc_geo(self,
                parent,
                asset_name,
                already_tabbed_in_node=None,
                excluded_departments=[],
                character=False,
                mode=UpdateModes.CLEAN):
        # Set up the body/elements and check if it's an asset.
        body = Project().get_body(asset_name)
        if not body.is_asset():
            qd.error("Must be an asset.")
            return None

        # Set up the nodes, name geo
        node = already_tabbed_in_node if already_tabbed_in_node else parent.createNode(
            "dcc_geo")
        if character:
            node.setName("geo")
        else:
            try:
                node.setName(asset_name.title())
            except:
                node.setName(asset_name.title() + "_1", unique_name=True)

        # Set the asset_name data tag
        data = node.parm("data").evalAsJSONMap()
        data["asset_name"] = asset_name
        node.parm("data").set(data)

        # Set the contents to the nodes that belong to the asset
        self.update_contents_geo(node, asset_name, excluded_departments, mode)

        return node
Beispiel #2
0
    def dcc_character(self,
                      parent,
                      asset_name,
                      already_tabbed_in_node=None,
                      excluded_departments=[],
                      mode=UpdateModes.CLEAN,
                      shot=None):

        # Set up the body/elements and make sure it's a character
        body = Project().get_body(asset_name)
        if not body.is_asset() or not body.get_type() == AssetType.CHARACTER:
            qd.error("Must be a character.")
            return None

        # If there's an already tabbed in node, set it to that node
        node = already_tabbed_in_node if already_tabbed_in_node else parent.createNode(
            "dcc_character")
        try:
            node.setName(asset_name.title())
        except:
            node.setName(asset_name.title() + "_1", unique_name=True)
        node.parm("asset_name").set(asset_name)

        # Set the asset_name data tag
        data = node.parm("data").evalAsJSONMap()
        data["asset_name"] = asset_name
        node.parm("data").set(data)

        # Set the contents to the character's nodes
        self.update_contents_character(node, asset_name, excluded_departments,
                                       mode, shot)
        return node
Beispiel #3
0
def post_publish(element, user, published=True, comment="No comment."):
    scene_file, created_new_file = get_scene_file()

    if published:
        if not mc.file(q=True, sceneName=True) == '':
            mc.file(save=True, force=True)  #save file

        scene_prep()

        username = user.get_username()
        dst = element.publish(username, scene_file, comment)

        #Ensure file has correct permissions
        try:
            os.chmod(dst, 0660)
        except:
            print("Setting file permissions failed badly.")

        # Export JSON
        print('Publish Complete. Begin Exporting JSON if set.')
        body = Project().get_body(element.get_parent())

        if body and body.is_asset():
            if body.get_type() == AssetType.SET or body.get_type(
            ) == AssetType.SHOT:
                json_export = JSONExporter()
                json_export.go(body, body.get_type())

        convert_to_education()
Beispiel #4
0
 def tab_in(self,
            parent,
            asset_name,
            already_tabbed_in_node=None,
            excluded_departments=[]):
     print "Creating node for {0}".format(asset_name)
     body = Project().get_body(asset_name)
     if body is None or not body.is_asset():
         qd.error(
             "Pipeline error: This asset either doesn't exist or isn't an asset."
         )
         return
     if body.get_type() == AssetType.CHARACTER:
         return self.dcc_character(parent, asset_name,
                                   already_tabbed_in_node,
                                   excluded_departments)
     elif body.get_type() == AssetType.PROP:
         return self.dcc_geo(parent, asset_name, already_tabbed_in_node,
                             excluded_departments)
     elif body.get_type() == AssetType.SET:
         return self.dcc_set(parent, asset_name, already_tabbed_in_node)
     else:
         qd.error(
             "Pipeline error: this asset isn't a character, prop or set.")
         return
Beispiel #5
0
    def update_contents_geo(self,
                            node,
                            asset_name,
                            excluded_departments=[],
                            mode=UpdateModes.SMART,
                            shot=None):

        # Set up the body/elements and make sure it's not an actor. Just do some simple error checking.
        body = Project().get_body(asset_name)
        if body is None:
            qd.error("Asset doesn't exist.")
            return None
        if not body.is_asset() or body.get_type(
        ) == AssetType.SET or "dcc_geo" not in node.type().name():
            qd.error("Must be a prop or actor.")
            return None

        # Get interior nodes
        importnode = node.node("import")
        inside = node.node("inside")

        # Set the asset_name and reload
        if node.parm("asset_name").evalAsString() != asset_name:
            node.parm("asset_name").set(asset_name)
        importnode.parm("reload").pressButton()

        # Tab in each content HDA based on department
        for department in self.dcc_geo_departments:
            # If the department is not excluded, tab-in/update the content node like normal
            if department not in excluded_departments:
                self.update_content_node(
                    node,
                    inside,
                    asset_name,
                    department,
                    mode,
                    inherit_parameters=department == Department.MODIFY)

            # If the department is excluded, we should delete it.
            elif mode == UpdateModes.CLEAN:
                self.destroy_if_there(inside, department)

        inside.layoutChildren()

        # If this prop is being animated, set parms accordingly
        if shot is not None:
            node.parm("space").set("anim")
            node.parm("asset_department").set("rig")
            node.parm("shot").set(shot)

        return node
Beispiel #6
0
 def subnet_type(self, asset_name):
     body = Project().get_body(asset_name)
     if body is None or not body.is_asset():
         qd.error(
             "Pipeline error: This asset either doesn't exist or isn't an asset."
         )
         return
     if body.get_type() == AssetType.ACTOR:
         return "dcc_character"
     elif body.get_type() == AssetType.PROP:
         return "dcc_geo"
     elif body.get_type() == AssetType.SET:
         return "dcc_set"
     else:
         qd.error("Pipeline error: this asset isn't an actor, prop or set.")
         return
Beispiel #7
0
    def exportPropJSON(self, filePath, rootNode, isReference=True, name="", version_number=None):  # TODO: look here for why the set json isn't created properly
        if isReference:
            body = get_body_from_reference(rootNode)
        else:
            body = Project().get_body(name)

        name = body.get_name()

        print("Body: ", str(body))
        print("filepath: ", filePath)
        print("rootNode: ", rootNode)

        if not body or not body.is_asset() or body.get_type() != AssetType.PROP:
            print "The asset %s does not exist as a prop, skipping.".format(name)
            return None

        # Check if verNum is nothing - if so, we need to make it be an int 0
        if not version_number:
            version_number = 0

        firstMesh, path = find_first_mesh(rootNode)
        vertpos1, vertpos2, vertpos3 = get_anchor_points(firstMesh)

        # Put all relevant data into dictionary object
        json_data = {"asset_name": name,
                     "version_number": version_number,
                     "path" : path,
                     "a" : [vertpos1.x, vertpos1.y, vertpos1.z],
                     "b" : [vertpos2.x, vertpos2.y, vertpos2.z],
                     "c" : [vertpos3.x, vertpos3.y, vertpos3.z] }

        print("json data: ", json_data)

        # Write JSON to fill
        jsonRef = json.dumps(json_data)
        wholePath = os.path.join(filePath, os.path.join(filePath, name + "_" + str(version_number) + ".json"))
        outfile = open(wholePath, "w")  # *** THIS IS THE NAME OF THE OUTPUT FILE ***
        outfile.write(jsonRef)
        outfile.close()

        if not isReference:
            qd.info("JSON references written successfully.")

        return {"asset_name" : json_data["asset_name"], "version_number" :  json_data["version_number"]}
Beispiel #8
0
    def dcc_set(self,
                parent,
                set_name,
                already_tabbed_in_node=False,
                mode=UpdateModes.CLEAN):

        # Check if it's a set and that it exists
        body = Project().get_body(set_name)
        if not body.is_asset() or not body.get_type() == AssetType.SET:
            qd.error("Must be a set.")

        node = already_tabbed_in_node if already_tabbed_in_node else parent.createNode(
            "dcc_set")
        try:
            node.setName(set_name)
        except:
            node.setName(set_name + "_1", unique_name=True)
        # Update contents in the set
        self.update_contents_set(node, set_name, mode)
        return node
Beispiel #9
0
    def update_contents_character(self,
                                  node,
                                  asset_name,
                                  excluded_departments=[],
                                  mode=UpdateModes.SMART,
                                  shot=None):

        # Set up the body/elements and make sure it's a character. Just do some simple error checking.
        body = Project().get_body(asset_name)
        if not body.is_asset() or body.get_type(
        ) != AssetType.CHARACTER or "dcc_character" not in node.type().name():
            qd.error("Must be a character.")
            return None

        # Reset the data parm
        data = node.parm("data").evalAsJSONMap()
        data["asset_name"] = asset_name
        node.parm("data").set(data)

        inside = node.node("inside")

        # Make sure the geo is set correctly
        geo = inside.node("geo")
        if geo is not None:
            if mode == UpdateModes.SMART:
                self.update_contents_geo(geo, asset_name, excluded_departments,
                                         mode)

            elif mode == UpdateModes.CLEAN:
                geo.destroy()
                geo = self.dcc_geo(inside,
                                   asset_name,
                                   excluded_departments=excluded_departments,
                                   character=True)
        else:
            geo = self.dcc_geo(inside,
                               asset_name,
                               excluded_departments=excluded_departments,
                               character=True)

        # Tab in each content HDA based on department
        for department in self.dcc_character_departments:
            # If the department is not excluded, tab-in/update the content node like normal
            if department not in excluded_departments:

                self.update_content_node(node, inside, asset_name, department,
                                         mode)

            # If the department is excluded, we should delete it.
            elif mode == UpdateModes.CLEAN:

                self.destroy_if_there(inside, department)

        inside.layoutChildren()

        geo.parm("version_number").setExpression(
            "ch(\"../../version_number\")", language=hou.exprLanguage.Hscript)

        # If this character is being animated, set parms accordingly
        if shot is not None:
            geo.parm("space").set("anim")
            geo.parm("asset_department").set("rig")
            geo.parm("shot").set(shot)

        return node
Beispiel #10
0
    def update_contents_set(self, node, set_name, mode=UpdateModes.SMART):
        # Check if reference file exists
        set_file = os.path.join(Project().get_assets_dir(), set_name, "model",
                                "main", "cache", "whole_set.json")

        # Error checking
        try:
            with open(set_file) as f:
                set_data = json.load(f)
        except Exception as error:
            qd.error("No valid JSON file for " + set_name)
            return

        node.parm("asset_name").set(set_name)
        data = node.parm("data").evalAsJSONMap()
        data["asset_name"] = set_name
        node.parm("data").set(data)
        inside = node.node("inside")

        # Grab current DCC Dynamic Content Subnets that have been tabbed in
        current_children = [
            child for child in inside.children()
            if child.type().name() in ["dcc_set", "dcc_character", "dcc_geo"]
        ]

        # Smart updating will only destroy assets that no longer exist in the Set's JSON list
        if mode == UpdateModes.SMART:
            non_matching = [
                child for child in current_children if len([
                    reference for reference in set_data
                    if matches_reference(child, reference)
                ]) == 0
            ]
            for non_match in non_matching:
                non_match.destroy()

        # Clean updating will destroy all children.
        elif mode == UpdateModes.CLEAN:
            inside.deleteItems(inside.children())

        # Grab current children again
        current_children = [
            child for child in inside.children()
            if child.type().name() in ["dcc_set", "dcc_character", "dcc_geo"]
        ]

        # Tab-in/update all assets in list
        for reference in set_data:
            body = Project().get_body(reference["asset_name"])

            if body is None:
                print 'Error on: ', reference["asset_name"]
                continue
            if not body.is_asset() or body.get_type() == AssetType.SET:
                continue

            # get the most recent data for this reference
            cloned_subnet, instances = Cloner().asset_results(
                [reference["asset_name"]])

            # move the cloned asset inside the set node and delete the one on the top level
            subnet = cloned_subnet.copyTo(inside)
            cloned_subnet.destroy()

            # Try to not override parameters in the set
            if mode == UpdateModes.SMART:
                for key in reference:
                    # Pull parm from node
                    parm = subnet.parm(key)
                    # If a non-default value is there, it most likely came from a user. Don't overwrite it.
                    if parm and parm.isAtDefault():
                        parm.set(reference[key])

            # Override parameters in the set
            elif mode == UpdateModes.CLEAN:
                newparms = {
                    "asset_name": reference["asset_name"],
                    "version_number": reference["version_number"]
                }
                subnet.setParms(newparms)

            # Build the set accordingly
            subnet.parm("space").set("set")
            subnet.parm("set").set(set_name)
            subnet.parm("update_mode").set(
                UpdateModes.list_modes().index(mode))
            # Set the data
            subnet.parm("data").set({
                "asset_name":
                str(reference["asset_name"]),
                "version_number":
                str(reference["version_number"])
            })

        inside.layoutChildren()
Beispiel #11
0
    def exportPropJSON(self,
                       filepath,
                       rootNode,
                       isReference=True,
                       name="",
                       version_number=None):
        if isReference:
            try:
                body = get_body_from_reference(rootNode)
            except:
                qd.warning("Could not find " + str(filepath) +
                           " in scene. Skipping.")
                return None
        else:
            body = Project().get_body(name)

        if not body or not body.is_asset():
            if body:
                if body.get_type() == AssetType.SHOT:
                    qd.warning(
                        "Shots in sets are not supported. Can't export " +
                        str(rootNode))
                    return None
            else:
                qd.warning("Asset not found in pipe: " + str(rootNode))
                return None

            qd.warning(str(rootNode) + " does not exist in pipe.")
            return None

        name = body.get_name()

        # Increment the version number
        version_number, version_string = body.version_prop_json(name, filepath)

        firstMesh, path = find_first_mesh(rootNode)
        try:
            vertpos1, vertpos2, vertpos3 = get_anchor_points(firstMesh)
        except Exception as e:
            print(str(e))
            qd.warning(
                "Couldn't export JSON for " + str(rootNode) +
                ". Is there a camera or a rig associated with this reference? Skipping this object."
            )
            return None

        # Put all relevant data into dictionary object
        json_data = {
            "asset_name": name,
            "version_number": version_number,
            "path": path,
            "a": [vertpos1.x, vertpos1.y, vertpos1.z],
            "b": [vertpos2.x, vertpos2.y, vertpos2.z],
            "c": [vertpos3.x, vertpos3.y, vertpos3.z]
        }

        print("json data: ", json_data)

        # Write JSON to fill
        jsonRef = json.dumps(json_data)
        wholePath = os.path.join(
            filepath,
            os.path.join(filepath, name + "_" + version_string + ".json"))
        outfile = open(wholePath,
                       "w")  # *** THIS IS THE NAME OF THE OUTPUT FILE ***
        outfile.write(jsonRef)
        outfile.close()

        if not isReference:
            print("JSON references written successfully.")

        return {
            "asset_name": json_data["asset_name"],
            "version_number": json_data["version_number"]
        }
Beispiel #12
0
class Exporter:
    def __init__(self):
        self.body = None
        self.item_gui = None
        self.list = ["alembic", "fbx", "json", "usd"]
        self.cameras = True

    def auto_export_all(self):
        self.export()

    def export_one(self,
                   alembic=False,
                   fbx=False,
                   json=False,
                   usd=False,
                   methods=None):
        self.export(alembic=alembic,
                    fbx=fbx,
                    json=json,
                    usd=usd,
                    methods=methods)

    def export(self,
               alembic=True,
               fbx=True,
               json=True,
               usd=True,
               methods=None):
        if methods is None:
            methods = self.list

        asset_name = os.environ.get("DCC_ASSET_NAME")
        if not asset_name:
            qd.error("You must first create or clone an asset.")
            return

        self.body = Project().get_body(asset_name)

        if alembic:
            AlembicExporter().auto_export(asset_name, self.cameras)

        if self.body and self.body.is_asset():
            if json:
                if self.body.get_type() == AssetType.SET or self.body.get_type(
                ) == AssetType.SHOT:
                    json_export = JSONExporter()
                    json_export.go(self.body, self.body.get_type())
                else:
                    methods.remove("json")

            if fbx:
                if self.body.get_type(
                ) == AssetType.PROP or self.body.get_type() == AssetType.ACTOR:
                    FbxExporter().auto_export(asset_name)
                else:
                    methods.remove("fbx")

        if usd:
            print("USD isn't supported... yet :|")
            methods.remove("usd")

        if methods:
            qd.info("Successfully exported " + str(asset_name) + " as " +
                    str(methods))
        else:
            qd.info("Nothing was exported.")

    def export_without_cameras(self):
        self.cameras = False
        self.export()

    def export_with_options(self):
        self.item_gui = co.CheckBoxOptions(parent=maya_main_window(),
                                           title="Select export methods:",
                                           options=self.list)
        self.item_gui.submitted.connect(self.export_results)

    def export_results(self, export_results):
        fbx = True
        alembic = True
        json = True
        usd = True
        methods = []

        for item in export_results.items():
            if item[0] == "fbx":
                if item[1] is False:
                    fbx = False
                else:
                    methods.append("fbx")

            elif item[0] == "alembic":
                if item[1] is False:
                    alembic = False
                else:
                    methods.append("alembic")

            elif item[0] == "json":
                if item[1] is False:
                    json = False
                else:
                    methods.append("json")

            elif item[0] == "usd":
                if item[1] is False:
                    usd = False
                else:
                    methods.append("usd")

        self.export(alembic=alembic,
                    fbx=fbx,
                    json=json,
                    usd=usd,
                    methods=methods)