Exemple #1
0
    def __init__(self):
        self.asset_gui = None

        # The order in which these nodes appear is the order they will be created in
        self.dcc_geo_departments = [Department.MODIFY, Department.MATERIAL]
        self.dcc_character_departments = [Department.HAIR, Department.CLOTH]
        self.all_departments = [
            Department.MODIFY, Department.MATERIAL, Department.HAIR,
            Department.CLOTH
        ]

        # The source HDA's are currently stored inside the pipe source code.
        self.hda_path = Environment().get_otl_dir()

        # We define the template HDAs definitions here, for use in the methods below
        self.hda_definitions = {
            Department.MATERIAL:
            hou.hdaDefinition(hou.sopNodeTypeCategory(), "dcc_material",
                              os.path.join(self.hda_path, "dcc_material.hda")),
            Department.MODIFY:
            hou.hdaDefinition(hou.sopNodeTypeCategory(), "dcc_modify",
                              os.path.join(self.hda_path, "dcc_modify.hda")),
            Department.HAIR:
            hou.hdaDefinition(hou.objNodeTypeCategory(), "dcc_hair",
                              os.path.join(self.hda_path, "dcc_hair.hda")),
            Department.CLOTH:
            hou.hdaDefinition(hou.objNodeTypeCategory(), "dcc_cloth",
                              os.path.join(self.hda_path, "dcc_cloth.hda"))
        }

        # By default, we ignore "Asset Controls", so that we can put things in there without them being promoted.
        # See: inherit_parameters() method
        self.default_ignored_folders = ["Asset Controls"]
Exemple #2
0
    def get_definition_by_department(self, source_path):
        definition = None
        print("dept: ", self.department)

        if self.department == Department.MATERIAL:
            definition = hou.hdaDefinition(hou.sopNodeTypeCategory(), "dcc_material", source_path)
        elif self.department == Department.MODIFY:
            definition = hou.hdaDefinition(hou.sopNodeTypeCategory(), "dcc_modify", source_path)
        elif self.department == Department.HAIR:
            definition = hou.hdaDefinition(hou.objNodeTypeCategory(), "dcc_hair", source_path)
        elif self.department == Department.CLOTH:
            definition = hou.hdaDefinition(hou.objNodeTypeCategory(), "dcc_cloth", source_path)


        return definition
Exemple #3
0
    def published_definition(self, asset_name, department):
        # Set the node type correctly
        category = hou.objNodeTypeCategory(
        ) if department in self.dcc_character_departments else hou.sopNodeTypeCategory(
        )
        hou.hda.reloadAllFiles()

        # Get the HDA File Path
        hda_name = asset_name + "_" + department
        hda_file = hda_name + "_main.hdanc"
        new_hda_path = os.path.join(Project().get_project_dir(), "production",
                                    "hda", hda_file)
        old_hda_path = os.path.join(Project().get_project_dir(), "production",
                                    "otls", hda_file)

        hda_path = ""
        # Does it exist?
        if os.path.islink(new_hda_path):
            hda_path = os.readlink(new_hda_path)
        elif os.path.islink(old_hda_path):
            hda_path = os.readlink(old_hda_path)
        else:
            return False

        # If it does, grab the definition
        hou.hda.installFile(hda_path)
        hda_definition = hou.hdaDefinition(category, hda_name, hda_path)

        # If the definition failed for some reason, don't tab it in.
        if hda_definition is not None:
            hda_definition.setPreferred(True)
            return True
        else:
            return False
Exemple #4
0
    def create_new_hda_definition(self,
                                  element,
                                  asset_name,
                                  department,
                                  checkout_file,
                                  content_hda_filepath=None):
        # CREATE NEW HDA DEFINITION
        if content_hda_filepath is None:
            content_hda_filepath = checkout_file

        print("content hda filepath: ", content_hda_filepath)

        operator_name = str(element.get_parent() + "_" +
                            element.get_department())
        operator_label = str((asset_name.replace("_", " ") + " " +
                              element.get_department()).title())

        self.hda_definitions[department].copyToHDAFile(checkout_file,
                                                       operator_name,
                                                       operator_label)
        hda_type = hou.objNodeTypeCategory(
        ) if department in self.dcc_character_departments else hou.sopNodeTypeCategory(
        )
        hou.hda.installFile(content_hda_filepath)
        print("hda type: ", hda_type)
        print("operator_name: ", operator_name)
        print("content_hda_filepath : ", content_hda_filepath)
        hda_definition = hou.hdaDefinition(hda_type, operator_name,
                                           content_hda_filepath)
        try:
            hda_definition.setPreferred(True)
        except:
            print("hda definition was not created")
Exemple #5
0
    def tool_results(self, value):
        tool_name = value[0]

        source = os.path.join(Environment().get_hda_dir(),
                              str(tool_name) + ".hda")

        hou.hda.installFile(source)
        obj = hou.node("/obj")

        try:
            hda = obj.createNode(tool_name)
        except:
            try:
                out = hou.node("/out")
                hda = out.createNode(tool_name)
            except Exception as e:
                qd.error("Could not find the correct context for tool: " +
                         str(tool_name),
                         details=str(e))
                return

        definition = hou.hdaDefinition(hda.type().category(),
                                       hda.type().name(), source)
        definition.setPreferred(True)

        hda.allowEditingOfContents()

        try:
            hda.setName(tool_name)
        except:
            print(
                str(tool_name) + " cloned but could not be renamed correctly.")

        layout_object_level_nodes()
Exemple #6
0
    def publish_src_node_to_department(self, src, node, department, user,
                                       comment):
        if os.path.exists(src):
            try:
                #save node definition--this is the same as the Save Node Type menu option. Just to make sure I remember how this works - We are getting the definition of the selected hda and calling the function on it passing in the selected hda. We are not calling the function on the selected hda.
                node.type().definition().updateFromNode(node)
            except hou.OperationFailed, e:
                qd.error(
                    'There was a problem publishing the HDA to the pipeline.\n'
                )
                print(str(e))
                return

            element = self.body.get_element(department, Element.DEFAULT_NAME)
            dst = self.publish_element(element, user, src, comment)

            print("dst: ", dst)

            try:
                hou.hda.installFile(dst)
                definition = hou.hdaDefinition(node.type().category(),
                                               node.type().name(), dst)
                definition.setPreferred(True)
                node.allowEditingOfContents()
            except Exception as e:
                qd.error("Publish failed for " + str(department),
                         details=str(e))
Exemple #7
0
def checkout_hda(hda, project, environment):
    '''
	hda - an hda to checkout
	Returns the element_path if the checkout was successful. Otherwise return None
	'''
    #if node is digital asset
    if hda.type().definition() is not None:
        asset_name = hda.type().name()  #get name of hda
        index = asset_name.rfind('_')
        department_name = asset_name[index + 1:]
        # Our old assets have "_main" at the end. We want them to refer to the "assembly" department.
        department_name = "assembly" if department_name == "main" else department_name
        asset_name = asset_name[:index]
        src = hda.type().definition().libraryFilePath()
        current_user = environment.get_current_username()

        if asset_name in project.list_assets():
            body = project.get_asset(asset_name)
        elif asset_name in project.list_tools():
            body = project.get_tool(asset_name)
        else:
            message_gui.error('We could not find ' + asset_name +
                              ' in the list of things you can checkout.')

        if department_name not in Department.ALL:
            message_gui.error(department_name + ' is not a valid Department')
            return None

        if os.path.exists(src):
            if body is not None:
                if Element.DEFAULT_NAME in body.list_elements(department_name):
                    element = body.get_element(department_name,
                                               Element.DEFAULT_NAME)
                elif Element.DEFAULT_NAME in body.list_elements(
                        Department.HDA):
                    element = body.get_element(Department.HDA,
                                               Element.DEFAULT_NAME)
                else:
                    message_gui.error(
                        'There was a problem checking out the selected hda',
                        details=
                        'The body for this HDA could not be found. This seems weird because we were able to find the asset_name in the list of assets. Right off the top of my head I don\'t know why it would do this. We\'ll have to take closer look.'
                    )
                    return None
                element_path = element.checkout(current_user)
                hou.hda.installFile(element_path)
                definition = hou.hdaDefinition(hda.type().category(),
                                               hda.type().name(), element_path)
                definition.setPreferred(True)
                #hou.hda.uninstallFile(src, change_oplibraries_file=False)
                hda.allowEditingOfContents()
                aa = hda.parm("ri_auto_archive")
                if aa:
                    aa.set("force")
                return element_path
    return None
Exemple #8
0
def paste_clipboard_to_netview(kwargs):
    """Paste clipboard contents (text or image) into the network editor.
    """
    clipboard = Qt.QtGui.QGuiApplication.clipboard()
    image = clipboard.image()
    text = clipboard.text()
    pane = kwargs.get('editor', None)

    if pane:
        pwd = pane.pwd()

        if image.isNull():
            # paste text (if any)
            if text != "":
                note = pwd.createStickyNote()
                note.move(pane.visibleBounds().center())
                s = note.size()
                s = hou.Vector2((
                    s.x() * 1.5,
                    s.y() * 0.5,
                ))
                note.setText(text)
                note.setSize(s)
        else:
            # paste image

            # TODO: generate automatic name
            image_name = ''
            ok, image_name = hou.ui.readInput(
                'Enter name of image to be pasted:',
                buttons=(
                    'Ok',
                    'Cancel',
                ),
                close_choice=1,
                initial_contents=image_name)
            if image_name == '':
                ok = 1
            image_name += '.png'

            if ok == 0:
                category = hou.objNodeTypeCategory()
                hda_typename = 'qLib::embedded_images'
                embedded = 'Embedded'
                hda_def = hou.hdaDefinition(category, hda_typename, embedded)

                # create hda definition if doesn't exist
                if not hda_def:
                    temp_node = hou.node('/obj').createNode('subnet')
                    hda_node = temp_node.createDigitalAsset(
                        name=hda_typename, save_as_embedded=True)
                    hda_node.destroy()

                hda_def = hou.hdaDefinition(category, hda_typename, embedded)

                # create an instance in /obj if doesn't exist
                node = None
                nodes = [
                    n for n in hou.node('/obj').children()
                    if n.type().name() == hda_typename
                ]

                if len(nodes) == 0:
                    node = hou.node('/obj').createNode(
                        hda_typename, node_name="embedded_images")

                # add clipboard image to hda definition (as section)
                ba = Qt.QtCore.QByteArray()
                buffer = Qt.QtCore.QBuffer(ba)
                buffer.open(Qt.QtCore.QIODevice.WriteOnly)
                image.save(buffer, "png")
                buffer.close()
                hda_def.addSection(image_name, str(buffer.data()))

                # add image to network view
                image = hou.NetworkImage(
                    "opdef:/qLib::Object/embedded_images?%s" % image_name)
                image.setBrightness(0.75)
                #image.setRect(hou.BoundingRect(0, 0, 5, 2))
                s = pane.visibleBounds()
                center = s.center()
                s.translate(-center)
                s.scale((
                    0.25,
                    0.25,
                ))
                s.translate(center)
                image.setRect(s)

                images = nodegraphutils.loadBackgroundImages(pwd)
                images.append(image)
                pane.setBackgroundImages(images)
                nodegraphutils.saveBackgroundImages(pwd, images)
Exemple #9
0
def get_embedded_img_hdadef():
    category = hou.objNodeTypeCategory()
    embedded = 'Embedded'
    hda_def = hou.hdaDefinition(category, embedded_hda_typename(), embedded)
    return hda_def
Exemple #10
0
def create_hda(asset_name, department, already_tabbed_in_node=None):

    # Check if this body is an asset. If not, return error.
    body = Project().get_body(asset_name)
    if not body.is_asset():
        error_message("Must be an asset of type PROP or CHARACTER.")
        return None

    # Check if it is a set.
    if body.get_type() == AssetType.SET:
        error_message("Asset must be a PROP or CHARACTER.")
        return None

    # Check if the user is trying to create a Hair or Cloth asset for a Prop on accident.
    if body.get_type() == AssetType.PROP and (department == Department.HAIR or department == Department.CLOTH):
        error_message("Hair and cloth should only be made for characters.")
        return None

    # Create element if does not exist.
    element = body.get_element(department, name=Element.DEFAULT_NAME, force_create=True)

    # TODO: Get rid of this ugly hotfix
    # !!! HOTFIX !!!
    # Material was previously used as an AssetElement, but now is being treated like an HDAElement.
    # This will convert it's file extension to .hdanc. (Before, it's extension was "").
    element._datadict[Element.APP_EXT] = element.create_new_dict(Element.DEFAULT_NAME, department, asset_name)[Element.APP_EXT]
    element._update_pipeline_file()
    # !!! END HOTFIX !!!

    # Check out the department.
    username = Project().get_current_username()
    checkout_file = element.checkout(username)

    # Tab in the parent asset that will hold this checked out HDA
    node = already_tabbed_in_node if already_tabbed_in_node else tab_in(hou.node("/obj"), asset_name, excluded_departments=[department])

    # If it's a character and it's not a hair or cloth asset, we need to reach one level deeper.
    if body.get_type() == AssetType.CHARACTER and department not in this.byu_character_departments:
        inside = node.node("inside/geo/inside")
    else:
        inside = node.node("inside")

    # CREATE NEW HDA DEFINITION
    operator_name = element.get_parent() + "_" + element.get_department()
    operator_label = (asset_name.replace("_", " ") + " " + element.get_department()).title()
    this.hda_definitions[department].copyToHDAFile(checkout_file, operator_name, operator_label)
    hda_type = hou.objNodeTypeCategory() if department in this.byu_character_departments else hou.sopNodeTypeCategory()
    hou.hda.installFile(checkout_file)
    hda_definition = hou.hdaDefinition(hda_type, operator_name, checkout_file)
    hda_definition.setPreferred(True)

    # Tab an instance of this new HDA into the asset you are working on
    try:
        hda_instance = inside.createNode(asset_name + "_" + department)
        print('noce')
    except Exception as e:
        error_message("HDA Creation Error. " + asset_name + "_" + department + " must not exist.")
    hda_instance.setName(department)
    tab_into_correct_place(inside, hda_instance, department)
    hda_instance.allowEditingOfContents()
    hda_instance.setSelected(True, clear_all_selected=True)

    return hda_instance
Exemple #11
0
        sys.stdout.flush()
        f.write("\n" + str(datetime.datetime.now()) + "\n")
        f.write(message)
        f.flush()

# DEBUGGING END

# I set this sucker up as a singleton. It's a matter of preference.
this = sys.modules[__name__]

# The source HDA's are currently stored inside the pipe source code.
hda_path = os.path.join(Environment().get_project_dir(), "byu-pipeline-tools", "houdini-tools", "otls")

# We define the template HDAs definitions here, for use in the methods below
hda_definitions = {
    Department.MATERIAL: hou.hdaDefinition(hou.sopNodeTypeCategory(), "byu_material", os.path.join(hda_path, "byu_material.hda")),
    Department.MODIFY: hou.hdaDefinition(hou.sopNodeTypeCategory(), "byu_modify", os.path.join(hda_path, "byu_modify.hda")),
    Department.HAIR: hou.hdaDefinition(hou.objNodeTypeCategory(), "byu_hair", os.path.join(hda_path, "byu_hair.hda")),
    Department.CLOTH: hou.hdaDefinition(hou.objNodeTypeCategory(), "byu_cloth", os.path.join(hda_path, "byu_cloth.hda"))
}

# The order in which these nodes appear is the order they will be created in
byu_geo_departments = [Department.MODIFY, Department.MATERIAL]
byu_character_departments = [Department.HAIR, Department.CLOTH]

hda_dir = Environment().get_hda_dir()

# Update mode types
class UpdateModes:
    SMART = "smart"
    CLEAN = "clean"
Exemple #12
0
            node.type().definition().updateFromNode(node)
        except hou.OperationFailed, e:
            qd.error(
                'There was a problem publishing the HDA to the pipeline.\n',
                details=str(e))
            return

        try:
            node.matchCurrentDefinition()
        except hou.OperationFailed, e:
            qd.warning("Problem matching description.")

        destination = os.path.join(Environment().get_hda_dir(),
                                   tool_name + ".hda")
        hou.hda.installFile(destination)
        definition = hou.hdaDefinition(node.type().category(),
                                       node.type().name(), destination)
        definition.setPreferred(True)

    def publish_set(self, node=None, name=None):
        self.departments = [Department.ASSEMBLY]

        if name:
            self.set_results([name])
            return

        project = Project()
        set_list = project.list_sets()
        self.item_gui = sfl.SelectFromList(l=set_list,
                                           parent=houdini_main_window(),
                                           title="Select a set to publish")
        self.item_gui.submitted.connect(self.set_results)
Exemple #13
0
                selectedHDA.matchCurrentDefinition()
            except hou.OperationFailed, e:
                message_gui.warning('There was a problem while trying to match the current definition. It\'s not a critical problem but it is a little troubling. Take a look at it and see if you can resolve the problem. Rest assured that the publish did work though', details=str(e))
            element = body.get_element(department, Element.DEFAULT_NAME)
            dst = element.publish(user, src, comment)
            #Ensure file has correct permissions
            try:
                os.chmod(dst, 0660)
            except:
                pass
			# TODO: UGLY HOTFIX FOR OLD ASSEMBLY ASSETS
            saveFile = hdaName + "_" + Element.DEFAULT_NAME + ".hdanc" if department not in [Department.ASSEMBLY, Department.HDA] else asset_name + "_" + department + "_" + Element.DEFAULT_NAME + ".hdanc"
            dst = os.path.join(environment.get_hda_dir(), saveFile)
            print("dst ", dst)
            hou.hda.installFile(dst)
            definition = hou.hdaDefinition(selectedHDA.type().category(), selectedHDA.type().name(), dst)
            definition.setPreferred(True)
            #hou.hda.uninstallFile(src, change_oplibraries_file=False)
        else:
            message_gui.error('File does not exist', details=src)

def publish_shot(publishWindow):
	element = publishWindow.result

	if publishWindow.published:
		hou.hipFile.save()

		#Publish
		user = publishWindow.user
		src = publishWindow.src
		comment = publishWindow.comment
Exemple #14
0
def paste_clipboard_to_netview(kwargs):
    """Paste clipboard contents (text or image) into the network editor.
    """
    clipboard = Qt.QtGui.QGuiApplication.clipboard()
    image = clipboard.image()
    text = clipboard.text()
    pane = kwargs.get('editor', None)

    if pane:
        pwd = pane.pwd()

        if image.isNull():
            # paste text (if any)
            if text!="":
                note = pwd.createStickyNote()
                note.move(pane.visibleBounds().center())
                s = note.size()
                s = hou.Vector2((s.x()*1.5, s.y()*0.5, ))
                note.setText(text)
                note.setSize(s)
        else:
            # paste image

            # TODO: generate automatic name
            image_name = ''
            ok, image_name = hou.ui.readInput('Enter name of image to be pasted:',
                buttons=('Ok', 'Cancel', ), close_choice=1,
                initial_contents=image_name)
            if image_name=='':
                ok = 1
            image_name += '.png'

            if ok==0:
                category = hou.objNodeTypeCategory()
                hda_typename = 'qLib::embedded_images'
                embedded = 'Embedded'
                hda_def = hou.hdaDefinition(category, hda_typename, embedded)
                
                # create hda definition if doesn't exist
                if not hda_def:
                    temp_node = hou.node('/obj').createNode('subnet')
                    hda_node = temp_node.createDigitalAsset(name=hda_typename, save_as_embedded=True)
                    hda_node.destroy()
        
                hda_def = hou.hdaDefinition(category, hda_typename, embedded)
        
                # create an instance in /obj if doesn't exist
                node = None
                nodes = [ n for n in hou.node('/obj').children() if n.type().name()==hda_typename ]
                
                if len(nodes)==0:
                    node = hou.node('/obj').createNode(hda_typename, node_name="embedded_images")
        
                # add clipboard image to hda definition (as section)
                ba = Qt.QtCore.QByteArray();
                buffer = Qt.QtCore.QBuffer(ba)
                buffer.open(Qt.QtCore.QIODevice.WriteOnly)
                image.save(buffer, "png")       
                buffer.close()
                hda_def.addSection(image_name, str(buffer.data()))
                
                # add image to network view
                image = hou.NetworkImage("opdef:/qLib::Object/embedded_images?%s" % image_name)
                image.setBrightness(0.75)
                #image.setRect(hou.BoundingRect(0, 0, 5, 2))
                s = pane.visibleBounds()
                center = s.center()
                s.translate(-center)
                s.scale((0.25, 0.25, ))
                s.translate(center)
                image.setRect(s)

                images = nodegraphutils.loadBackgroundImages(pwd)
                images.append(image)
                pane.setBackgroundImages(images)
                nodegraphutils.saveBackgroundImages(pwd, images)
Exemple #15
0
class Publisher:
    def __init__(self):
        self.dcc_geo_departments = [Department.MODIFY, Department.MATERIAL]
        self.item_gui = None

    def publish_content_hda(self, node):
        node_name = node.type().name()
        index = node_name.rfind('_')
        asset_name = node_name[:index]
        department = node_name[index + 1:]

        self.body = Project().get_body(asset_name)
        src = node.type().definition().libraryFilePath()
        user = Environment().get_user()

        comment = "publish by " + str(
            user.get_username()) + " in department " + str(department)

        self.publish_src_node_to_department(src, node, department, user,
                                            comment)

        success_message = "Success! Published " + asset_name + " to " + str(
            department)
        self.print_success_message(success_message)

    def publish_asset(self, node=None):
        self.departments = [
            Department.MODIFY, Department.MATERIAL, Department.HAIR,
            Department.CLOTH
        ]
        self.publish(selectedHDA=node)

    def publish_tool(self, node=None):
        self.departments = [Department.HDA]
        self.publish(selectedHDA=node)

    def publish_set(self, node=None):
        self.departments = [Department.ASSEMBLY]

        project = Project()
        set_list = project.list_sets()
        self.item_gui = sfl.SelectFromList(l=set_list,
                                           parent=houdini_main_window(),
                                           title="Select a set to publish")
        self.item_gui.submitted.connect(self.set_results)

    def set_results(self, value):
        set_name = value[0]
        project = Project()
        self.body = project.get_body(set_name)

        obj = hou.node("/obj")
        set = obj.node(set_name)

        if set is None:
            qd.error(
                "No set found with that name. Please check naming and try again."
            )
            return

        print("set: ", set)
        inside = set.node("inside")
        children = inside.children()
        set_file = os.path.join(Project().get_assets_dir(), set_name, "model",
                                "main", "cache", "whole_set.json")

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

        items_in_set = []
        for item in set_data:
            item_name = item['asset_name']
            item_version = item['version_number']
            items_in_set.append(item_name)

        # TODO: for each child, make sure that it exists in whole_set.json, or add it if it doesn't, or remove it if it does not
        child_names = []
        for child in children:
            child_path = child.path()
            name = child_path.split('/')[-1].lower()
            child_names.append(name)

        for item in set_data:
            if str(item['asset_name']) not in child_names:
                set_data.remove(item)

        for child in children:
            print("child: ", child)
            inside = child.node("inside")
            out = inside.node("OUT")
            set_transform = inside.node("set_dressing_transform")
            child_path = child.path()
            name = child_path.split('/')[-1].lower()

            child_body = project.get_body(name)
            if child_body is None:
                qd.warning(
                    str(name) +
                    " not found in pipe. Please check that node is named correctly."
                )
                continue

            # get transform parms: t is translate, r rotate and s scale (with associated x,y,z vals)
            tx, ty, tz = self.get_transform(set_transform, "tx", "ty", "tz")
            rx, ry, rz = self.get_transform(set_transform, "rx", "ry", "rz")
            sx, sy, sz = self.get_transform(set_transform, "sx", "sy", "sz")

            latest_file, latest_version = self.body.get_latest_json_version(
                name)
            if latest_version == int(9):
                new_version = 0
            else:
                new_version = int(latest_version) + 1

            prop_file = os.path.join(
                Project().get_assets_dir(), set_name, "model", "main", "cache",
                str(name) + "_" + str(latest_version) + ".json")

            if name in items_in_set:
                print("set contains asset: " + str(name))
                try:
                    with open(prop_file) as f:
                        prop_data = json.load(f)
                except Exception as error:
                    qd.warning("No valid JSON file for " + str(name) +
                               ". Skipping changes made to this asset.")
                    continue

                for set_item in set_data:
                    if str(set_item['asset_name']) == str(name):
                        set_item['version_number'] = new_version
                        break

            else:
                print(str(name) + " not found in set file.")
                path = self.get_prim_path(out)
                prop_data = {
                    "asset_name": name,
                    "version_number": 0,
                    "path": str(path),
                    "a": [0, 0, 0],
                    "b": [0, 0, 0],
                    "c": [0, 0, 0]
                }
                set_data.append({"asset_name": str(name), "version_number": 0})
                new_version = 0

            new_prop_file = os.path.join(
                Project().get_assets_dir(), set_name, "model", "main", "cache",
                str(name) + "_" + str(new_version) + ".json")

            # get a b and c from prop_data file. Each is an array of size 3, representing x,y,z coords
            a = prop_data['a']
            b = prop_data['b']
            c = prop_data['c']

            self.update_points_by_geo(out, a, b, c)

            # put the updated coords back into prop_data
            prop_data['a'] = a
            prop_data['b'] = b
            prop_data['c'] = c

            # TODO: add a commit and a publish for this set

            print("prop data (updated): ", prop_data)

            updated_prop_data = json.dumps(prop_data)
            outfile = open(new_prop_file, "w")
            outfile.write(updated_prop_data)
            outfile.close()

            print("prop file updated for " + str(name))

            self.clear_transform(set_transform)
            self.update_version_number(child, new_version)
            import_node = child.node("import")
            read_from_json = import_node.node("read_from_json")
            read_from_json.parm("reload").pressButton()

        outfile = open(set_file, "w")
        print("set data: ", set_data)
        updated_set_data = json.dumps(set_data)
        outfile.write(updated_set_data)
        outfile.close()

        qd.info("Set " + str(set_name) + " published successfully!")

    def update_version_number(self, child, version_number):
        version_parm = child.parm("version_number").evalAsInt()
        child.parm("version_number").set(version_number)

    def get_prim_path(self, out):
        geo = out.geometry()
        return geo.findPrimAttrib("path").strings()[0]

    def update_points_by_geo(self, out, a, b, c):
        geo = out.geometry()
        point_a = geo.iterPoints()[0]
        point_b = geo.iterPoints()[1]
        point_c = geo.iterPoints()[2]

        a_x = point_a.position()[0]
        a_y = point_a.position()[1]
        a_z = point_a.position()[2]
        b_x = point_b.position()[0]
        b_y = point_b.position()[1]
        b_z = point_b.position()[2]
        c_x = point_c.position()[0]
        c_y = point_c.position()[1]
        c_z = point_c.position()[2]

        # a is the first point of this object in geo spreadsheet, b is second, c third.
        a[0] = a_x
        a[1] = a_y
        a[2] = a_z
        b[0] = b_x
        b[1] = b_y
        b[2] = b_z
        c[0] = c_x
        c[1] = c_y
        c[2] = c_z

    def get_transform(self, child, parm1, parm2, parm3):
        x = child.parm(parm1).evalAsFloat()
        y = child.parm(parm2).evalAsFloat()
        z = child.parm(parm3).evalAsFloat()

        return x, y, z

    def clear_transform(self, child):
        parm_scale_list = ["sx", "sy", "sz"]
        parm_list = ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"]

        for parm in parm_list:
            if parm not in parm_scale_list:
                child.parm(parm).set(0.0)
            else:
                child.parm(parm).set(1.0)
            child.parm(parm).eval()

    def publish_shot(self):
        scene = hou.hipFile.name()
        self.departments = [Department.HDA, Department.LIGHTING, Department.FX]

        project = Project()
        asset_list = project.list_shots()
        self.item_gui = sfl.SelectFromList(l=asset_list,
                                           parent=houdini_main_window(),
                                           title="Select a shot to publish to")
        self.item_gui.submitted.connect(self.shot_results)

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

        project = Project()
        self.body = project.get_body(chosen_asset)

        department = Department.LIGHTING
        element = self.body.get_element(department)  #, Element.DEFAULT_NAME)

        hou.hipFile.save()
        src = hou.hipFile.name()

        #Publish
        user = Environment().get_user()
        comment = "publish by " + str(
            user.get_username()) + " in department " + str(department)
        dst = self.publish_element(element, user, src, comment)

        message = "Successfully published " + str(self.body.get_name()) + "!"
        self.print_success_message(message)

    def publish(
        self,
        selectedHDA=None
    ):  #, departments=[Department.HDA, Department.ASSEMBLY, Department.MODIFY, Department.MATERIAL, Department.HAIR, Department.CLOTH]):
        project = Project()
        self.selectedHDA = selectedHDA

        if selectedHDA is None:
            nodes = hou.selectedNodes()

            if len(nodes) == 1:
                selectedHDA = nodes[0]
                self.selectedHDA = selectedHDA
            elif len(nodes) > 1:
                qd.error(
                    'Too many nodes selected. Please select only one node.')
                return
            else:
                qd.error('No nodes selected. Please select a node.')
                return

        if selectedHDA.type().definition() is not None:
            self.src = selectedHDA.type().definition().libraryFilePath()
            asset_list = project.list_props_and_characters()
            self.item_gui = sfl.SelectFromList(
                l=asset_list,
                parent=houdini_main_window(),
                title="Select an asset to publish to")
            self.item_gui.submitted.connect(self.asset_results)

        else:
            qd.error('The selected node is not a digital asset')
            return

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

        project = Project()
        self.body = project.get_body(chosen_asset)
        self.publish_hda()

    def publish_hda(self):
        project = Project()
        environment = Environment()
        user = environment.get_user()
        selectedHDA = self.selectedHDA
        src = self.src
        body = self.body
        asset_type = body.get_type()

        inside = selectedHDA.node("inside")
        modify = inside.node("modify")
        material = inside.node("material")
        hair = inside.node("hair")
        cloth = inside.node("cloth")

        if asset_type == AssetType.CHARACTER:
            geo = inside.node("geo")
            geo_inside = geo.node("inside")
            modify = geo_inside.node("modify")
            material = geo_inside.node("material")

        departments_to_publish = []

        if not modify is None:
            departments_to_publish.append("modify")
        if not material is None:
            departments_to_publish.append("material")
        if not hair is None:
            departments_to_publish.append("hair")
        if not cloth is None:
            departments_to_publish.append("cloth")

        if body is None:
            qd.error("Asset not found in pipe.")
            return

        comment = "publish by " + str(user.get_username(
        )) + " in departments " + str(departments_to_publish)

        for department in departments_to_publish:
            inside = self.get_inside_node(asset_type, department, selectedHDA)
            node = inside.node(department)
            src = node.type().definition().libraryFilePath()

            self.publish_src_node_to_department(src, node, department, user,
                                                comment)

        success_message = "Success! Published to " + str(
            departments_to_publish)
        self.print_success_message(success_message)

        return "published to " + str(departments_to_publish)

    def get_inside_node(self, type, department, node):
        # If it's a character and it's not a hair or cloth asset, we need to reach one level deeper.
        if type == AssetType.CHARACTER and department in self.dcc_geo_departments:
            inside = node.node("inside/geo/inside")
        else:
            inside = node.node("inside")

        return inside

    def publish_src_node_to_department(self, src, node, department, user,
                                       comment):
        if os.path.exists(src):
            try:
                #save node definition--this is the same as the Save Node Type menu option. Just to make sure I remember how this works - We are getting the definition of the selected hda and calling the function on it passing in the selected hda. We are not calling the function on the selected hda.
                node.type().definition().updateFromNode(node)
            except hou.OperationFailed, e:
                qd.error(
                    'There was a problem publishing the HDA to the pipeline.\n'
                )
                print(str(e))
                return

            try:
                node.matchCurrentDefinition(
                )  # this function locks the node for editing.
            except hou.OperationFailed, e:
                qd.warning(
                    'There was a problem while trying to match the current definition. It\'s not a critical problem. Look at it and see if you can resolve the problem. Publish was successful.'
                )
                print(str(e))

            element = self.body.get_element(department, Element.DEFAULT_NAME)
            dst = self.publish_element(element, user, src, comment)

            print("dst: ", dst)

            hou.hda.installFile(dst)
            definition = hou.hdaDefinition(node.type().category(),
                                           node.type().name(), dst)
            definition.setPreferred(True)
Exemple #16
0
            details=str(e))

    dst = element.publish(user, hda_src, comment)
    #Ensure file has correct permissions
    try:
        os.chmod(dst, 0660)
    except:
        pass

    # TODO: UGLY HOTFIX FOR OLD ASSEMBLY ASSETS for v1 backwards compatability
    saveFile = hdaName + "_" + Element.DEFAULT_NAME + ".hdanc" if department not in [
        Department.ASSEMBLY, Department.HDA
    ] else asset_name + "_" + department + "_" + Element.DEFAULT_NAME + ".hdanc"

    dst = os.path.join(environment.get_hda_dir(), saveFile)
    print("dst ", dst)
    hou.hda.installFile(dst)
    definition = hou.hdaDefinition(hda.type().category(),
                                   hda.type().name(), dst)
    definition.setPreferred(True)


##quick publish for v2 assets
def non_gui_publish_go(selectedHDA=None, comment=None):

    if selectedHDA != None:
        non_gui_publish_hda(selectedHDA, comment)
    else:
        qd.error('Please select a single node')
        return