From 352cbf842f35cb818744e978826dd4523dd9d93a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 27 Mar 2024 20:00:06 +0100 Subject: [PATCH 01/50] Implement Houdini Load Asset LOP HDA --- client/ayon_core/hosts/houdini/addon.py | 64 +-- .../ayon_core/hosts/houdini/api/hda_utils.py | 402 ++++++++++++++++++ client/ayon_core/hosts/houdini/api/lib.py | 226 ++++++++++ .../ayon_core/hosts/houdini/api/pipeline.py | 24 +- .../houdini/plugins/load/load_asset_lop.py | 52 +++ .../resources/otls/ayon_lop_import.hda | Bin 0 -> 41786 bytes 6 files changed, 739 insertions(+), 29 deletions(-) create mode 100644 client/ayon_core/hosts/houdini/api/hda_utils.py create mode 100644 client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py create mode 100644 client/ayon_core/hosts/houdini/resources/otls/ayon_lop_import.hda diff --git a/client/ayon_core/hosts/houdini/addon.py b/client/ayon_core/hosts/houdini/addon.py index 95d714aea1..8f82ee2e76 100644 --- a/client/ayon_core/hosts/houdini/addon.py +++ b/client/ayon_core/hosts/houdini/addon.py @@ -4,41 +4,49 @@ HOUDINI_HOST_DIR = os.path.dirname(os.path.abspath(__file__)) -class HoudiniAddon(AYONAddon, IHostAddon): - name = "houdini" - host_name = "houdini" - - def add_implementation_envs(self, env, _app): - # Add requirements to HOUDINI_PATH and HOUDINI_MENU_PATH - startup_path = os.path.join(HOUDINI_HOST_DIR, "startup") - new_houdini_path = [startup_path] - new_houdini_menu_path = [startup_path] - - old_houdini_path = env.get("HOUDINI_PATH") or "" - old_houdini_menu_path = env.get("HOUDINI_MENU_PATH") or "" - - for path in old_houdini_path.split(os.pathsep): +def merge_paths(*paths): + """Merge path strings to a single uniqified `os.pathsep` joined string. + Each path argument can itself be `os.pathsep` joined string. + >>> merge_paths("A", "A;B;C", "D;E") + "A;B;C;D;E" + Returns: + str: Single joined path using `os.pathsep` + """ + result = [] + processed = set() + for paths_str in paths: + for path in paths_str.split(os.pathsep): if not path: continue - norm_path = os.path.normpath(path) - if norm_path not in new_houdini_path: - new_houdini_path.append(norm_path) - - for path in old_houdini_menu_path.split(os.pathsep): - if not path: + path = os.path.normpath(path) + if path in processed: continue - norm_path = os.path.normpath(path) - if norm_path not in new_houdini_menu_path: - new_houdini_menu_path.append(norm_path) + result.append(path) + processed.add(path) + + return os.pathsep.join(result) - # Add ampersand for unknown reason (Maybe is needed in Houdini?) - new_houdini_path.append("&") - new_houdini_menu_path.append("&") - env["HOUDINI_PATH"] = os.pathsep.join(new_houdini_path) - env["HOUDINI_MENU_PATH"] = os.pathsep.join(new_houdini_menu_path) +class HoudiniAddon(AYONAddon, IHostAddon): + name = "houdini" + host_name = "houdini" + + def add_implementation_envs(self, env, _app): + # Add requirements to HOUDINI_PATH, HOUDINI_MENU_PATH, HOUDINI_OTL_PATH + startup_path = os.path.join(HOUDINI_HOST_DIR, "startup") + resources_path = os.path.join(HOUDINI_HOST_DIR, "resources") + + env["HOUDINI_PATH"] = merge_paths( + startup_path, env.get("HOUDINI_PATH", ""), "&" + ) + env["HOUDINI_MENU_PATH"] = merge_paths( + startup_path, env.get("HOUDINI_MENU_PATH", ""), "&" + ) + env["HOUDINI_OTL_PATH"] = merge_paths( + resources_path, env.get("HOUDINI_OTL_PATH", ""), "&" + ) def get_launch_hook_paths(self, app): if app.host_name != self.host_name: diff --git a/client/ayon_core/hosts/houdini/api/hda_utils.py b/client/ayon_core/hosts/houdini/api/hda_utils.py new file mode 100644 index 0000000000..f80046173a --- /dev/null +++ b/client/ayon_core/hosts/houdini/api/hda_utils.py @@ -0,0 +1,402 @@ +"""Helper functions for load HDA""" + +import os +import contextlib + +import ayon_api +from ayon_api import ( + get_project, + get_representation_by_id, + get_versions, + get_folder_by_path, + get_product_by_name, + get_version_by_name, + get_representation_by_name +) +from ayon_core.pipeline.load import ( + get_representation_context, + get_representation_path_from_context +) +from ayon_core.pipeline.context_tools import get_current_project_name + +from ayon_core.hosts.houdini.api import lib + +import hou + + +@contextlib.contextmanager +def _unlocked_parm(parm): + """Unlock parm during context; will always lock after""" + try: + parm.lock(False) + yield + finally: + parm.lock(True) + + +def get_available_versions(node): + """Return the versions list for node. + + Args: + node (hou.Node): Node to query selected products's versions for. + + Returns: + List[int]: Version numbers for the product + """ + + project_name = node.evalParm("project_name") or get_current_project_name() + folder_path = node.evalParm("folder_path") + product_name = node.evalParm("product_name") + + if not all([ + project_name, folder_path, product_name + ]): + return [] + + id_only = ["id"] + folder_entity = get_folder_by_path(project_name, + folder_path, + fields=id_only) + if not folder_entity: + return [] + product_entity = get_product_by_name( + project_name, + product_name=product_name, + folder_id=folder_entity["id"], + fields=id_only) + if not product_entity: + return [] + + # TODO: Support hero versions + versions = get_versions(project_name=project_name, + product_ids=[product_entity["id"]], + fields=["version"], + hero=False) + version_names = [version["version"] for version in versions] + version_names.reverse() + return version_names + + +def update_info(node, context): + """Update project, folder, product, version, representation name parms. + + Arguments: + node (hou.Node): Node to update + context (dict): Context of representation + + """ + # TODO: Avoid 'duplicate' taking over the expression if originally + # it was $OS and by duplicating, e.g. the `folder` does not exist + # anymore since it is now `hero1` instead of `hero` + # TODO: Support hero versions + version = str(context["version"]["version"]) + + # We only set the values if the value does not match the currently + # evaluated result of the other parms, so that if the the project name + # value was dynamically set by the user with an expression or alike + # then if it still matches the value of the current representation id + # we preserve it + parms = { + "project_name": context["project"]["name"], + "folder_path": context["folder"]["path"], + "product_name": context["product"]["name"], + "version": version, + "representation_name": context["representation"]["name"], + } + parms = {key: value for key, value in parms.items() + if node.evalParm(key) != value} + parms["load_message"] = "" # clear any warnings/errors + + # Note that these never trigger any parm callbacks since we do not + # trigger the `parm.pressButton` and programmatically setting values + # in Houdini does not trigger callbacks automatically + node.setParms(parms) + + +def _get_thumbnail(project_name, version_id, thumbnail_dir): + folder = hou.text.expandString(thumbnail_dir) + path = os.path.join(folder, "{}_thumbnail.jpg".format(version_id)) + expanded_path = hou.text.expandString(path) + if os.path.isfile(expanded_path): + return path + + # Try and create a thumbnail cache file + data = ayon_api.get_thumbnail(project_name, + entity_type="version", + entity_id=version_id) + if data: + thumbnail_dir_expanded = hou.text.expandString(thumbnail_dir) + os.makedirs(thumbnail_dir_expanded, exist_ok=True) + with open(expanded_path, "wb") as f: + f.write(data.content) + return path + + +def set_representation(node, repre_id): + file_parm = node.parm("file") + if repre_id: + project_name = node.evalParm("project_name") or \ + get_current_project_name() + try: + repre_entity = get_representation_by_id(project_name, repre_id) + except Exception: + # Ignore invalid representation ids silently + repre_entity = None + + if repre_entity: + context = get_representation_context(project_name, repre_entity) + update_info(node, context) + path = get_representation_path_from_context(context) + # Load fails on UNC paths with backslashes and also + # fails to resolve @sourcename var with backslashed + # paths correctly. So we force forward slashes + path = path.replace("\\", "/") + with _unlocked_parm(file_parm): + file_parm.set(path) + + if node.evalParm("show_thumbnail"): + # Update thumbnail + # TODO: Cache thumbnail path as well + version_id = repre_entity["versionId"] + thumbnail_dir = node.evalParm("thumbnail_cache_dir") + thumbnail_path = _get_thumbnail(project_name, version_id, + thumbnail_dir) + set_node_thumbnail(node, thumbnail_path) + else: + # Clear filepath and thumbnail + with _unlocked_parm(file_parm): + file_parm.set("") + set_node_thumbnail(node, None) + + +def set_node_thumbnail(node, thumbnail): + """Update node thumbnail to thumbnail""" + if thumbnail is None: + lib.set_node_thumbnail(node, None) + + rect = compute_thumbnail_rect(node) + lib.set_node_thumbnail(node, thumbnail, rect) + + +def compute_thumbnail_rect(node): + """Compute thumbnail bounding rect based on thumbnail parms""" + offset_x = node.evalParm("thumbnail_offsetx") + offset_y = node.evalParm("thumbnail_offsety") + width = node.evalParm("thumbnail_size") + # todo: compute height from aspect of actual image file. + aspect = 0.5625 # for now assume 16:9 + height = width * aspect + + center = 0.5 + half_width = (width * .5) + + return hou.BoundingRect( + offset_x + center - half_width, + offset_y, + offset_x + center + half_width, + offset_y + height + ) + + +def on_thumbnail_show_changed(node): + """Callback on thumbnail show parm changed""" + if node.evalParm("show_thumbnail"): + # For now, update all + on_representation_id_changed(node) + else: + lib.remove_all_thumbnails(node) + + +def on_thumbnail_size_changed(node): + """Callback on thumbnail offset or size parms changed""" + thumbnail = lib.get_node_thumbnail(node) + if thumbnail: + rect = compute_thumbnail_rect(node) + thumbnail.setRect(rect) + lib.set_node_thumbnail(node, thumbnail) + + +def on_representation_id_changed(node): + """Callback on representation id changed + + Args: + node (hou.Node): Node to update. + """ + repre_id = node.evalParm("representation") + set_representation(node, repre_id) + + +def on_representation_parms_changed(node): + """ + Usually used as callback to the project, folder, product, version and + representation parms which on change - would result in a different + representation id to be resolved. + + Args: + node (hou.Node): Node to update. + """ + project_name = node.evalParm("project_name") or get_current_project_name() + representation_id = get_representation_id( + project_name=project_name, + folder_path=node.evalParm("folder_path"), + product_name=node.evalParm("product_name"), + version=node.evalParm("version"), + representation_name=node.evalParm("representation_name"), + load_message_parm=node.parm("load_message") + ) + if representation_id is None: + representation_id = "" + else: + representation_id = str(representation_id) + + if node.evalParm("representation") != representation_id: + node.parm("representation").set(representation_id) + node.parm("representation").pressButton() # trigger callback + + +def get_representation_id( + project_name, + folder_path, + product_name, + version, + representation_name, + load_message_parm, +): + """Get representation id. + + Args: + project_name (str): Project name + folder_path (str): Folder name + product_name (str): Product name + version (str): Version name as string + representation_name (str): Representation name + load_message_parm (hou.Parm): A string message parm to report + any error messages to. + + Returns: + Optional[str]: Representation id or None if not found. + + """ + + if not all([ + project_name, folder_path, product_name, version, representation_name + ]): + labels = { + "project": project_name, + "folder": folder_path, + "product": product_name, + "version": version, + "representation": representation_name + } + missing = ", ".join(key for key, value in labels.items() if not value) + load_message_parm.set(f"Load info incomplete. Found empty: {missing}") + return + + try: + version = int(version.strip()) + except ValueError: + load_message_parm.set(f"Invalid version format: '{version}'\n" + "Make sure to set a valid version number.") + return + + id_only = ["id"] + folder_entity = get_folder_by_path(project_name, + folder_path=folder_path, + fields=id_only) + if not folder_entity: + # This may be due to the project not existing - so let's validate + # that first + if not get_project(project_name): + load_message_parm.set(f"Project not found: '{project_name}'") + return + load_message_parm.set(f"Folder not found: '{folder_path}'") + return + + product_entity = get_product_by_name( + project_name, + product_name=product_name, + folder_id=folder_entity["id"], + fields=id_only) + if not product_entity: + load_message_parm.set(f"Product not found: '{product_name}'") + return + version_doc = get_version_by_name( + project_name, + version, + product_id=product_entity["id"], + fields=id_only) + if not version_doc: + load_message_parm.set(f"Version not found: '{version}'") + return + representation_doc = get_representation_by_name( + project_name, + representation_name, + version_id=version_doc["id"], + fields=id_only) + if not representation_doc: + load_message_parm.set( + f"Representation not found: '{representation_name}'.") + return + return representation_doc["id"] + + +def setup_flag_changed_callback(node): + """Register flag changed callback (for thumbnail brightness)""" + node.addEventCallback( + (hou.nodeEventType.FlagChanged,), + on_flag_changed + ) + + +def on_flag_changed(node, **kwargs): + """On node flag changed callback. + + Updates the brightness of attached thumbnails + """ + # Showing thumbnail is disabled so can return early since + # there should be no thumbnail to update. + if not node.evalParm('show_thumbnail'): + return + + # Update node thumbnails brightness with the + # bypass state of the node. + parent = node.parent() + images = lib.get_background_images(parent) + if not images: + return + + brightness = 0.3 if node.isBypassed() else 1.0 + has_changes = False + node_path = node.path() + for image in images: + if image.relativeToPath() == node_path: + image.setBrightness(brightness) + has_changes = True + + if has_changes: + lib.set_background_images(parent, images) + + +def keep_background_images_linked(node, old_name): + """Reconnect background images to node from old name. + + Used as callback on node name changes to keep thumbnails linked.""" + from ayon_core.hosts.houdini.api.lib import ( + get_background_images, + set_background_images + ) + + parent = node.parent() + images = get_background_images(parent) + if not images: + return + + changes = False + old_path = f"{node.parent().path()}/{old_name}" + for image in images: + if image.relativeToPath() == old_path: + image.setRelativeToPath(node.path()) + changes = True + + if changes: + set_background_images(parent, images) diff --git a/client/ayon_core/hosts/houdini/api/lib.py b/client/ayon_core/hosts/houdini/api/lib.py index a72118c276..239e405c98 100644 --- a/client/ayon_core/hosts/houdini/api/lib.py +++ b/client/ayon_core/hosts/houdini/api/lib.py @@ -998,6 +998,232 @@ def add_self_publish_button(node): node.setParmTemplateGroup(template) +def get_background_images(node, raw=False): + """"Return background images defined inside node. + + Similar to `nodegraphutils.saveBackgroundImages` but this method also + allows to retrieve the data as JSON encodable data instead of + `hou.NetworkImage` instances when using `raw=True` + """ + + def _parse(image_data): + image = hou.NetworkImage(image_data["path"], + hou.BoundingRect(*image_data["rect"])) + if "relativetopath" in image_data: + image.setRelativeToPath(image_data["relativetopath"]) + if "brightness" in image_data: + image.setBrightness(image_data["brightness"]) + return image + + data = node.userData("backgroundimages") + if not data: + return [] + + try: + images = json.loads(data) + if not raw: + images = [_parse(_data) for _data in images] + except json.decoder.JSONDecodeError: + images = [] + + return images + + +def set_background_images(node, images): + """Set hou.NetworkImage background images under given hou.Node + + Similar to: `nodegraphutils.loadBackgroundImages` + + """ + + def _serialize(image): + """Return hou.NetworkImage as serialized dict""" + if isinstance(image, dict): + # Assume already serialized, only do some minor validations + assert "path" in image + assert "rect" in image + assert len(image["rect"]) == 4 + return image + + rect = image.rect() + rect_min = rect.min() + rect_max = rect.max() + data = { + "path": image.path(), + "rect": [rect_min.x(), rect_min.y(), rect_max.x(), rect_max.y()], + "brightness": image.brightness(), + "relativetopath": image.relativeToPath() + } + if data["brightness"] == 1.0: + del data["brightness"] + if data["relativetopath"] == "": + del data["relativetopath"] + return data + + with hou.undos.group('Edit Background Images'): + if images: + assert all(isinstance(image, (dict, hou.NetworkImage)) + for image in images) + data = json.dumps([_serialize(image) for image in images]) + node.setUserData("backgroundimages", data) + else: + node.destroyUserData("backgroundimages", must_exist=False) + + +def set_node_thumbnail(node, + image_path, + rect=None): + """Set hou.NetworkImage attached to node. + + If an existing connected image is found it assumes that is the existing + thumbnail and will update that particular instance instead. + + When `image_path` is None an existing attached `hou.NetworkImage` will be + removed. + + Arguments: + node (hou.Node): Node to set thumbnail for. + image_path (Union[str, None]): Path to image to set. + If None is set then the thumbnail will be removed if it exists. + rect (hou.BoundingRect): Bounding rect for the relative placement + to the node. + + Returns: + hou.NetworkImage or None: The network image that was set or None if + instead it not set or removed. + + """ + + parent = node.parent() + images = get_background_images(parent) + + node_path = node.path() + # Find first existing image attached to node + index, image = next( + ( + (index, image) for index, image in enumerate(images) if + image.relativeToPath() == node_path + ), + (None, None) + ) + if image_path is None: + # Remove image if it exists + if image: + images.remove(image) + set_background_images(parent, images) + return + + if rect is None: + rect = hou.BoundingRect(-1, -1, 1, 1) + + if isinstance(image_path, hou.NetworkImage): + image = image_path + if index is not None: + images[index] = image + else: + images.append(image) + elif image is None: + # Create the image + image = hou.NetworkImage(image_path, rect) + image.setRelativeToPath(node.path()) + images.append(image) + else: + # Update first existing image + image.setRect(rect) + image.setPath(image_path) + + set_background_images(parent, images) + + return image + + +def remove_all_thumbnails(node): + """Remove all node thumbnails. + + Removes all network background images that are linked to the given node. + """ + parent = node.parent() + images = get_background_images(parent) + node_path = node.path() + images = [ + image for image in images if image.relativeToPath() != node_path + ] + set_background_images(parent, images) + + +def get_node_thumbnail(node, first_only=True): + """Return node thumbnails. + + Return network background images that are linked to the given node. + By default, only returns the first one found, unless `first_only` is False. + + Returns: + Union[hou.NetworkImage, List[hou.NetworkImage]]: + Connected network images + + """ + parent = node.parent() + images = get_background_images(parent) + node_path = node.path() + + def is_attached_to_node(image): + return image.relativeToPath() == node_path + + attached_images = filter(is_attached_to_node, images) + + # Find first existing image attached to node + if first_only: + return next(attached_images, None) + else: + return attached_images + + +def find_active_network(category, default): + """Find the first active network editor in the UI. + + If no active network editor pane is found at the given category then the + `default` path will be used as fallback. + + For example, to find an active LOPs network: + >>> network = find_active_network( + ... category=hou.lopNodeTypeCategory(), + ... fallback="/stage" + ... ) + hou.Node("/stage/lopnet1") + + Arguments: + category (hou.NodeTypeCategory): The node network category type. + default (str): The default path to fallback to if no active pane + is found with the given category. + + Returns: + hou.Node: The node network to return. + + """ + # Find network editors that are current tab of given category + index = 0 + while True: + pane = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor, index) + index += 1 + if pane is None: + break + + if not pane.isCurrentTab(): + continue + + pwd = pane.pwd() + if pwd.type().category() != category: + continue + + if not pwd.isEditable(): + continue + + return pwd + + # Default to the fallback if no valid candidate was found + return hou.node(default) + + def update_content_on_context_change(): """Update all Creator instances to current asset""" host = registered_host() diff --git a/client/ayon_core/hosts/houdini/api/pipeline.py b/client/ayon_core/hosts/houdini/api/pipeline.py index b9446933ac..4568640f84 100644 --- a/client/ayon_core/hosts/houdini/api/pipeline.py +++ b/client/ayon_core/hosts/houdini/api/pipeline.py @@ -262,7 +262,29 @@ def parse_container(container): dict: The container schema data for this container node. """ - data = lib.read(container) + # Read only relevant parms + # TODO: Clean up this hack replacing `lib.read(container)` + import six + import json + from .lib import JSON_PREFIX + + data = {} + for name in ["name", "namespace", "loader", "representation", "id"]: + parm = container.parm(name) + if not parm: + return {} + + value = parm.eval() + + # test if value is json encoded dict + if isinstance(value, six.string_types) and \ + value.startswith(JSON_PREFIX): + try: + value = json.loads(value[len(JSON_PREFIX):]) + except json.JSONDecodeError: + # not a json + pass + data[name] = value # Backwards compatibility pre-schemas for containers data["schema"] = data.get("schema", "openpype:container-1.0") diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py b/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py new file mode 100644 index 0000000000..2c6aff4276 --- /dev/null +++ b/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py @@ -0,0 +1,52 @@ +from ayon_core.pipeline import load +from ayon_core.hosts.houdini.api.lib import find_active_network + +import hou + + +class LOPLoadAssetLoader(load.LoaderPlugin): + + product_types = {"*"} + label = "Load Asset (LOPs)" + representations = ["usd", "abc", "usda", "usdc"] + order = -10 + icon = "code-fork" + color = "orange" + + def load(self, context, name=None, namespace=None, data=None): + + # Define node name + namespace = namespace if namespace else context["asset"]["name"] + node_name = "{}_{}".format(namespace, name) if namespace else name + + # Create node + network = find_active_network( + category=hou.lopNodeTypeCategory(), + default="/stage" + ) + node = network.createNode("ayon::lop_import", node_name=node_name) + node.moveToGoodPosition() + + # Set representation id + representation_id = str(context["representation"]["_id"]) + parm = node.parm("representation") + parm.set(representation_id) + parm.pressButton() # trigger callbacks + + nodes = [node] + self[:] = nodes + + def update(self, container, representation): + node = container["node"] + + representation_id = str(representation["_id"]) + parm = node.parm("representation") + parm.set(representation_id) + parm.pressButton() # trigger callbacks + + def remove(self, container): + node = container["node"] + node.destroy() + + def switch(self, container, representation): + self.update(container, representation) diff --git a/client/ayon_core/hosts/houdini/resources/otls/ayon_lop_import.hda b/client/ayon_core/hosts/houdini/resources/otls/ayon_lop_import.hda new file mode 100644 index 0000000000000000000000000000000000000000..c38cdd5d79747a9c95e09a994d83850f9abcf922 GIT binary patch literal 41786 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�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 bIKn%=epF1 Date: Wed, 27 Mar 2024 20:06:58 +0100 Subject: [PATCH 02/50] Remove print statement within hda --- .../resources/otls/ayon_lop_import.hda | Bin 41786 -> 41729 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/client/ayon_core/hosts/houdini/resources/otls/ayon_lop_import.hda b/client/ayon_core/hosts/houdini/resources/otls/ayon_lop_import.hda index c38cdd5d79747a9c95e09a994d83850f9abcf922..7fd225060dfc4005a4c6c94d83e90b7fcbb10dec 100644 GIT binary patch delta 2070 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 Date: Thu, 28 Mar 2024 12:44:13 +0100 Subject: [PATCH 03/50] Fix refactor to AYON on Loader Plugin Co-authored-by: Mustafa Taher --- .../hosts/houdini/plugins/load/load_asset_lop.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py b/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py index 2c6aff4276..0158eb7243 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py @@ -16,7 +16,7 @@ class LOPLoadAssetLoader(load.LoaderPlugin): def load(self, context, name=None, namespace=None, data=None): # Define node name - namespace = namespace if namespace else context["asset"]["name"] + namespace = namespace if namespace else context["folder"]["name"] node_name = "{}_{}".format(namespace, name) if namespace else name # Create node @@ -28,7 +28,7 @@ def load(self, context, name=None, namespace=None, data=None): node.moveToGoodPosition() # Set representation id - representation_id = str(context["representation"]["_id"]) + representation_id = str(context["representation"]["id"]) parm = node.parm("representation") parm.set(representation_id) parm.pressButton() # trigger callbacks @@ -36,10 +36,10 @@ def load(self, context, name=None, namespace=None, data=None): nodes = [node] self[:] = nodes - def update(self, container, representation): + def update(self, container, context): node = container["node"] - representation_id = str(representation["_id"]) + representation_id = str(context["representation"]["id"]) parm = node.parm("representation") parm.set(representation_id) parm.pressButton() # trigger callbacks @@ -48,5 +48,5 @@ def remove(self, container): node = container["node"] node.destroy() - def switch(self, container, representation): - self.update(container, representation) + def switch(self, container, context): + self.update(container, context) From a35b9cccf3c2e1ed518580d63c2bed6d611a4505 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 28 Mar 2024 12:46:18 +0100 Subject: [PATCH 04/50] Cosmetics --- .../hosts/houdini/plugins/load/load_asset_lop.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py b/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py index 0158eb7243..6ce181028e 100644 --- a/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py +++ b/client/ayon_core/hosts/houdini/plugins/load/load_asset_lop.py @@ -5,6 +5,7 @@ class LOPLoadAssetLoader(load.LoaderPlugin): + """Load reference/payload into Solaris using AYON `lop_import` LOP""" product_types = {"*"} label = "Load Asset (LOPs)" @@ -28,9 +29,8 @@ def load(self, context, name=None, namespace=None, data=None): node.moveToGoodPosition() # Set representation id - representation_id = str(context["representation"]["id"]) parm = node.parm("representation") - parm.set(representation_id) + parm.set(context["representation"]["id"]) parm.pressButton() # trigger callbacks nodes = [node] @@ -39,9 +39,9 @@ def load(self, context, name=None, namespace=None, data=None): def update(self, container, context): node = container["node"] - representation_id = str(context["representation"]["id"]) + # Set representation id parm = node.parm("representation") - parm.set(representation_id) + parm.set(context["representation"]["id"]) parm.pressButton() # trigger callbacks def remove(self, container): From 6948d0c748458548c94c72acb18da11a667b4fe4 Mon Sep 17 00:00:00 2001 From: Lyon_Rosenblatt <48656065+lyon040502003@users.noreply.github.com> Date: Mon, 1 Apr 2024 13:20:33 +0200 Subject: [PATCH 05/50] changed Exception to ayon_api.exceptions.GraphQlQueryFailed in def set_representation(node, repre_id): in order to avoide error shadowing --- client/ayon_core/hosts/houdini/api/hda_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/api/hda_utils.py b/client/ayon_core/hosts/houdini/api/hda_utils.py index f80046173a..68660d2ed2 100644 --- a/client/ayon_core/hosts/houdini/api/hda_utils.py +++ b/client/ayon_core/hosts/houdini/api/hda_utils.py @@ -139,7 +139,7 @@ def set_representation(node, repre_id): get_current_project_name() try: repre_entity = get_representation_by_id(project_name, repre_id) - except Exception: + except ayon_api.exceptions.GraphQlQueryFailed: # Ignore invalid representation ids silently repre_entity = None From 2c52f932ef9dc8187e1fe0bc170582366360cdd2 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 15 Apr 2024 15:47:12 +0200 Subject: [PATCH 06/50] Apply suggestions from code review Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/hosts/houdini/api/hda_utils.py | 12 ++++++------ client/ayon_core/hosts/houdini/api/lib.py | 16 +++++++--------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/client/ayon_core/hosts/houdini/api/hda_utils.py b/client/ayon_core/hosts/houdini/api/hda_utils.py index 68660d2ed2..d4cef75986 100644 --- a/client/ayon_core/hosts/houdini/api/hda_utils.py +++ b/client/ayon_core/hosts/houdini/api/hda_utils.py @@ -320,24 +320,24 @@ def get_representation_id( if not product_entity: load_message_parm.set(f"Product not found: '{product_name}'") return - version_doc = get_version_by_name( + version_entity = get_version_by_name( project_name, version, product_id=product_entity["id"], fields=id_only) - if not version_doc: + if not version_entity: load_message_parm.set(f"Version not found: '{version}'") return - representation_doc = get_representation_by_name( + representation_entity = get_representation_by_name( project_name, representation_name, - version_id=version_doc["id"], + version_id=version_entity["id"], fields=id_only) - if not representation_doc: + if not representation_entity: load_message_parm.set( f"Representation not found: '{representation_name}'.") return - return representation_doc["id"] + return representation_entity["id"] def setup_flag_changed_callback(node): diff --git a/client/ayon_core/hosts/houdini/api/lib.py b/client/ayon_core/hosts/houdini/api/lib.py index 239e405c98..ea673dc25d 100644 --- a/client/ayon_core/hosts/houdini/api/lib.py +++ b/client/ayon_core/hosts/houdini/api/lib.py @@ -1021,11 +1021,11 @@ def _parse(image_data): try: images = json.loads(data) - if not raw: - images = [_parse(_data) for _data in images] except json.decoder.JSONDecodeError: images = [] + if not raw: + images = [_parse(_data) for _data in images] return images @@ -1051,13 +1051,11 @@ def _serialize(image): data = { "path": image.path(), "rect": [rect_min.x(), rect_min.y(), rect_max.x(), rect_max.y()], - "brightness": image.brightness(), - "relativetopath": image.relativeToPath() } - if data["brightness"] == 1.0: - del data["brightness"] - if data["relativetopath"] == "": - del data["relativetopath"] + if image.brightness() != 1.0: + data["brightness"] = image.brightness() + if image.relativeToPath(): + data["relativetopath"] = image.relativeToPath() return data with hou.undos.group('Edit Background Images'): @@ -1204,10 +1202,10 @@ def find_active_network(category, default): index = 0 while True: pane = hou.ui.paneTabOfType(hou.paneTabType.NetworkEditor, index) - index += 1 if pane is None: break + index += 1 if not pane.isCurrentTab(): continue From 54d00c78ee7dcc66d0207cc1503647dfe16e1f05 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 15 Apr 2024 15:51:24 +0200 Subject: [PATCH 07/50] Raise errors instead of assert --- client/ayon_core/hosts/houdini/api/lib.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/hosts/houdini/api/lib.py b/client/ayon_core/hosts/houdini/api/lib.py index 239e405c98..3894f369e4 100644 --- a/client/ayon_core/hosts/houdini/api/lib.py +++ b/client/ayon_core/hosts/houdini/api/lib.py @@ -1040,9 +1040,12 @@ def _serialize(image): """Return hou.NetworkImage as serialized dict""" if isinstance(image, dict): # Assume already serialized, only do some minor validations - assert "path" in image - assert "rect" in image - assert len(image["rect"]) == 4 + if "path" not in image: + raise ValueError("Missing `path` key in image dictionary.") + if "rect" not in image: + raise ValueError("Missing `rect` key in image dictionary.") + if len(image["rect"]) != 4: + raise ValueError("`rect` value must be list of four floats.") return image rect = image.rect() From 0e1f36ec8531e1ef5f409d6e4bf15da8780f0d20 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 15 Apr 2024 15:53:05 +0200 Subject: [PATCH 08/50] Move imports --- client/ayon_core/hosts/houdini/api/pipeline.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/hosts/houdini/api/pipeline.py b/client/ayon_core/hosts/houdini/api/pipeline.py index 4568640f84..d2fa68184d 100644 --- a/client/ayon_core/hosts/houdini/api/pipeline.py +++ b/client/ayon_core/hosts/houdini/api/pipeline.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- """Pipeline tools for OpenPype Houdini integration.""" import os +import six +import json import logging import hou # noqa @@ -25,6 +27,8 @@ emit_event, ) +from .lib import JSON_PREFIX + log = logging.getLogger("ayon_core.hosts.houdini") @@ -264,9 +268,6 @@ def parse_container(container): """ # Read only relevant parms # TODO: Clean up this hack replacing `lib.read(container)` - import six - import json - from .lib import JSON_PREFIX data = {} for name in ["name", "namespace", "loader", "representation", "id"]: From bef67347ecbc990813a3b933c7c5342815bfabb7 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 15 Apr 2024 15:58:13 +0200 Subject: [PATCH 09/50] More explicit UUID check for representation entity to avoid shadowing other errors --- client/ayon_core/hosts/houdini/api/hda_utils.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/houdini/api/hda_utils.py b/client/ayon_core/hosts/houdini/api/hda_utils.py index d4cef75986..020473fe03 100644 --- a/client/ayon_core/hosts/houdini/api/hda_utils.py +++ b/client/ayon_core/hosts/houdini/api/hda_utils.py @@ -2,6 +2,7 @@ import os import contextlib +import uuid import ayon_api from ayon_api import ( @@ -24,6 +25,15 @@ import hou +def is_valid_uuid(value) -> bool: + """Return whether value is a valid UUID""" + try: + uuid.UUID(value) + except ValueError: + return False + return True + + @contextlib.contextmanager def _unlocked_parm(parm): """Unlock parm during context; will always lock after""" @@ -137,9 +147,10 @@ def set_representation(node, repre_id): if repre_id: project_name = node.evalParm("project_name") or \ get_current_project_name() - try: + + if is_valid_uuid(repre_id): repre_entity = get_representation_by_id(project_name, repre_id) - except ayon_api.exceptions.GraphQlQueryFailed: + else: # Ignore invalid representation ids silently repre_entity = None From 49a8ef420c80e78bf0c813ce0f0773e3041a6098 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 15 Apr 2024 16:00:51 +0200 Subject: [PATCH 10/50] Tweak comment wording --- client/ayon_core/hosts/houdini/api/hda_utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/hosts/houdini/api/hda_utils.py b/client/ayon_core/hosts/houdini/api/hda_utils.py index 020473fe03..25a896ca17 100644 --- a/client/ayon_core/hosts/houdini/api/hda_utils.py +++ b/client/ayon_core/hosts/houdini/api/hda_utils.py @@ -102,10 +102,11 @@ def update_info(node, context): version = str(context["version"]["version"]) # We only set the values if the value does not match the currently - # evaluated result of the other parms, so that if the the project name + # evaluated result of the other parms, so that if the project name # value was dynamically set by the user with an expression or alike # then if it still matches the value of the current representation id - # we preserve it + # we preserve it. In essence, only update the value if the current + # *evaluated* value of the parm differs. parms = { "project_name": context["project"]["name"], "folder_path": context["folder"]["path"], From 644e458d70bffda1991a38b6eb6a1c41d45c257a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 7 May 2024 00:08:11 +0200 Subject: [PATCH 11/50] Apply suggestions from code review by iLliCiTiT Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../ayon_core/hosts/houdini/api/hda_utils.py | 84 ++++++++++--------- client/ayon_core/hosts/houdini/api/lib.py | 4 +- .../ayon_core/hosts/houdini/api/pipeline.py | 3 +- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/client/ayon_core/hosts/houdini/api/hda_utils.py b/client/ayon_core/hosts/houdini/api/hda_utils.py index 25a896ca17..a6bf00641a 100644 --- a/client/ayon_core/hosts/houdini/api/hda_utils.py +++ b/client/ayon_core/hosts/houdini/api/hda_utils.py @@ -64,24 +64,26 @@ def get_available_versions(node): return [] id_only = ["id"] - folder_entity = get_folder_by_path(project_name, - folder_path, - fields=id_only) + folder_entity = get_folder_by_path( + project_name, + folder_path, + fields={"id"}) if not folder_entity: return [] product_entity = get_product_by_name( project_name, product_name=product_name, folder_id=folder_entity["id"], - fields=id_only) + fields={"id"}) if not product_entity: return [] # TODO: Support hero versions - versions = get_versions(project_name=project_name, - product_ids=[product_entity["id"]], - fields=["version"], - hero=False) + versions = get_versions( + project_name, + product_ids={product_entity["id"]}, + fields={"version"}, + hero=False) version_names = [version["version"] for version in versions] version_names.reverse() return version_names @@ -145,40 +147,46 @@ def _get_thumbnail(project_name, version_id, thumbnail_dir): def set_representation(node, repre_id): file_parm = node.parm("file") - if repre_id: - project_name = node.evalParm("project_name") or \ - get_current_project_name() - - if is_valid_uuid(repre_id): - repre_entity = get_representation_by_id(project_name, repre_id) - else: - # Ignore invalid representation ids silently - repre_entity = None - - if repre_entity: - context = get_representation_context(project_name, repre_entity) - update_info(node, context) - path = get_representation_path_from_context(context) - # Load fails on UNC paths with backslashes and also - # fails to resolve @sourcename var with backslashed - # paths correctly. So we force forward slashes - path = path.replace("\\", "/") - with _unlocked_parm(file_parm): - file_parm.set(path) - - if node.evalParm("show_thumbnail"): - # Update thumbnail - # TODO: Cache thumbnail path as well - version_id = repre_entity["versionId"] - thumbnail_dir = node.evalParm("thumbnail_cache_dir") - thumbnail_path = _get_thumbnail(project_name, version_id, - thumbnail_dir) - set_node_thumbnail(node, thumbnail_path) - else: + if not repre_id: # Clear filepath and thumbnail with _unlocked_parm(file_parm): file_parm.set("") set_node_thumbnail(node, None) + return + + project_name = ( + node.evalParm("project_name") + or get_current_project_name() + ) + + # Ignore invalid representation ids silently + # TODO remove - added for backwards compatibility with OpenPype scenes + if not is_valid_uuid(repre_id): + return + + repre_entity = get_representation_by_id(project_name, repre_id) + if not repre_entity: + return + + context = get_representation_context(project_name, repre_entity) + update_info(node, context) + path = get_representation_path_from_context(context) + # Load fails on UNC paths with backslashes and also + # fails to resolve @sourcename var with backslashed + # paths correctly. So we force forward slashes + path = path.replace("\\", "/") + with _unlocked_parm(file_parm): + file_parm.set(path) + + if node.evalParm("show_thumbnail"): + # Update thumbnail + # TODO: Cache thumbnail path as well + version_id = repre_entity["versionId"] + thumbnail_dir = node.evalParm("thumbnail_cache_dir") + thumbnail_path = _get_thumbnail( + project_name, version_id, thumbnail_dir + ) + set_node_thumbnail(node, thumbnail_path) def set_node_thumbnail(node, thumbnail): diff --git a/client/ayon_core/hosts/houdini/api/lib.py b/client/ayon_core/hosts/houdini/api/lib.py index d6c599deda..384179bec3 100644 --- a/client/ayon_core/hosts/houdini/api/lib.py +++ b/client/ayon_core/hosts/houdini/api/lib.py @@ -1150,9 +1150,7 @@ def _serialize(image): node.destroyUserData("backgroundimages", must_exist=False) -def set_node_thumbnail(node, - image_path, - rect=None): +def set_node_thumbnail(node, image_path, rect=None): """Set hou.NetworkImage attached to node. If an existing connected image is found it assumes that is the existing diff --git a/client/ayon_core/hosts/houdini/api/pipeline.py b/client/ayon_core/hosts/houdini/api/pipeline.py index 75ef36e701..7ea85cae36 100644 --- a/client/ayon_core/hosts/houdini/api/pipeline.py +++ b/client/ayon_core/hosts/houdini/api/pipeline.py @@ -278,8 +278,7 @@ def parse_container(container): value = parm.eval() # test if value is json encoded dict - if isinstance(value, six.string_types) and \ - value.startswith(JSON_PREFIX): + if isinstance(value, str) and value.startswith(JSON_PREFIX): try: value = json.loads(value[len(JSON_PREFIX):]) except json.JSONDecodeError: From 23ce776c82f8c0fa93464c08e624a89ac1aa8302 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 7 May 2024 00:10:28 +0200 Subject: [PATCH 12/50] Set `fields` explicitly per call as `{"id"}` --- client/ayon_core/hosts/houdini/api/hda_utils.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/hosts/houdini/api/hda_utils.py b/client/ayon_core/hosts/houdini/api/hda_utils.py index a6bf00641a..21436692c2 100644 --- a/client/ayon_core/hosts/houdini/api/hda_utils.py +++ b/client/ayon_core/hosts/houdini/api/hda_utils.py @@ -319,10 +319,9 @@ def get_representation_id( "Make sure to set a valid version number.") return - id_only = ["id"] folder_entity = get_folder_by_path(project_name, folder_path=folder_path, - fields=id_only) + fields={"id"}) if not folder_entity: # This may be due to the project not existing - so let's validate # that first @@ -336,7 +335,7 @@ def get_representation_id( project_name, product_name=product_name, folder_id=folder_entity["id"], - fields=id_only) + fields={"id"}) if not product_entity: load_message_parm.set(f"Product not found: '{product_name}'") return @@ -344,7 +343,7 @@ def get_representation_id( project_name, version, product_id=product_entity["id"], - fields=id_only) + fields={"id"}) if not version_entity: load_message_parm.set(f"Version not found: '{version}'") return @@ -352,7 +351,7 @@ def get_representation_id( project_name, representation_name, version_id=version_entity["id"], - fields=id_only) + fields={"id"}) if not representation_entity: load_message_parm.set( f"Representation not found: '{representation_name}'.") From ffb942628e6f6f13143fcba0be28c6cc3575cda2 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 7 May 2024 00:11:14 +0200 Subject: [PATCH 13/50] Update client/ayon_core/hosts/houdini/api/hda_utils.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- client/ayon_core/hosts/houdini/api/hda_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/api/hda_utils.py b/client/ayon_core/hosts/houdini/api/hda_utils.py index a6bf00641a..43cb430b5b 100644 --- a/client/ayon_core/hosts/houdini/api/hda_utils.py +++ b/client/ayon_core/hosts/houdini/api/hda_utils.py @@ -63,7 +63,6 @@ def get_available_versions(node): ]): return [] - id_only = ["id"] folder_entity = get_folder_by_path( project_name, folder_path, From bb70229eb576949306a67e1d323db175dae9a23d Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 7 May 2024 00:11:55 +0200 Subject: [PATCH 14/50] Fix grammar --- client/ayon_core/hosts/houdini/api/hda_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/houdini/api/hda_utils.py b/client/ayon_core/hosts/houdini/api/hda_utils.py index 497648369d..c5c5484e64 100644 --- a/client/ayon_core/hosts/houdini/api/hda_utils.py +++ b/client/ayon_core/hosts/houdini/api/hda_utils.py @@ -48,7 +48,7 @@ def get_available_versions(node): """Return the versions list for node. Args: - node (hou.Node): Node to query selected products's versions for. + node (hou.Node): Node to query selected products' versions for. Returns: List[int]: Version numbers for the product From cdb6bc7535693aeca5e7eb211f7cf718a62e8dc6 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 3 Jun 2024 17:31:32 +0200 Subject: [PATCH 15/50] Fix refactoring of imports --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 4 ++-- .../client/ayon_houdini/plugins/load/load_asset_lop.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index c5c5484e64..12b455bbac 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -20,7 +20,7 @@ ) from ayon_core.pipeline.context_tools import get_current_project_name -from ayon_core.hosts.houdini.api import lib +from ayon_houdini.api import lib import hou @@ -399,7 +399,7 @@ def keep_background_images_linked(node, old_name): """Reconnect background images to node from old name. Used as callback on node name changes to keep thumbnails linked.""" - from ayon_core.hosts.houdini.api.lib import ( + from ayon_houdini.api.lib import ( get_background_images, set_background_images ) diff --git a/server_addon/houdini/client/ayon_houdini/plugins/load/load_asset_lop.py b/server_addon/houdini/client/ayon_houdini/plugins/load/load_asset_lop.py index 6ce181028e..d9ab438d6d 100644 --- a/server_addon/houdini/client/ayon_houdini/plugins/load/load_asset_lop.py +++ b/server_addon/houdini/client/ayon_houdini/plugins/load/load_asset_lop.py @@ -1,5 +1,5 @@ from ayon_core.pipeline import load -from ayon_core.hosts.houdini.api.lib import find_active_network +from ayon_houdini.api.lib import find_active_network import hou From eeb38397b631042cb6828b59535f7e641b1b0ec2 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 3 Jun 2024 17:37:35 +0200 Subject: [PATCH 16/50] Bumped addon version --- server_addon/houdini/client/ayon_houdini/version.py | 2 +- server_addon/houdini/package.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/version.py b/server_addon/houdini/client/ayon_houdini/version.py index a30c770e1d..eff044feba 100644 --- a/server_addon/houdini/client/ayon_houdini/version.py +++ b/server_addon/houdini/client/ayon_houdini/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Houdini addon version.""" -__version__ = "0.3.0" +__version__ = "0.3.1" diff --git a/server_addon/houdini/package.py b/server_addon/houdini/package.py index 275d21c1bf..a8884ff60a 100644 --- a/server_addon/houdini/package.py +++ b/server_addon/houdini/package.py @@ -1,6 +1,6 @@ name = "houdini" title = "Houdini" -version = "0.3.0" +version = "0.3.1" client_dir = "ayon_houdini" From 7e6ecc8bd0b9db4da482bc6fec074f7e611f68f6 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 3 Jun 2024 23:50:18 +0200 Subject: [PATCH 17/50] Move HDA --- .../ayon_houdini/startup}/otls/ayon_lop_import.hda | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename {client/ayon_core/hosts/houdini/resources => server_addon/houdini/client/ayon_houdini/startup}/otls/ayon_lop_import.hda (100%) diff --git a/client/ayon_core/hosts/houdini/resources/otls/ayon_lop_import.hda b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda similarity index 100% rename from client/ayon_core/hosts/houdini/resources/otls/ayon_lop_import.hda rename to server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda From ef5048d62e20aab9df9bc694c2594cc65acf881a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 3 Jun 2024 23:51:14 +0200 Subject: [PATCH 18/50] Revert changes to `addon.py` --- .../houdini/client/ayon_houdini/addon.py | 64 ++++++++----------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/addon.py b/server_addon/houdini/client/ayon_houdini/addon.py index 8f82ee2e76..95d714aea1 100644 --- a/server_addon/houdini/client/ayon_houdini/addon.py +++ b/server_addon/houdini/client/ayon_houdini/addon.py @@ -4,49 +4,41 @@ HOUDINI_HOST_DIR = os.path.dirname(os.path.abspath(__file__)) -def merge_paths(*paths): - """Merge path strings to a single uniqified `os.pathsep` joined string. - Each path argument can itself be `os.pathsep` joined string. - >>> merge_paths("A", "A;B;C", "D;E") - "A;B;C;D;E" - Returns: - str: Single joined path using `os.pathsep` - """ - result = [] - processed = set() - for paths_str in paths: - for path in paths_str.split(os.pathsep): - if not path: - continue +class HoudiniAddon(AYONAddon, IHostAddon): + name = "houdini" + host_name = "houdini" + + def add_implementation_envs(self, env, _app): + # Add requirements to HOUDINI_PATH and HOUDINI_MENU_PATH + startup_path = os.path.join(HOUDINI_HOST_DIR, "startup") + new_houdini_path = [startup_path] + new_houdini_menu_path = [startup_path] + + old_houdini_path = env.get("HOUDINI_PATH") or "" + old_houdini_menu_path = env.get("HOUDINI_MENU_PATH") or "" - path = os.path.normpath(path) - if path in processed: + for path in old_houdini_path.split(os.pathsep): + if not path: continue - result.append(path) - processed.add(path) + norm_path = os.path.normpath(path) + if norm_path not in new_houdini_path: + new_houdini_path.append(norm_path) - return os.pathsep.join(result) + for path in old_houdini_menu_path.split(os.pathsep): + if not path: + continue + norm_path = os.path.normpath(path) + if norm_path not in new_houdini_menu_path: + new_houdini_menu_path.append(norm_path) -class HoudiniAddon(AYONAddon, IHostAddon): - name = "houdini" - host_name = "houdini" + # Add ampersand for unknown reason (Maybe is needed in Houdini?) + new_houdini_path.append("&") + new_houdini_menu_path.append("&") - def add_implementation_envs(self, env, _app): - # Add requirements to HOUDINI_PATH, HOUDINI_MENU_PATH, HOUDINI_OTL_PATH - startup_path = os.path.join(HOUDINI_HOST_DIR, "startup") - resources_path = os.path.join(HOUDINI_HOST_DIR, "resources") - - env["HOUDINI_PATH"] = merge_paths( - startup_path, env.get("HOUDINI_PATH", ""), "&" - ) - env["HOUDINI_MENU_PATH"] = merge_paths( - startup_path, env.get("HOUDINI_MENU_PATH", ""), "&" - ) - env["HOUDINI_OTL_PATH"] = merge_paths( - resources_path, env.get("HOUDINI_OTL_PATH", ""), "&" - ) + env["HOUDINI_PATH"] = os.pathsep.join(new_houdini_path) + env["HOUDINI_MENU_PATH"] = os.pathsep.join(new_houdini_menu_path) def get_launch_hook_paths(self, app): if app.host_name != self.host_name: From 05c5a42e8dbab4c527ce1e5d797de54936212d4a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 3 Jun 2024 23:55:23 +0200 Subject: [PATCH 19/50] Refactor `ayon_core.hosts.houdini` usage in HDA to `ayon_houdini` --- .../startup/otls/ayon_lop_import.hda | Bin 41729 -> 41693 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda index 7fd225060dfc4005a4c6c94d83e90b7fcbb10dec..6dc4ef7d149d3cbc8a4020efbf2500f76ece021c 100644 GIT binary patch delta 2113 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 S4uCL6&R0YBa1wkIt^Wtj=)d>? delta 2152 zcmY+Fc{J2*AI5*fP=+kcWZ#C6ZM-OJLWoIbD0^i688T)xGg)J@WU1_>V#pg&vNaPP z`zWG8NXXhEp2qH>kkUIko%5dO{^z={>+}8I=lbuS>g0-h$(5wO&WH9R63`(&I1su=ax}Q4sD&JS_zxGbkE8?=33f#P%Xkm~oSt*oW&jlT zjH7&5f+dItDWE?9I5%*D6b`84=m9JN;}Zf}1o{wgd(g$46E<<+-q3z5;SABo|9Ad_ zQ#=-&oaZ#%d(DCb`cOa~&W2l5P7jxy>=poUFaK$Bz}yXs@e1P9MTHV@0N^>t*v~zp zMICkvAx`KCf2$M9=ULRhIb6mYh&W5Ei$C;^F-(_cp=Kc;@qk&Abc8@;^NhgDLl0DRPAh)qOz0=0qosa+HCBt&k|xgI~`2-lU6m} zR^0(b@%p?zqru8^FzBKQjDFbXu~}o)teZ&c5!=Bkoa?&|xWB}^mvff<^rK*0cLWP% ziQuBSo%x#wu(%|8#c~Xvba2(J;#9m+A*0zzJ`&v z35Jb`8#jw{;@5C(ZDT)i7e9GY@n~~lo4XM@_n56PH6z1sRHuaEJN+VhrC(jRtwkXj zq_56QLD?ZnYY90?bheo{cKnve+_(bWx8q=@?MnKG^`$S??>B!1Gy@ps{?gWjl`S$9 zC3Z*q9Q^${o=;12QqnY)ebhWVBPD4N1vxQZ$BydI*2H~^lqDS)s+Fd~jfWoN8q(Rq z{t7p*{Q59pdL?@GQ@3fvr61o`zhHlDe>8q?{her?TrGr6e@~NMkZP(*4GiW9t1b~G zScMsm3WD@CcI^}8^yu}C_Dp47NIGT=Rj4q;%mp#VK6b4(t}nJe&PWz(<8*n=xOk5u zZCqfMUKv~Yr(;x^UrVXVmnt6D7IOV3LKM4Jf`(MH+Z;}ZKV7eo{fQki>jP6N^YJWI z>?xP=GM#-kjKoGDp7rVMt90! z=)Qb2x$4FEf}P#dJS)A1AXZesPN^2-r?)S+RC==h!|E)(C2uKSL5GBStjuH`BswF<7yJf&Jrg{aN^}2&_t)lYZaX zdzTtRD7jQttlKb#D!94QTrcKz&D{F0@ZE~;+~Zf5;9-J!AY5mFaVHt=1L(&LI>^gc zW=C2pbDu?q{DbR=`F4QiTRvm8>56$W*K*7D(0CJw0MBeI~q8|~HBS{wU+}s-deot-@~b zW&ic~sfWSRixc&t=x4J5mD$sb63y!AXCBiTKbxHrlj7(_%YRm=JKGgCo zk(zE{B(^!S66e*~29*qR>uBL_Y7A$W)2R5iSB&F+<8)@L#ZZ|wqswllUQkYF1D<$a zo?c93h~VE`V}CL>s43G;%q^){jX8!vXZyyUhh!r^TePCCN;@Id#A(8*J%tZ6+S&CR zkg_K(jcSPeok!c?BlJ@J)|Y9LNf2TIHEkc$-(9W)8=03ZIbbn8{p(_!wYt2j6udaC zXW!Ei$MlTY?U~^l#nu_JX}jFf;xnFRj3C2MIetGP2}A`F$(%1eXUui+U%t~V=3joy kRgnR@BcOZ`&X2fvgc$J`lp+7OIZwUHAwmof@3@oy1Ao`QLjV8( From 8aee5f120fc2d24c51dd38735dd058c7ea6a7f0c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 6 Jun 2024 01:10:20 +0200 Subject: [PATCH 20/50] Swap ayon_lop_import.hda with expanded otl This is done via `hotl` executable that comes with Houdini using the `-t` flag. Also see: https://github.com/ynput/ayon-core/issues/591#issuecomment-2147410097 --- .../startup/otls/ayon_lop_import.hda | Bin 41693 -> 0 bytes .../otls/ayon_lop_import.hda/INDEX__SECTION | 14 + .../otls/ayon_lop_import.hda/Sections.list | 4 + .../AYON__icon.png | Bin 0 -> 16907 bytes .../Contents.dir/Contents.createtimes | 6 + .../Contents.dir/Contents.houdini_versions | 9 + .../Contents.dir/Contents.mime | 384 ++++++++++++++++++ .../Contents.dir/Contents.modtimes | 6 + .../Contents.dir/Sections.list | 2 + .../CreateScript | 15 + .../DialogScript | 324 +++++++++++++++ .../ExtraFileOptions | 122 ++++++ .../ayon_8_8Lop_1lop__import_8_81.0/Help | 0 .../ayon_8_8Lop_1lop__import_8_81.0/IconImage | Bin 0 -> 6939 bytes .../InternalFileOptions | 10 + .../MessageNodes | 1 + .../ayon_8_8Lop_1lop__import_8_81.0/OnCreated | 5 + .../ayon_8_8Lop_1lop__import_8_81.0/OnDeleted | 6 + .../ayon_8_8Lop_1lop__import_8_81.0/OnLoaded | 15 + .../OnNameChanged | 8 + .../PythonModule | 8 + .../Sections.list | 17 + .../Tools.shelf | 19 + .../TypePropertiesOptions | 14 + .../ayon_lop_import.hda/houdini.hdalibrary | 0 25 files changed, 989 insertions(+) delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/Sections.list create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/AYON__icon.png create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.createtimes create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.houdini_versions create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.modtimes create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Sections.list create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/CreateScript create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/ExtraFileOptions create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Help create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/IconImage create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/InternalFileOptions create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/MessageNodes create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnCreated create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnDeleted create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnLoaded create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnNameChanged create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Sections.list create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Tools.shelf create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/TypePropertiesOptions create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/houdini.hdalibrary diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda deleted file mode 100644 index 6dc4ef7d149d3cbc8a4020efbf2500f76ece021c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41693 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 0, 0, -1)" } + parmtag { "sidefx::usdpathtype" "prim" } + } + parm { + name "timeoffset1" + label "Time Offset (in Frames)" + type float + default { "0" } + range { -100 100 } + parmtag { "autoscope" "0000000000000000" } + parmtag { "script_callback_language" "python" } + } + parm { + name "timescale1" + label "Time Scale" + type float + default { "1" } + range { 0 5 } + parmtag { "autoscope" "0000000000000000" } + parmtag { "script_callback_language" "python" } + } + } + + } + + groupcollapsible { + name "info_display2" + label "Info Display" + + parm { + name "show_thumbnail" + label "Show Entity Thumbnail" + type toggle + joinnext + default { "0" } + parmtag { "script_callback" "hou.phm().on_thumbnail_show_changed(kwargs['node'])" } + parmtag { "script_callback_language" "python" } + } + parm { + name "thumbnail_size" + label "Size" + type float + joinnext + default { "2" } + hidewhen "{ show_thumbnail == 0 }" + range { 0 10 } + parmtag { "script_callback" "hou.phm().on_thumbnail_size_changed(kwargs['node'])" } + parmtag { "script_callback_language" "python" } + } + parm { + name "thumbnail_cache_dir" + label "Thumbnail Cache Dir" + type directory + invisible + default { "$JOB/.houdini_loader_thumbnails" } + parmtag { "script_callback_language" "python" } + } + parm { + name "thumbnail_padding" + label "Padding" + type float + invisible + default { "1" } + range { 0 10 } + parmtag { "script_callback_language" "python" } + } + parm { + name "thumbnail_offset" + label "Offset" + type vector2 + size 2 + default { "0" "0.35" } + hidewhen "{ show_thumbnail == 0 }" + range { -1 1 } + parmtag { "script_callback" "hou.phm().on_thumbnail_size_changed(kwargs['node'])" } + parmtag { "script_callback_language" "python" } + } + parm { + name "show_pipeline_parms" + label "Show Pipeline Parms" + type toggle + default { "0" } + parmtag { "script_callback" "hou.phm().on_thumbnail_show_changed(kwargs['node'])" } + parmtag { "script_callback_language" "python" } + } + } + + group { + name "ayon_folder0" + label "Ayon" + hidewhen "{ show_pipeline_parms == 0 }" + + parm { + name "name" + label "Name" + type label + default { "$OS" } + } + parm { + name "namespace" + label "Namespace" + type label + default { "`opfullpath(\".\")`" } + } + parm { + name "loader" + label "Loader" + type label + default { "LOPLoadAssetLoader" } + } + parm { + name "id" + label "ID" + type label + default { "pyblish.avalon.container" } + } + parm { + name "representation" + label "Representation ID" + type string + default { "" } + parmtag { "script_callback" "hou.phm().on_representation_id_changed(kwargs['node'])" } + parmtag { "script_callback_language" "python" } + } + parm { + name "version_name" + label "Current Version Label" + type label + invisible + default { "" } + } + parm { + name "subset_name" + label "Subset (backwards compatibility)" + type label + invisible + default { "`chs(\"product_name\")`" } + } + } + +} diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/ExtraFileOptions b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/ExtraFileOptions new file mode 100644 index 0000000000..38babad6a2 --- /dev/null +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/ExtraFileOptions @@ -0,0 +1,122 @@ +{ + "AYON_icon.png/Cursor":{ + "type":"intarray", + "value":[0,0] + }, + "AYON_icon.png/IsExpr":{ + "type":"bool", + "value":false + }, + "AYON_icon.png/IsPython":{ + "type":"bool", + "value":false + }, + "AYON_icon.png/IsScript":{ + "type":"bool", + "value":false + }, + "AYON_icon.png/Source":{ + "type":"string", + "value":"C:/Users/Maqina-05/Desktop/AYON_icon.png" + }, + "OnCreated/Cursor":{ + "type":"intarray", + "value":[5,29] + }, + "OnCreated/IsExpr":{ + "type":"bool", + "value":false + }, + "OnCreated/IsPython":{ + "type":"bool", + "value":true + }, + "OnCreated/IsScript":{ + "type":"bool", + "value":true + }, + "OnCreated/Source":{ + "type":"string", + "value":"" + }, + "OnDeleted/Cursor":{ + "type":"intarray", + "value":[2,1] + }, + "OnDeleted/IsExpr":{ + "type":"bool", + "value":false + }, + "OnDeleted/IsPython":{ + "type":"bool", + "value":true + }, + "OnDeleted/IsScript":{ + "type":"bool", + "value":true + }, + "OnDeleted/Source":{ + "type":"string", + "value":"" + }, + "OnLoaded/Cursor":{ + "type":"intarray", + "value":[9,76] + }, + "OnLoaded/IsExpr":{ + "type":"bool", + "value":false + }, + "OnLoaded/IsPython":{ + "type":"bool", + "value":true + }, + "OnLoaded/IsScript":{ + "type":"bool", + "value":true + }, + "OnLoaded/Source":{ + "type":"string", + "value":"" + }, + "OnNameChanged/Cursor":{ + "type":"intarray", + "value":[4,1] + }, + "OnNameChanged/IsExpr":{ + "type":"bool", + "value":false + }, + "OnNameChanged/IsPython":{ + "type":"bool", + "value":true + }, + "OnNameChanged/IsScript":{ + "type":"bool", + "value":true + }, + "OnNameChanged/Source":{ + "type":"string", + "value":"" + }, + "PythonModule/Cursor":{ + "type":"intarray", + "value":[1,18] + }, + "PythonModule/IsExpr":{ + "type":"bool", + "value":false + }, + "PythonModule/IsPython":{ + "type":"bool", + "value":true + }, + "PythonModule/IsScript":{ + "type":"bool", + "value":true + }, + "PythonModule/Source":{ + "type":"string", + "value":"" + } +} diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Help b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Help new file mode 100644 index 0000000000..e69de29bb2 diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/IconImage b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/IconImage new file mode 100644 index 0000000000000000000000000000000000000000..aa0d42021d18d060470b471f05f06031ac2a056d GIT binary patch literal 6939 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 nj9>flH|4A;bjv5p2ZMqB`y< + + + + + LOP + + + $HDA_TABLE_AND_NAME + + CB Pipeline + + + + \ No newline at end of file diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/TypePropertiesOptions b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/TypePropertiesOptions new file mode 100644 index 0000000000..a6d52acf2a --- /dev/null +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/TypePropertiesOptions @@ -0,0 +1,14 @@ +CheckExternal := 1; +ContentsCompressionType := 1; +ForbidOutsideParms := 1; +GzipContents := 1; +LockContents := 1; +MakeDefault := 1; +ParmsFromVfl := 0; +PrefixDroppedParmLabel := 0; +PrefixDroppedParmName := 0; +SaveCachedCode := 0; +SaveIcon := 1; +SaveSpareParms := 0; +UnlockOnCreate := 0; +UseDSParms := 1; diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/houdini.hdalibrary b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/houdini.hdalibrary new file mode 100644 index 0000000000..e69de29bb2 From e33c2c7063f60c96f27c38357e36cf9abf34a782 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 6 Jun 2024 01:33:57 +0200 Subject: [PATCH 21/50] Add AYON to HDA label --- .../startup/otls/ayon_lop_import.hda/INDEX__SECTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION index 04fce876c6..8dd8ee6270 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION @@ -1,5 +1,5 @@ Operator: ayon::lop_import::1.0 -Label: Load Asset +Label: AYON Load Asset Path: oplib:/ayon::Lop/lop_import::1.0?ayon::Lop/lop_import::1.0 Icon: opdef:/ayon::Lop/lop_import::1.0?IconImage Table: Lop @@ -10,5 +10,5 @@ Inputs: 0 to 1 Subnet: true Python: false Empty: false -Modified: Mon Jun 3 23:54:46 2024 +Modified: Thu Jun 6 01:31:52 2024 From f6e9738837ed89870c118c9a7d4c0b69a9ddaf40 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Thu, 6 Jun 2024 15:36:11 +0300 Subject: [PATCH 22/50] add two more functions --- .../client/ayon_houdini/api/hda_utils.py | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index 12b455bbac..f83b8add09 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -18,7 +18,10 @@ get_representation_context, get_representation_path_from_context ) -from ayon_core.pipeline.context_tools import get_current_project_name +from ayon_core.pipeline.context_tools import ( + get_current_project_name, + get_current_folder_path +) from ayon_houdini.api import lib @@ -418,3 +421,74 @@ def keep_background_images_linked(node, old_name): if changes: set_background_images(parent, images) + + +def get_products_menu_items(node): + """Return products menu items + + It gets a list of available products of the specified product types + within the specified folder path with in the specified project. + + Users can specify those in the HDA parameters. + + Returns: + List[str]: Product options for Products menu. + """ + project_name = node.evalParm("project_name") + folder_path = node.evalParm("folder_path") + representation_name = node.evalParm("representation_name") + + folder_entity = ayon_api.get_folder_by_path(project_name, + folder_path, + fields={"id"}) + if not folder_entity: + return [] + + products = ayon_api.get_products( + project_name, + folder_ids=[folder_entity["id"]], + product_types=[representation_name] + ) + + items = [] + for product in products: + items.append(product["name"]) + items.append(product["name"]) + + return(items) + + +def select_folder_path(node): + """select folder path. + + When triggered it opens a dialog shows the available + folder paths within a given project. + + Users can specify that in the HDA parameters. + + Note: + This function should be refactored. + It currently shows the available + folder paths within the current project only. + """ + from ayon_core.tools.publisher.widgets.folders_dialog import FoldersDialog + from ayon_core.tools.utils.host_tools import get_tool_by_name + + main_window = lib.get_main_window() + publisher_window = get_tool_by_name( tool_name="publisher", parent=main_window) + + # TODO: A dedicated Dialog should be implement using `SimpleFoldersWidget`. + # we should avoid using `FoldersDialog` because It's highly recommend to + # never use inner widgets of any tool... + # Note: The following dialog doesn't support changing `the project_name` + # But, having a semi-functional dialog is better than nothing. + dialog = FoldersDialog(publisher_window.controller, main_window) + dialog.exec_() + + selected_folder_path = dialog.get_selected_folder_path() + + if not selected_folder_path or \ + selected_folder_path == get_current_folder_path(): + selected_folder_path = '$AYON_FOLDER_PATH' + + node.parm("folder_path").set(selected_folder_path) From 9f73f5968a334abb1da55b006b5205a447492def Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Thu, 6 Jun 2024 15:36:42 +0300 Subject: [PATCH 23/50] add ayon::lop_import::1.1 --- .../otls/ayon_lop_import.hda/INDEX__SECTION | 19 +- .../otls/ayon_lop_import.hda/Sections.list | 1 + .../AYON__icon.png | Bin 0 -> 16907 bytes .../Contents.dir/Contents.createtimes | 6 + .../Contents.dir/Contents.houdini_versions | 9 + .../Contents.dir/Contents.mime | 384 ++++++++++++++++++ .../Contents.dir/Contents.modtimes | 6 + .../Contents.dir/Sections.list | 2 + .../CreateScript | 15 + .../DialogScript | 330 +++++++++++++++ .../ExtraFileOptions | 122 ++++++ .../ayon_8_8Lop_1lop__import_8_81.1/Help | 0 .../ayon_8_8Lop_1lop__import_8_81.1/IconImage | Bin 0 -> 6939 bytes .../InternalFileOptions | 10 + .../MessageNodes | 1 + .../ayon_8_8Lop_1lop__import_8_81.1/OnCreated | 5 + .../ayon_8_8Lop_1lop__import_8_81.1/OnDeleted | 6 + .../ayon_8_8Lop_1lop__import_8_81.1/OnLoaded | 14 + .../OnNameChanged | 8 + .../PythonModule | 9 + .../Sections.list | 17 + .../Tools.shelf | 18 + .../TypePropertiesOptions | 14 + 23 files changed, 993 insertions(+), 3 deletions(-) create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/AYON__icon.png create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Contents.dir/Contents.createtimes create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Contents.dir/Contents.houdini_versions create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Contents.dir/Contents.mime create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Contents.dir/Contents.modtimes create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Contents.dir/Sections.list create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/CreateScript create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/DialogScript create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/ExtraFileOptions create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Help create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/IconImage create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/InternalFileOptions create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/MessageNodes create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/OnCreated create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/OnDeleted create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/OnLoaded create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/OnNameChanged create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/PythonModule create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Sections.list create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Tools.shelf create mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/TypePropertiesOptions diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION index 8dd8ee6270..f558dfa687 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION @@ -3,12 +3,25 @@ Label: AYON Load Asset Path: oplib:/ayon::Lop/lop_import::1.0?ayon::Lop/lop_import::1.0 Icon: opdef:/ayon::Lop/lop_import::1.0?IconImage Table: Lop -License: -Extra: -User: +License: +Extra: +User: Inputs: 0 to 1 Subnet: true Python: false Empty: false Modified: Thu Jun 6 01:31:52 2024 +Operator: ayon::lop_import::1.1 +Label: AYON Load Asset +Path: oplib:/ayon::Lop/lop_import::1.1?ayon::Lop/lop_import::1.1 +Icon: opdef:/ayon::Lop/lop_import::1.1?IconImage +Table: Lop +License: +Extra: +User: +Inputs: 0 to 1 +Subnet: true +Python: false +Empty: false +Modified: Thu Jun 6 03:33:00 2024 diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/Sections.list b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/Sections.list index 0a1bfe4e69..074defe264 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/Sections.list +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/Sections.list @@ -2,3 +2,4 @@ INDEX__SECTION INDEX_SECTION houdini.hdalibrary houdini.hdalibrary ayon_8_8Lop_1lop__import_8_81.0 ayon::Lop/lop_import::1.0 +ayon_8_8Lop_1lop__import_8_81.1 ayon::Lop/lop_import::1.1 diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/AYON__icon.png b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/AYON__icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ed13aeea527299092c400f18045b11b28c4d23ac GIT binary patch literal 16907 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 0, 0, -1)" } + parmtag { "sidefx::usdpathtype" "prim" } + } + parm { + name "timeoffset1" + label "Time Offset (in Frames)" + type float + default { "0" } + range { -100 100 } + parmtag { "autoscope" "0000000000000000" } + parmtag { "script_callback_language" "python" } + } + parm { + name "timescale1" + label "Time Scale" + type float + default { "1" } + range { 0 5 } + parmtag { "autoscope" "0000000000000000" } + parmtag { "script_callback_language" "python" } + } + } + + } + + groupcollapsible { + name "info_display2" + label "Info Display" + + parm { + name "show_thumbnail" + label "Show Entity Thumbnail" + type toggle + joinnext + default { "0" } + parmtag { "script_callback" "hou.phm().on_thumbnail_show_changed(kwargs['node'])" } + parmtag { "script_callback_language" "python" } + } + parm { + name "thumbnail_size" + label "Size" + type float + joinnext + default { "2" } + hidewhen "{ show_thumbnail == 0 }" + range { 0 10 } + parmtag { "script_callback" "hou.phm().on_thumbnail_size_changed(kwargs['node'])" } + parmtag { "script_callback_language" "python" } + } + parm { + name "thumbnail_cache_dir" + label "Thumbnail Cache Dir" + type directory + invisible + default { "$JOB/.houdini_loader_thumbnails" } + parmtag { "script_callback_language" "python" } + } + parm { + name "thumbnail_padding" + label "Padding" + type float + invisible + default { "1" } + range { 0 10 } + parmtag { "script_callback_language" "python" } + } + parm { + name "thumbnail_offset" + label "Offset" + type vector2 + size 2 + default { "0" "0.35" } + hidewhen "{ show_thumbnail == 0 }" + range { -1 1 } + parmtag { "script_callback" "hou.phm().on_thumbnail_size_changed(kwargs['node'])" } + parmtag { "script_callback_language" "python" } + } + parm { + name "show_pipeline_parms" + label "Show Pipeline Parms" + type toggle + default { "0" } + parmtag { "script_callback" "hou.phm().on_thumbnail_show_changed(kwargs['node'])" } + parmtag { "script_callback_language" "python" } + } + } + + group { + name "ayon_folder0" + label "Ayon" + hidewhen "{ show_pipeline_parms == 0 }" + + parm { + name "name" + label "Name" + type label + default { "$OS" } + } + parm { + name "namespace" + label "Namespace" + type label + default { "`opfullpath(\".\")`" } + } + parm { + name "loader" + label "Loader" + type label + default { "LOPLoadAssetLoader" } + } + parm { + name "id" + label "ID" + type label + default { "pyblish.avalon.container" } + } + parm { + name "representation" + label "Representation ID" + type string + default { "" } + parmtag { "script_callback" "hou.phm().on_representation_id_changed(kwargs['node'])" } + parmtag { "script_callback_language" "python" } + } + parm { + name "version_name" + label "Current Version Label" + type label + invisible + default { "" } + } + parm { + name "subset_name" + label "Subset (backwards compatibility)" + type label + invisible + default { "`chs(\"product_name\")`" } + } + } + +} diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/ExtraFileOptions b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/ExtraFileOptions new file mode 100644 index 0000000000..fb58b6889f --- /dev/null +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/ExtraFileOptions @@ -0,0 +1,122 @@ +{ + "AYON_icon.png/Cursor":{ + "type":"intarray", + "value":[0,0] + }, + "AYON_icon.png/IsExpr":{ + "type":"bool", + "value":false + }, + "AYON_icon.png/IsPython":{ + "type":"bool", + "value":false + }, + "AYON_icon.png/IsScript":{ + "type":"bool", + "value":false + }, + "AYON_icon.png/Source":{ + "type":"string", + "value":"C:/Users/Maqina-05/Desktop/AYON_icon.png" + }, + "OnCreated/Cursor":{ + "type":"intarray", + "value":[5,29] + }, + "OnCreated/IsExpr":{ + "type":"bool", + "value":false + }, + "OnCreated/IsPython":{ + "type":"bool", + "value":true + }, + "OnCreated/IsScript":{ + "type":"bool", + "value":true + }, + "OnCreated/Source":{ + "type":"string", + "value":"" + }, + "OnDeleted/Cursor":{ + "type":"intarray", + "value":[1,15] + }, + "OnDeleted/IsExpr":{ + "type":"bool", + "value":false + }, + "OnDeleted/IsPython":{ + "type":"bool", + "value":true + }, + "OnDeleted/IsScript":{ + "type":"bool", + "value":true + }, + "OnDeleted/Source":{ + "type":"string", + "value":"" + }, + "OnLoaded/Cursor":{ + "type":"intarray", + "value":[9,76] + }, + "OnLoaded/IsExpr":{ + "type":"bool", + "value":false + }, + "OnLoaded/IsPython":{ + "type":"bool", + "value":true + }, + "OnLoaded/IsScript":{ + "type":"bool", + "value":true + }, + "OnLoaded/Source":{ + "type":"string", + "value":"" + }, + "OnNameChanged/Cursor":{ + "type":"intarray", + "value":[1,15] + }, + "OnNameChanged/IsExpr":{ + "type":"bool", + "value":false + }, + "OnNameChanged/IsPython":{ + "type":"bool", + "value":true + }, + "OnNameChanged/IsScript":{ + "type":"bool", + "value":true + }, + "OnNameChanged/Source":{ + "type":"string", + "value":"" + }, + "PythonModule/Cursor":{ + "type":"intarray", + "value":[10,1] + }, + "PythonModule/IsExpr":{ + "type":"bool", + "value":false + }, + "PythonModule/IsPython":{ + "type":"bool", + "value":true + }, + "PythonModule/IsScript":{ + "type":"bool", + "value":true + }, + "PythonModule/Source":{ + "type":"string", + "value":"" + } +} diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Help b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Help new file mode 100644 index 0000000000..e69de29bb2 diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/IconImage b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/IconImage new file mode 100644 index 0000000000000000000000000000000000000000..aa0d42021d18d060470b471f05f06031ac2a056d GIT binary patch literal 6939 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 nj9>flH|4A;bjv5p2ZMqB`y< + + + + + LOP + + + $HDA_TABLE_AND_NAME + + AYON + + + diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/TypePropertiesOptions b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/TypePropertiesOptions new file mode 100644 index 0000000000..a6d52acf2a --- /dev/null +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/TypePropertiesOptions @@ -0,0 +1,14 @@ +CheckExternal := 1; +ContentsCompressionType := 1; +ForbidOutsideParms := 1; +GzipContents := 1; +LockContents := 1; +MakeDefault := 1; +ParmsFromVfl := 0; +PrefixDroppedParmLabel := 0; +PrefixDroppedParmName := 0; +SaveCachedCode := 0; +SaveIcon := 1; +SaveSpareParms := 0; +UnlockOnCreate := 0; +UseDSParms := 1; From 8e5e7d50595b1440e19f00503cd31639696f9ead Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 7 Jun 2024 00:37:35 +0200 Subject: [PATCH 24/50] Fix tool submenu name to `AYON` Co-authored-by: Mustafa Taher --- .../ayon_8_8Lop_1lop__import_8_81.0/Tools.shelf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Tools.shelf b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Tools.shelf index 812c6c62fe..01802c33db 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Tools.shelf +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Tools.shelf @@ -11,7 +11,7 @@ a single file. --> $HDA_TABLE_AND_NAME - CB Pipeline + AYON From 73a9833db2ac9d3621362995812788ae5d5ec46f Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 10 Jun 2024 16:31:26 +0300 Subject: [PATCH 25/50] update doc strings --- .../houdini/client/ayon_houdini/api/hda_utils.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index f83b8add09..701a0a2bf3 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -429,7 +429,8 @@ def get_products_menu_items(node): It gets a list of available products of the specified product types within the specified folder path with in the specified project. - Users can specify those in the HDA parameters. + Args: + node (hou.OpNode): The HDA node. Returns: List[str]: Product options for Products menu. @@ -459,17 +460,18 @@ def get_products_menu_items(node): def select_folder_path(node): - """select folder path. - - When triggered it opens a dialog shows the available - folder paths within a given project. + """Show dialog to select folder path. - Users can specify that in the HDA parameters. + When triggered it opens a dialog that shows the available + folder paths within a given project. Note: This function should be refactored. It currently shows the available folder paths within the current project only. + + Args: + node (hou.OpNode): The HDA node. """ from ayon_core.tools.publisher.widgets.folders_dialog import FoldersDialog from ayon_core.tools.utils.host_tools import get_tool_by_name From c8f10a944c3761045a1d3a59bad631dd1cba0a46 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 10 Jun 2024 16:49:03 +0300 Subject: [PATCH 26/50] update the original hda instead of adding changes as new version --- .../otls/ayon_lop_import.hda/INDEX__SECTION | 16 +- .../otls/ayon_lop_import.hda/Sections.list | 1 - .../Contents.dir/Contents.mime | 16 +- .../DialogScript | 10 +- .../ExtraFileOptions | 6 +- .../MessageNodes | 2 +- .../ayon_8_8Lop_1lop__import_8_81.0/OnCreated | 2 +- .../ayon_8_8Lop_1lop__import_8_81.0/OnDeleted | 2 +- .../ayon_8_8Lop_1lop__import_8_81.0/OnLoaded | 1 - .../OnNameChanged | 2 +- .../PythonModule | 3 +- .../Tools.shelf | 3 +- .../AYON__icon.png | Bin 16907 -> 0 bytes .../Contents.dir/Contents.createtimes | 6 - .../Contents.dir/Contents.houdini_versions | 9 - .../Contents.dir/Contents.mime | 384 ------------------ .../Contents.dir/Contents.modtimes | 6 - .../Contents.dir/Sections.list | 2 - .../CreateScript | 15 - .../DialogScript | 330 --------------- .../ExtraFileOptions | 122 ------ .../ayon_8_8Lop_1lop__import_8_81.1/Help | 0 .../ayon_8_8Lop_1lop__import_8_81.1/IconImage | Bin 6939 -> 0 bytes .../InternalFileOptions | 10 - .../MessageNodes | 1 - .../ayon_8_8Lop_1lop__import_8_81.1/OnCreated | 5 - .../ayon_8_8Lop_1lop__import_8_81.1/OnDeleted | 6 - .../ayon_8_8Lop_1lop__import_8_81.1/OnLoaded | 14 - .../OnNameChanged | 8 - .../PythonModule | 9 - .../Sections.list | 17 - .../Tools.shelf | 18 - .../TypePropertiesOptions | 14 - 33 files changed, 27 insertions(+), 1013 deletions(-) delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/AYON__icon.png delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Contents.dir/Contents.createtimes delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Contents.dir/Contents.houdini_versions delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Contents.dir/Contents.mime delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Contents.dir/Contents.modtimes delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Contents.dir/Sections.list delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/CreateScript delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/DialogScript delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/ExtraFileOptions delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Help delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/IconImage delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/InternalFileOptions delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/MessageNodes delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/OnCreated delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/OnDeleted delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/OnLoaded delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/OnNameChanged delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/PythonModule delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Sections.list delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Tools.shelf delete mode 100644 server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/TypePropertiesOptions diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION index f558dfa687..5b5d5a1340 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/INDEX__SECTION @@ -10,18 +10,4 @@ Inputs: 0 to 1 Subnet: true Python: false Empty: false -Modified: Thu Jun 6 01:31:52 2024 - -Operator: ayon::lop_import::1.1 -Label: AYON Load Asset -Path: oplib:/ayon::Lop/lop_import::1.1?ayon::Lop/lop_import::1.1 -Icon: opdef:/ayon::Lop/lop_import::1.1?IconImage -Table: Lop -License: -Extra: -User: -Inputs: 0 to 1 -Subnet: true -Python: false -Empty: false -Modified: Thu Jun 6 03:33:00 2024 +Modified: Thu Jun 10 16:44:00 2024 diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/Sections.list b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/Sections.list index 074defe264..0a1bfe4e69 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/Sections.list +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/Sections.list @@ -2,4 +2,3 @@ INDEX__SECTION INDEX_SECTION houdini.hdalibrary houdini.hdalibrary ayon_8_8Lop_1lop__import_8_81.0 ayon::Lop/lop_import::1.0 -ayon_8_8Lop_1lop__import_8_81.1 ayon::Lop/lop_import::1.1 diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime index babfe0e1a9..dfd2c736a7 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime @@ -11,7 +11,7 @@ Lop Content-Disposition: attachment; filename="hdaroot.init" Content-Type: text/plain -type = ayon::lop_import::1.0 +type = ayon::lop_import::1.1 matchesdef = 0 --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY @@ -19,9 +19,9 @@ Content-Disposition: attachment; filename="hdaroot.def" Content-Type: text/plain comment "" -position -8.53722 4.22263 +position -1.67827 1.26636 connectornextid 0 -flags = lock off model off template off footprint off xray off bypass off display off render off highlight off unload off savedata off compress on colordefault on exposed on debug off +flags = lock off model off template off footprint off xray off bypass off display on render on highlight off unload off savedata off compress on colordefault on exposed on debug off outputsNamed3 { } @@ -35,10 +35,10 @@ stat { create -1 modify -1 - author User@HP-Z820-03 + author Mustafa_Taher@Major-Kalawy access 0777 } -color UT_Color RGB 0.8 0.8 0.8 +color UT_Color RGB 0.8 0.8 0.8 delscript "" exprlanguage hscript end @@ -98,7 +98,7 @@ stat author Maqina-05@Maqina-05 access 0777 } -color UT_Color RGB 0.8 0.8 0.8 +color UT_Color RGB 0.8 0.8 0.8 delscript "" exprlanguage hscript end @@ -158,7 +158,7 @@ stat author Maqina-05@Maqina-05 access 0777 } -color UT_Color RGB 0.8 0.8 0.8 +color UT_Color RGB 0.8 0.8 0.8 delscript "" exprlanguage hscript end @@ -324,7 +324,7 @@ stat author User@HP-Z820-03 access 0777 } -color UT_Color RGB 0.8 0.8 0.8 +color UT_Color RGB 0.8 0.8 0.8 delscript "" exprlanguage hscript end diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript index 6281baecb6..44ee560b91 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript @@ -1,7 +1,7 @@ -# Dialog script for ayon::lop_import::1.0 automatically generated +# Dialog script for ayon::lop_import::1.1 automatically generated { - name ayon::lop_import::1.0 + name ayon::lop_import::1.1 script load_asset::1.0 label "Load Asset" @@ -40,6 +40,8 @@ label "Folder Path" type string default { "$AYON_FOLDER_PATH" } + parmtag { "script_action" "from ayon_houdini.api.hda_utils import select_folder_path;select_folder_path(kwargs['node'])" } + parmtag { "script_action_icon" "BUTTONS_reselect" } parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } parmtag { "script_callback_language" "python" } } @@ -48,6 +50,10 @@ label "Product" type string default { "usdAsset" } + menureplace { + [ "hou.phm().get_products_menu_items(kwargs['node'])" ] + language python + } parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } parmtag { "script_callback_language" "python" } } diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/ExtraFileOptions b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/ExtraFileOptions index 38babad6a2..fb58b6889f 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/ExtraFileOptions +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/ExtraFileOptions @@ -41,7 +41,7 @@ }, "OnDeleted/Cursor":{ "type":"intarray", - "value":[2,1] + "value":[1,15] }, "OnDeleted/IsExpr":{ "type":"bool", @@ -81,7 +81,7 @@ }, "OnNameChanged/Cursor":{ "type":"intarray", - "value":[4,1] + "value":[1,15] }, "OnNameChanged/IsExpr":{ "type":"bool", @@ -101,7 +101,7 @@ }, "PythonModule/Cursor":{ "type":"intarray", - "value":[1,18] + "value":[10,1] }, "PythonModule/IsExpr":{ "type":"bool", diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/MessageNodes b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/MessageNodes index f3d2a13d61..ff389a716b 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/MessageNodes +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/MessageNodes @@ -1 +1 @@ -warn_no_representation_set reference \ No newline at end of file +warn_no_representation_set reference diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnCreated b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnCreated index cc1a8f6325..bd09a7838b 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnCreated +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnCreated @@ -2,4 +2,4 @@ node = kwargs["node"] hda_module = node.hdaModule() hda_module.setup_flag_changed_callback(node) -node.parm("file").lock(True) \ No newline at end of file +node.parm("file").lock(True) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnDeleted b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnDeleted index 613107ed2b..42e4ef2401 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnDeleted +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnDeleted @@ -3,4 +3,4 @@ from ayon_houdini.api.lib import remove_all_thumbnails # Clear thumbnails node = kwargs["node"] -remove_all_thumbnails(node) \ No newline at end of file +remove_all_thumbnails(node) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnLoaded b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnLoaded index 067c1964e1..42e3c6e640 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnLoaded +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnLoaded @@ -12,4 +12,3 @@ def on_duplicate(): if not hou.hipFile.isLoadingHipFile(): on_duplicate() - diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnNameChanged b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnNameChanged index af1fe7d119..2076f5ad9d 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnNameChanged +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnNameChanged @@ -5,4 +5,4 @@ from ayon_houdini.api.hda_utils import ( node = kwargs["node"] old_name = kwargs["old_name"] -keep_background_images_linked(node, old_name) \ No newline at end of file +keep_background_images_linked(node, old_name) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule index f1ee7df56f..5dfe9aba91 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule @@ -4,5 +4,6 @@ from ayon_houdini.api.hda_utils import ( on_representation_id_changed, on_representation_parms_changed, setup_flag_changed_callback, - get_available_versions + get_available_versions, + get_products_menu_items ) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Tools.shelf b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Tools.shelf index 812c6c62fe..0c76942883 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Tools.shelf +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Tools.shelf @@ -11,9 +11,8 @@ a single file. --> $HDA_TABLE_AND_NAME - CB Pipeline + AYON - \ No newline at end of file diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/AYON__icon.png b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/AYON__icon.png deleted file mode 100644 index ed13aeea527299092c400f18045b11b28c4d23ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16907 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 0, 0, -1)" } - parmtag { "sidefx::usdpathtype" "prim" } - } - parm { - name "timeoffset1" - label "Time Offset (in Frames)" - type float - default { "0" } - range { -100 100 } - parmtag { "autoscope" "0000000000000000" } - parmtag { "script_callback_language" "python" } - } - parm { - name "timescale1" - label "Time Scale" - type float - default { "1" } - range { 0 5 } - parmtag { "autoscope" "0000000000000000" } - parmtag { "script_callback_language" "python" } - } - } - - } - - groupcollapsible { - name "info_display2" - label "Info Display" - - parm { - name "show_thumbnail" - label "Show Entity Thumbnail" - type toggle - joinnext - default { "0" } - parmtag { "script_callback" "hou.phm().on_thumbnail_show_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } - } - parm { - name "thumbnail_size" - label "Size" - type float - joinnext - default { "2" } - hidewhen "{ show_thumbnail == 0 }" - range { 0 10 } - parmtag { "script_callback" "hou.phm().on_thumbnail_size_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } - } - parm { - name "thumbnail_cache_dir" - label "Thumbnail Cache Dir" - type directory - invisible - default { "$JOB/.houdini_loader_thumbnails" } - parmtag { "script_callback_language" "python" } - } - parm { - name "thumbnail_padding" - label "Padding" - type float - invisible - default { "1" } - range { 0 10 } - parmtag { "script_callback_language" "python" } - } - parm { - name "thumbnail_offset" - label "Offset" - type vector2 - size 2 - default { "0" "0.35" } - hidewhen "{ show_thumbnail == 0 }" - range { -1 1 } - parmtag { "script_callback" "hou.phm().on_thumbnail_size_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } - } - parm { - name "show_pipeline_parms" - label "Show Pipeline Parms" - type toggle - default { "0" } - parmtag { "script_callback" "hou.phm().on_thumbnail_show_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } - } - } - - group { - name "ayon_folder0" - label "Ayon" - hidewhen "{ show_pipeline_parms == 0 }" - - parm { - name "name" - label "Name" - type label - default { "$OS" } - } - parm { - name "namespace" - label "Namespace" - type label - default { "`opfullpath(\".\")`" } - } - parm { - name "loader" - label "Loader" - type label - default { "LOPLoadAssetLoader" } - } - parm { - name "id" - label "ID" - type label - default { "pyblish.avalon.container" } - } - parm { - name "representation" - label "Representation ID" - type string - default { "" } - parmtag { "script_callback" "hou.phm().on_representation_id_changed(kwargs['node'])" } - parmtag { "script_callback_language" "python" } - } - parm { - name "version_name" - label "Current Version Label" - type label - invisible - default { "" } - } - parm { - name "subset_name" - label "Subset (backwards compatibility)" - type label - invisible - default { "`chs(\"product_name\")`" } - } - } - -} diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/ExtraFileOptions b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/ExtraFileOptions deleted file mode 100644 index fb58b6889f..0000000000 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/ExtraFileOptions +++ /dev/null @@ -1,122 +0,0 @@ -{ - "AYON_icon.png/Cursor":{ - "type":"intarray", - "value":[0,0] - }, - "AYON_icon.png/IsExpr":{ - "type":"bool", - "value":false - }, - "AYON_icon.png/IsPython":{ - "type":"bool", - "value":false - }, - "AYON_icon.png/IsScript":{ - "type":"bool", - "value":false - }, - "AYON_icon.png/Source":{ - "type":"string", - "value":"C:/Users/Maqina-05/Desktop/AYON_icon.png" - }, - "OnCreated/Cursor":{ - "type":"intarray", - "value":[5,29] - }, - "OnCreated/IsExpr":{ - "type":"bool", - "value":false - }, - "OnCreated/IsPython":{ - "type":"bool", - "value":true - }, - "OnCreated/IsScript":{ - "type":"bool", - "value":true - }, - "OnCreated/Source":{ - "type":"string", - "value":"" - }, - "OnDeleted/Cursor":{ - "type":"intarray", - "value":[1,15] - }, - "OnDeleted/IsExpr":{ - "type":"bool", - "value":false - }, - "OnDeleted/IsPython":{ - "type":"bool", - "value":true - }, - "OnDeleted/IsScript":{ - "type":"bool", - "value":true - }, - "OnDeleted/Source":{ - "type":"string", - "value":"" - }, - "OnLoaded/Cursor":{ - "type":"intarray", - "value":[9,76] - }, - "OnLoaded/IsExpr":{ - "type":"bool", - "value":false - }, - "OnLoaded/IsPython":{ - "type":"bool", - "value":true - }, - "OnLoaded/IsScript":{ - "type":"bool", - "value":true - }, - "OnLoaded/Source":{ - "type":"string", - "value":"" - }, - "OnNameChanged/Cursor":{ - "type":"intarray", - "value":[1,15] - }, - "OnNameChanged/IsExpr":{ - "type":"bool", - "value":false - }, - "OnNameChanged/IsPython":{ - "type":"bool", - "value":true - }, - "OnNameChanged/IsScript":{ - "type":"bool", - "value":true - }, - "OnNameChanged/Source":{ - "type":"string", - "value":"" - }, - "PythonModule/Cursor":{ - "type":"intarray", - "value":[10,1] - }, - "PythonModule/IsExpr":{ - "type":"bool", - "value":false - }, - "PythonModule/IsPython":{ - "type":"bool", - "value":true - }, - "PythonModule/IsScript":{ - "type":"bool", - "value":true - }, - "PythonModule/Source":{ - "type":"string", - "value":"" - } -} diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Help b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/Help deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/IconImage b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/IconImage deleted file mode 100644 index aa0d42021d18d060470b471f05f06031ac2a056d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6939 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 nj9>flH|4A;bjv5p2ZMqB`y< - - - - - LOP - - - $HDA_TABLE_AND_NAME - - AYON - - - diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/TypePropertiesOptions b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/TypePropertiesOptions deleted file mode 100644 index a6d52acf2a..0000000000 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.1/TypePropertiesOptions +++ /dev/null @@ -1,14 +0,0 @@ -CheckExternal := 1; -ContentsCompressionType := 1; -ForbidOutsideParms := 1; -GzipContents := 1; -LockContents := 1; -MakeDefault := 1; -ParmsFromVfl := 0; -PrefixDroppedParmLabel := 0; -PrefixDroppedParmName := 0; -SaveCachedCode := 0; -SaveIcon := 1; -SaveSpareParms := 0; -UnlockOnCreate := 0; -UseDSParms := 1; From 56c02d58a38afbb7c6fb263362c3554621abbffe Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 10 Jun 2024 18:59:00 +0300 Subject: [PATCH 27/50] remove products filter --- .../client/ayon_houdini/api/hda_utils.py | 36 ------------------- .../DialogScript | 4 --- .../PythonModule | 3 +- 3 files changed, 1 insertion(+), 42 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index 701a0a2bf3..6e40e794a9 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -423,42 +423,6 @@ def keep_background_images_linked(node, old_name): set_background_images(parent, images) -def get_products_menu_items(node): - """Return products menu items - - It gets a list of available products of the specified product types - within the specified folder path with in the specified project. - - Args: - node (hou.OpNode): The HDA node. - - Returns: - List[str]: Product options for Products menu. - """ - project_name = node.evalParm("project_name") - folder_path = node.evalParm("folder_path") - representation_name = node.evalParm("representation_name") - - folder_entity = ayon_api.get_folder_by_path(project_name, - folder_path, - fields={"id"}) - if not folder_entity: - return [] - - products = ayon_api.get_products( - project_name, - folder_ids=[folder_entity["id"]], - product_types=[representation_name] - ) - - items = [] - for product in products: - items.append(product["name"]) - items.append(product["name"]) - - return(items) - - def select_folder_path(node): """Show dialog to select folder path. diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript index 44ee560b91..374666f4d8 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript @@ -50,10 +50,6 @@ label "Product" type string default { "usdAsset" } - menureplace { - [ "hou.phm().get_products_menu_items(kwargs['node'])" ] - language python - } parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } parmtag { "script_callback_language" "python" } } diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule index 5dfe9aba91..f1ee7df56f 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule @@ -4,6 +4,5 @@ from ayon_houdini.api.hda_utils import ( on_representation_id_changed, on_representation_parms_changed, setup_flag_changed_callback, - get_available_versions, - get_products_menu_items + get_available_versions ) From 5bab335f212804a90081591c13eea7cec5cfe6da Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Mon, 10 Jun 2024 19:08:50 +0300 Subject: [PATCH 28/50] fix hda version --- .../Contents.dir/Contents.mime | 2 +- .../ayon_8_8Lop_1lop__import_8_81.0/DialogScript | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime index dfd2c736a7..ec12230a75 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/Contents.dir/Contents.mime @@ -11,7 +11,7 @@ Lop Content-Disposition: attachment; filename="hdaroot.init" Content-Type: text/plain -type = ayon::lop_import::1.1 +type = ayon::lop_import::1.0 matchesdef = 0 --HOUDINIMIMEBOUNDARY0xD3ADD339-0x00000F49-0x56B122C9-0x00000001HOUDINIMIMEBOUNDARY diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript index 374666f4d8..097e6c348a 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript @@ -1,7 +1,7 @@ -# Dialog script for ayon::lop_import::1.1 automatically generated +# Dialog script for ayon::lop_import::1.0 automatically generated { - name ayon::lop_import::1.1 + name ayon::lop_import::1.0 script load_asset::1.0 label "Load Asset" From 8581edde688b8543ce788ef60a5f2c75aab452c8 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 10 Jun 2024 19:37:11 +0200 Subject: [PATCH 29/50] Bump ayon houdini addon version --- server_addon/houdini/client/ayon_houdini/version.py | 2 +- server_addon/houdini/package.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/version.py b/server_addon/houdini/client/ayon_houdini/version.py index 87d445d563..10d1478249 100644 --- a/server_addon/houdini/client/ayon_houdini/version.py +++ b/server_addon/houdini/client/ayon_houdini/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring AYON addon 'houdini' version.""" -__version__ = "0.3.1" +__version__ = "0.3.2" diff --git a/server_addon/houdini/package.py b/server_addon/houdini/package.py index a8884ff60a..1f7879483e 100644 --- a/server_addon/houdini/package.py +++ b/server_addon/houdini/package.py @@ -1,6 +1,6 @@ name = "houdini" title = "Houdini" -version = "0.3.1" +version = "0.3.2" client_dir = "ayon_houdini" From b15f454fe3d6aa93b188e681a5043c1238287dbd Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 10 Jun 2024 19:38:50 +0200 Subject: [PATCH 30/50] Fix line lengths + style --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index 6e40e794a9..350a2ef01f 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -441,11 +441,12 @@ def select_folder_path(node): from ayon_core.tools.utils.host_tools import get_tool_by_name main_window = lib.get_main_window() - publisher_window = get_tool_by_name( tool_name="publisher", parent=main_window) + publisher_window = get_tool_by_name(tool_name="publisher", + parent=main_window) # TODO: A dedicated Dialog should be implement using `SimpleFoldersWidget`. - # we should avoid using `FoldersDialog` because It's highly recommend to - # never use inner widgets of any tool... + # we should avoid using `FoldersDialog` because It's highly + # recommended to never use inner widgets of any tool. # Note: The following dialog doesn't support changing `the project_name` # But, having a semi-functional dialog is better than nothing. dialog = FoldersDialog(publisher_window.controller, main_window) From f2381042151a1f773f70494fd96936faf810e3c9 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 10 Jun 2024 19:39:35 +0200 Subject: [PATCH 31/50] Fix logic --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index 350a2ef01f..ce703b1839 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -454,8 +454,11 @@ def select_folder_path(node): selected_folder_path = dialog.get_selected_folder_path() - if not selected_folder_path or \ - selected_folder_path == get_current_folder_path(): + if not selected_folder_path: + # Do nothing if user picked nothing + return + + if selected_folder_path == get_current_folder_path(): selected_folder_path = '$AYON_FOLDER_PATH' node.parm("folder_path").set(selected_folder_path) From e0334bc3211f3dae7d2e80ce4c9602e2f57e2955 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 10 Jun 2024 20:17:20 +0200 Subject: [PATCH 32/50] Use `SimpleFoldersWidget` --- .../client/ayon_houdini/api/hda_utils.py | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index ce703b1839..cf0efa425a 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -22,9 +22,12 @@ get_current_project_name, get_current_folder_path ) +from ayon_core.tools.utils import SimpleFoldersWidget +from ayon_core.style import load_stylesheet from ayon_houdini.api import lib +from qtpy import QtWidgets import hou @@ -437,19 +440,47 @@ def select_folder_path(node): Args: node (hou.OpNode): The HDA node. """ - from ayon_core.tools.publisher.widgets.folders_dialog import FoldersDialog - from ayon_core.tools.utils.host_tools import get_tool_by_name - main_window = lib.get_main_window() - publisher_window = get_tool_by_name(tool_name="publisher", - parent=main_window) - # TODO: A dedicated Dialog should be implement using `SimpleFoldersWidget`. - # we should avoid using `FoldersDialog` because It's highly - # recommended to never use inner widgets of any tool. + project_name = node.evalParm("project_name") + folder_path = node.evalParm("folder_path") + + class PickDialog(QtWidgets.QDialog): + def __init__(self, parent=None): + super(PickDialog, self).__init__(parent) + # TODO: Add pick project field + self.setWindowTitle("Select folder..") + + filter_widget = QtWidgets.QLineEdit() + filter_widget.setPlaceholderText("Filter folders..") + folder_widget = SimpleFoldersWidget(parent=self) + accept_button = QtWidgets.QPushButton("Accept") + + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(filter_widget) + layout.addWidget(folder_widget) + layout.addWidget(accept_button) + + filter_widget.textChanged.connect(folder_widget.set_name_filter) + + folder_widget.double_clicked.connect(self.on_confirm) + accept_button.clicked.connect(self.on_confirm) + + self.folder_widget = folder_widget + + def get_selected_folder_path(self): + return self.folder_widget.get_selected_folder_path() + + def on_confirm(self): + self.close() + # Note: The following dialog doesn't support changing `the project_name` # But, having a semi-functional dialog is better than nothing. - dialog = FoldersDialog(publisher_window.controller, main_window) + dialog = PickDialog(parent=main_window) + dialog.folder_widget.set_project_name(project_name) + if folder_path: + dialog.folder_widget.set_selected_folder_path(folder_path) + dialog.setStyleSheet(load_stylesheet()) dialog.exec_() selected_folder_path = dialog.get_selected_folder_path() From d64c5ada010bf88e55857b8055990b882ae0938b Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 10 Jun 2024 20:18:00 +0200 Subject: [PATCH 33/50] Add todo --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index cf0efa425a..c5f607fbdd 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -479,6 +479,9 @@ def on_confirm(self): dialog = PickDialog(parent=main_window) dialog.folder_widget.set_project_name(project_name) if folder_path: + # TODO: This does not work because project is refreshed in a thread + # and thus the setting of folder path occurs before the project + # refresh dialog.folder_widget.set_selected_folder_path(folder_path) dialog.setStyleSheet(load_stylesheet()) dialog.exec_() From 31f55fb741cf7c5f507fb17ae80c922c37d5433c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 11 Jun 2024 00:01:53 +0200 Subject: [PATCH 34/50] Update server_addon/houdini/client/ayon_houdini/api/hda_utils.py Co-authored-by: Mustafa Taher --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index c5f607fbdd..23c38543dd 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -474,8 +474,6 @@ def get_selected_folder_path(self): def on_confirm(self): self.close() - # Note: The following dialog doesn't support changing `the project_name` - # But, having a semi-functional dialog is better than nothing. dialog = PickDialog(parent=main_window) dialog.folder_widget.set_project_name(project_name) if folder_path: From d332dd204c07585711a6c1e946589ea153ea60e1 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 11 Jun 2024 00:19:17 +0200 Subject: [PATCH 35/50] Only set folder path if user accepted the dialog --- .../houdini/client/ayon_houdini/api/hda_utils.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index c5f607fbdd..c54156ef3e 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -463,17 +463,14 @@ def __init__(self, parent=None): filter_widget.textChanged.connect(folder_widget.set_name_filter) - folder_widget.double_clicked.connect(self.on_confirm) - accept_button.clicked.connect(self.on_confirm) + folder_widget.double_clicked.connect(self.accept) + accept_button.clicked.connect(self.accept) self.folder_widget = folder_widget def get_selected_folder_path(self): return self.folder_widget.get_selected_folder_path() - def on_confirm(self): - self.close() - # Note: The following dialog doesn't support changing `the project_name` # But, having a semi-functional dialog is better than nothing. dialog = PickDialog(parent=main_window) @@ -484,12 +481,14 @@ def on_confirm(self): # refresh dialog.folder_widget.set_selected_folder_path(folder_path) dialog.setStyleSheet(load_stylesheet()) - dialog.exec_() - selected_folder_path = dialog.get_selected_folder_path() + result = dialog.exec_() + if result != QtWidgets.QDialog.Accepted: + return + selected_folder_path = dialog.get_selected_folder_path() if not selected_folder_path: - # Do nothing if user picked nothing + # Do nothing if user accepted with nothing selected return if selected_folder_path == get_current_folder_path(): From 00ccc875d373dbb5f8e8d9260d9ec8e87e928aed Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 11 Jun 2024 00:21:09 +0200 Subject: [PATCH 36/50] Remove todo --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index 23e156ad6a..2484936854 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -448,7 +448,6 @@ def select_folder_path(node): class PickDialog(QtWidgets.QDialog): def __init__(self, parent=None): super(PickDialog, self).__init__(parent) - # TODO: Add pick project field self.setWindowTitle("Select folder..") filter_widget = QtWidgets.QLineEdit() From 7f3194f70fdd75b7bee225fd863bcccc206f8285 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 27 Jun 2024 15:56:02 +0200 Subject: [PATCH 37/50] Implement Pick Project and Folder Path dialog --- .../client/ayon_houdini/api/hda_utils.py | 120 +++++++++++++----- 1 file changed, 87 insertions(+), 33 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index 2484936854..766c6947c6 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -3,6 +3,7 @@ import os import contextlib import uuid +from typing import List import ayon_api from ayon_api import ( @@ -27,7 +28,7 @@ from ayon_houdini.api import lib -from qtpy import QtWidgets +from qtpy import QtCore, QtWidgets import hou @@ -426,6 +427,68 @@ def keep_background_images_linked(node, old_name): set_background_images(parent, images) +class PickAssetDialog(QtWidgets.QDialog): + """Simple dialog to allow a user to select project and asset.""" + + def __init__(self, parent=None): + super(PickAssetDialog, self).__init__(parent) + self.setWindowTitle("Select project and folder path..") + self.setStyleSheet(load_stylesheet()) + + project_widget = QtWidgets.QComboBox() + project_widget.addItems(self.get_projects()) + + filter_widget = QtWidgets.QLineEdit() + filter_widget.setPlaceholderText("Filter folders..") + + folder_widget = SimpleFoldersWidget(parent=self) + + accept_button = QtWidgets.QPushButton("Accept") + + main_layout = QtWidgets.QVBoxLayout(self) + main_layout.addWidget(project_widget, 0) + main_layout.addWidget(filter_widget, 0) + main_layout.addWidget(folder_widget, 1) + main_layout.addWidget(accept_button, 0) + + self.project_widget = project_widget + self.folder_widget = folder_widget + + project_widget.currentTextChanged.connect(self.on_project_changed) + filter_widget.textChanged.connect(folder_widget.set_name_filter) + folder_widget.double_clicked.connect(self.accept) + accept_button.clicked.connect(self.accept) + + # Default refreshed to current project + project_name = get_current_project_name() + self.set_project_name(project_name) + + def get_selected_folder_path(self): + return self.folder_widget.get_selected_folder_path() + + def get_selected_project_name(self): + return self.project_widget.currentText() + + def get_projects(self) -> List[str]: + projects = ayon_api.get_projects(fields=["name"]) + return [p["name"] for p in projects] + + def on_project_changed(self, project_name: str): + self.folder_widget.set_project_name(project_name) + + def set_project_name(self, project_name: str): + self.project_widget.setCurrentText(project_name) + + if self.project_widget.currentText() != project_name: + # Project does not exist + return + + # Force the set of widget because even though a callback exist on the + # project widget it may have been initialized to that value and hence + # detect no change. + self.folder_widget.set_project_name(project_name) + + def select_folder_path(node): """Show dialog to select folder path. @@ -445,44 +508,33 @@ def select_folder_path(node): project_name = node.evalParm("project_name") folder_path = node.evalParm("folder_path") - class PickDialog(QtWidgets.QDialog): - def __init__(self, parent=None): - super(PickDialog, self).__init__(parent) - self.setWindowTitle("Select folder..") - - filter_widget = QtWidgets.QLineEdit() - filter_widget.setPlaceholderText("Filter folders..") - folder_widget = SimpleFoldersWidget(parent=self) - accept_button = QtWidgets.QPushButton("Accept") - - layout = QtWidgets.QVBoxLayout(self) - layout.addWidget(filter_widget) - layout.addWidget(folder_widget) - layout.addWidget(accept_button) - - filter_widget.textChanged.connect(folder_widget.set_name_filter) - - folder_widget.double_clicked.connect(self.accept) - accept_button.clicked.connect(self.accept) - - self.folder_widget = folder_widget - - def get_selected_folder_path(self): - return self.folder_widget.get_selected_folder_path() - - dialog = PickDialog(parent=main_window) - dialog.folder_widget.set_project_name(project_name) + dialog = PickAssetDialog(parent=main_window) + dialog.set_project_name(project_name) if folder_path: - # TODO: This does not work because project is refreshed in a thread - # and thus the setting of folder path occurs before the project - # refresh - dialog.folder_widget.set_selected_folder_path(folder_path) + # We add a small delay to the setting of the selected folder + # because the folder widget's set project logic itself also runs + # with a bit of a delay, and unfortunately otherwise the project + # has not been selected yet and thus selection does not work. + def _select_folder_path(): + dialog.folder_widget.set_selected_folder_path(folder_path) + QtCore.QTimer.singleShot(100, _select_folder_path) + dialog.setStyleSheet(load_stylesheet()) result = dialog.exec_() if result != QtWidgets.QDialog.Accepted: return + # Set project + selected_project_name = dialog.get_selected_project_name() + if selected_project_name == get_current_project_name(): + selected_project_name = '$AYON_PROJECT_NAME' + + project_parm = node.parm("project_name") + project_parm.set(selected_project_name) + project_parm.pressButton() # allow any callbacks to trigger + + # Set folder path selected_folder_path = dialog.get_selected_folder_path() if not selected_folder_path: # Do nothing if user accepted with nothing selected @@ -491,4 +543,6 @@ def get_selected_folder_path(self): if selected_folder_path == get_current_folder_path(): selected_folder_path = '$AYON_FOLDER_PATH' - node.parm("folder_path").set(selected_folder_path) + folder_parm = node.parm("folder_path") + folder_parm.set(selected_folder_path) + folder_parm.pressButton() # allow any callbacks to trigger From e69c0754bf425433091c75fdfd33d3277f379e20 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 27 Jun 2024 15:57:58 +0200 Subject: [PATCH 38/50] Cosmetics + do not default to setting current project --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index 766c6947c6..0efe0434bc 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -459,14 +459,10 @@ def __init__(self, parent=None): folder_widget.double_clicked.connect(self.accept) accept_button.clicked.connect(self.accept) - # Default refreshed to current project - project_name = get_current_project_name() - self.set_project_name(project_name) - - def get_selected_folder_path(self): + def get_selected_folder_path(self) -> str: return self.folder_widget.get_selected_folder_path() - def get_selected_project_name(self): + def get_selected_project_name(self) -> str: return self.project_widget.currentText() def get_projects(self) -> List[str]: From 791707b5483294dc2663fe20f4acf226f837951a Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Thu, 27 Jun 2024 22:32:18 +0300 Subject: [PATCH 39/50] add products drop down menu --- .../client/ayon_houdini/api/hda_utils.py | 40 +++++++++++++++++++ .../DialogScript | 19 ++++++++- .../ayon_8_8Lop_1lop__import_8_81.0/OnCreated | 1 + .../PythonModule | 4 +- 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index 0efe0434bc..be3869fbf3 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -542,3 +542,43 @@ def _select_folder_path(): folder_parm = node.parm("folder_path") folder_parm.set(selected_folder_path) folder_parm.pressButton() # allow any callbacks to trigger + + +def get_available_products(node): + """Return products menu items + It gets a list of available products of the specified product types + within the specified folder path with in the specified project. + Users can specify those in the HDA parameters. + Returns: + List[str]: Product options for Products menu. + """ + project_name = node.evalParm("project_name") + folder_path = node.evalParm("folder_path") + product_type = node.evalParm("product_type") + + folder_entity = ayon_api.get_folder_by_path(project_name, + folder_path, + fields={"id"}) + if not folder_entity: + return [] + + products = ayon_api.get_products( + project_name, + folder_ids=[folder_entity["id"]], + product_types=[product_type] + ) + + return([ + product["name"] for product in products + ]) + + +def refresh_version(node): + """Callback on product name change + + Refresh version parameter value by setting its value to + the latest version of the selected product. + """ + + versions = get_available_versions(node) + node.parm("version").set(str(versions[0])) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript index 097e6c348a..6128b216d7 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript @@ -45,12 +45,29 @@ parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } parmtag { "script_callback_language" "python" } } + parm { + name "product_type" + label "Product Type" + type string + default { "usd" } + } parm { name "product_name" label "Product" type string default { "usdAsset" } - parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } + menureplace { + [ "products = hou.phm().get_available_products(kwargs['node'])" ] + [ "" ] + [ "result = []" ] + [ "for product in products:" ] + [ " result.append(product)" ] + [ " result.append(product)" ] + [ " " ] + [ "return result" ] + language python + } + parmtag { "script_callback" "hou.phm().refresh_version(kwargs['node'])\nhou.phm().on_representation_parms_changed(kwargs['node'])" } parmtag { "script_callback_language" "python" } } parm { diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnCreated b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnCreated index bd09a7838b..06ccdaa653 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnCreated +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/OnCreated @@ -2,4 +2,5 @@ node = kwargs["node"] hda_module = node.hdaModule() hda_module.setup_flag_changed_callback(node) +node.parm("product_type").lock(True) node.parm("file").lock(True) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule index f1ee7df56f..4b83cf008e 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule @@ -4,5 +4,7 @@ from ayon_houdini.api.hda_utils import ( on_representation_id_changed, on_representation_parms_changed, setup_flag_changed_callback, - get_available_versions + get_available_versions, + get_available_products, + refresh_version ) From f7560641841a29f2e191cc219ebf07e7803e6374 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 27 Jun 2024 22:17:20 +0200 Subject: [PATCH 40/50] Update server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript Co-authored-by: Mustafa Taher --- .../ayon_8_8Lop_1lop__import_8_81.0/DialogScript | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript index 097e6c348a..924a8a91e9 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript @@ -32,6 +32,8 @@ label "Project" type string default { "$AYON_PROJECT_NAME" } + parmtag { "script_action" "from ayon_houdini.api.hda_utils import select_folder_path;select_folder_path(kwargs['node'])" } + parmtag { "script_action_icon" "BUTTONS_reselect" } parmtag { "script_callback" "hou.phm().on_representation_parms_changed(kwargs['node'])" } parmtag { "script_callback_language" "python" } } From eb24c3618040ad1e3501c172951a38a721b6c617 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jun 2024 00:53:42 +0200 Subject: [PATCH 41/50] Cosmetics --- .../houdini/client/ayon_houdini/api/hda_utils.py | 13 ++++++------- .../ayon_8_8Lop_1lop__import_8_81.0/DialogScript | 2 +- .../ayon_8_8Lop_1lop__import_8_81.0/PythonModule | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index be3869fbf3..e6c849c07a 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -557,8 +557,8 @@ def get_available_products(node): product_type = node.evalParm("product_type") folder_entity = ayon_api.get_folder_by_path(project_name, - folder_path, - fields={"id"}) + folder_path, + fields={"id"}) if not folder_entity: return [] @@ -568,12 +568,10 @@ def get_available_products(node): product_types=[product_type] ) - return([ - product["name"] for product in products - ]) + return [product["name"] for product in products] -def refresh_version(node): +def set_to_latest_version(node): """Callback on product name change Refresh version parameter value by setting its value to @@ -581,4 +579,5 @@ def refresh_version(node): """ versions = get_available_versions(node) - node.parm("version").set(str(versions[0])) + if versions: + node.parm("version").set(str(versions[0])) diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript index 7254da6913..3c97d10f35 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/DialogScript @@ -69,7 +69,7 @@ [ "return result" ] language python } - parmtag { "script_callback" "hou.phm().refresh_version(kwargs['node'])\nhou.phm().on_representation_parms_changed(kwargs['node'])" } + parmtag { "script_callback" "hou.phm().set_to_latest_version(kwargs['node'])\nhou.phm().on_representation_parms_changed(kwargs['node'])" } parmtag { "script_callback_language" "python" } } parm { diff --git a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule index 4b83cf008e..934fb2f612 100644 --- a/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule +++ b/server_addon/houdini/client/ayon_houdini/startup/otls/ayon_lop_import.hda/ayon_8_8Lop_1lop__import_8_81.0/PythonModule @@ -6,5 +6,5 @@ from ayon_houdini.api.hda_utils import ( setup_flag_changed_callback, get_available_versions, get_available_products, - refresh_version + set_to_latest_version ) From 4a53f46d3e5b5a52a14f341f173fb7c1cf27d527 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jun 2024 00:57:02 +0200 Subject: [PATCH 42/50] Add note about the sorting --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index e6c849c07a..d0590e9bfa 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -54,6 +54,9 @@ def _unlocked_parm(parm): def get_available_versions(node): """Return the versions list for node. + The versions are sorted with the latest version first and oldest lower + version last. + Args: node (hou.Node): Node to query selected products' versions for. From 44289ce067c79834f8f7185ad18c110538933d83 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jun 2024 00:59:33 +0200 Subject: [PATCH 43/50] Cosmetics --- .../houdini/client/ayon_houdini/api/hda_utils.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index d0590e9bfa..cc36fb51d1 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -61,7 +61,7 @@ def get_available_versions(node): node (hou.Node): Node to query selected products' versions for. Returns: - List[int]: Version numbers for the product + list[int]: Version numbers for the product """ project_name = node.evalParm("project_name") or get_current_project_name() @@ -552,8 +552,12 @@ def get_available_products(node): It gets a list of available products of the specified product types within the specified folder path with in the specified project. Users can specify those in the HDA parameters. + + Args: + node (hou.OpNode): The HDA node. + Returns: - List[str]: Product options for Products menu. + list[str]: Product names for Products menu. """ project_name = node.evalParm("project_name") folder_path = node.evalParm("folder_path") @@ -579,6 +583,9 @@ def set_to_latest_version(node): Refresh version parameter value by setting its value to the latest version of the selected product. + + Args: + node (hou.OpNode): The HDA node. """ versions = get_available_versions(node) From 5e009dbdf0576cf2a9689f8ab5e3e47f815272ab Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jun 2024 01:21:51 +0200 Subject: [PATCH 44/50] Remove unused select folder logic --- .../houdini/client/ayon_houdini/api/usd.py | 107 ------------------ 1 file changed, 107 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/usd.py b/server_addon/houdini/client/ayon_houdini/api/usd.py index ed33fbf590..ec5f86d4b2 100644 --- a/server_addon/houdini/client/ayon_houdini/api/usd.py +++ b/server_addon/houdini/client/ayon_houdini/api/usd.py @@ -20,113 +20,6 @@ log = logging.getLogger(__name__) -class SelectFolderDialog(QtWidgets.QWidget): - """Frameless folders dialog to select folder with double click. - - Args: - parm: Parameter where selected folder path is set. - """ - - def __init__(self, parm): - self.setWindowTitle("Pick Folder") - self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Popup) - - header_widget = QtWidgets.QWidget(self) - - filter_input = PlaceholderLineEdit(header_widget) - filter_input.setPlaceholderText("Filter folders..") - - refresh_btn = RefreshButton(self) - - header_layout = QtWidgets.QHBoxLayout(header_widget) - header_layout.setContentsMargins(0, 0, 0, 0) - header_layout.addWidget(filter_input) - header_layout.addWidget(refresh_btn) - - for widget in ( - refresh_btn, - filter_input, - ): - size_policy = widget.sizePolicy() - size_policy.setVerticalPolicy( - QtWidgets.QSizePolicy.MinimumExpanding) - widget.setSizePolicy(size_policy) - - folders_widget = SimpleFoldersWidget(self) - folders_widget.set_project_name(get_current_project_name()) - - layout = QtWidgets.QHBoxLayout(self) - layout.addWidget(header_widget, 0) - layout.addWidget(folders_widget, 1) - - folders_widget.double_clicked.connect(self._set_parameter) - filter_input.textChanged.connect(self._on_filter_change) - refresh_btn.clicked.connect(self._on_refresh_clicked) - - self._folders_widget = folders_widget - self._parm = parm - - def _on_refresh_clicked(self): - self._folders_widget.refresh() - - def _on_filter_change(self, text): - self._folders_widget.set_name_filter(text) - - def _set_parameter(self): - folder_path = self._folders_widget.get_selected_folder_path() - self._parm.set(folder_path) - self.close() - - def _on_show(self): - pos = QtGui.QCursor.pos() - # Select the current folder if there is any - select_id = None - folder_path = self._parm.eval() - if folder_path: - project_name = get_current_project_name() - folder_entity = ayon_api.get_folder_by_path( - project_name, folder_path, fields={"id"} - ) - if folder_entity: - select_id = folder_entity["id"] - - # Set stylesheet - self.setStyleSheet(style.load_stylesheet()) - # Refresh folders (is threaded) - self._folders_widget.refresh() - # Select folder - must be done after refresh - if select_id is not None: - self._folders_widget.set_selected_folder(select_id) - - # Show cursor (top right of window) near cursor - self.resize(250, 400) - self.move(self.mapFromGlobal(pos) - QtCore.QPoint(self.width(), 0)) - - def showEvent(self, event): - super(SelectFolderDialog, self).showEvent(event) - self._on_show() - - -def pick_folder(node): - """Show a user interface to select an Folder in the project - - When double clicking an folder it will set the Folder value in the - 'folderPath' parameter. - - """ - - parm = node.parm("folderPath") - if not parm: - log.error("Node has no 'folderPath' parameter: %s", node) - return - - # Construct a frameless popup so it automatically - # closes when clicked outside of it. - global tool - tool = SelectFolderDialog(parm) - tool.show() - - def add_usd_output_processor(ropnode, processor): """Add USD Output Processor to USD Rop node. From d902593a0167ccc3c20b9b2151384a0316939b07 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jun 2024 01:22:52 +0200 Subject: [PATCH 45/50] Remove unused imports --- server_addon/houdini/client/ayon_houdini/api/usd.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/usd.py b/server_addon/houdini/client/ayon_houdini/api/usd.py index ec5f86d4b2..f7824dfc5c 100644 --- a/server_addon/houdini/client/ayon_houdini/api/usd.py +++ b/server_addon/houdini/client/ayon_houdini/api/usd.py @@ -3,17 +3,6 @@ import contextlib import logging -import ayon_api -from qtpy import QtWidgets, QtCore, QtGui - -from ayon_core import style -from ayon_core.pipeline import get_current_project_name -from ayon_core.tools.utils import ( - PlaceholderLineEdit, - RefreshButton, - SimpleFoldersWidget, -) - from pxr import Sdf From 5c4b466b0f9c65cc9a66968b9d10d9c4bb2495d7 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jun 2024 01:26:07 +0200 Subject: [PATCH 46/50] Typing --- .../houdini/client/ayon_houdini/api/hda_utils.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index cc36fb51d1..9a1ec946d3 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -135,7 +135,7 @@ def update_info(node, context): node.setParms(parms) -def _get_thumbnail(project_name, version_id, thumbnail_dir): +def _get_thumbnail(project_name: str, version_id: str, thumbnail_dir: str): folder = hou.text.expandString(thumbnail_dir) path = os.path.join(folder, "{}_thumbnail.jpg".format(version_id)) expanded_path = hou.text.expandString(path) @@ -154,9 +154,9 @@ def _get_thumbnail(project_name, version_id, thumbnail_dir): return path -def set_representation(node, repre_id): +def set_representation(node, representation_id: str): file_parm = node.parm("file") - if not repre_id: + if not representation_id: # Clear filepath and thumbnail with _unlocked_parm(file_parm): file_parm.set("") @@ -170,10 +170,10 @@ def set_representation(node, repre_id): # Ignore invalid representation ids silently # TODO remove - added for backwards compatibility with OpenPype scenes - if not is_valid_uuid(repre_id): + if not is_valid_uuid(representation_id): return - repre_entity = get_representation_by_id(project_name, repre_id) + repre_entity = get_representation_by_id(project_name, representation_id) if not repre_entity: return @@ -198,7 +198,7 @@ def set_representation(node, repre_id): set_node_thumbnail(node, thumbnail_path) -def set_node_thumbnail(node, thumbnail): +def set_node_thumbnail(node, thumbnail: str): """Update node thumbnail to thumbnail""" if thumbnail is None: lib.set_node_thumbnail(node, None) From 159ee22a95db45055bd1b8ab4dcf0bc30ef781fa Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jun 2024 13:16:58 +0200 Subject: [PATCH 47/50] Update server_addon/houdini/client/ayon_houdini/api/pipeline.py Co-authored-by: Mustafa Taher --- server_addon/houdini/client/ayon_houdini/api/pipeline.py | 1 - 1 file changed, 1 deletion(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/pipeline.py b/server_addon/houdini/client/ayon_houdini/api/pipeline.py index 5ba8f21721..c6fbbd5b62 100644 --- a/server_addon/houdini/client/ayon_houdini/api/pipeline.py +++ b/server_addon/houdini/client/ayon_houdini/api/pipeline.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- """Pipeline tools for OpenPype Houdini integration.""" import os -import six import json import logging From 926a32ae065b8f113e43e61dbd2c287bb6d2e748 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jun 2024 14:05:14 +0200 Subject: [PATCH 48/50] Refactor class to match more with the function name + `asset` is OpenPype lingo, `folderPath` is where all the cool kids are at. --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index 9a1ec946d3..e7997f0e79 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -430,11 +430,11 @@ def keep_background_images_linked(node, old_name): set_background_images(parent, images) -class PickAssetDialog(QtWidgets.QDialog): +class SelectFolderPathDialog(QtWidgets.QDialog): """Simple dialog to allow a user to select project and asset.""" def __init__(self, parent=None): - super(PickAssetDialog, self).__init__(parent) + super(SelectFolderPathDialog, self).__init__(parent) self.setWindowTitle("Select project and folder path..") self.setStyleSheet(load_stylesheet()) @@ -507,7 +507,7 @@ def select_folder_path(node): project_name = node.evalParm("project_name") folder_path = node.evalParm("folder_path") - dialog = PickAssetDialog(parent=main_window) + dialog = SelectFolderPathDialog(parent=main_window) dialog.set_project_name(project_name) if folder_path: # We add a small delay to the setting of the selected folder From 3e5a9fd301da7993a85052e22c446da30a39d0cd Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jun 2024 14:05:45 +0200 Subject: [PATCH 49/50] Match filter placeholder text with Loader UI --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index e7997f0e79..2270e39afb 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -442,7 +442,7 @@ def __init__(self, parent=None): project_widget.addItems(self.get_projects()) filter_widget = QtWidgets.QLineEdit() - filter_widget.setPlaceholderText("Filter folders..") + filter_widget.setPlaceholderText("Folder name filter...") folder_widget = SimpleFoldersWidget(parent=self) From afedffc48dcf4df393981a9ac5a270d897c5afaa Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 28 Jun 2024 14:10:09 +0200 Subject: [PATCH 50/50] Simplify window title --- server_addon/houdini/client/ayon_houdini/api/hda_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py index 2270e39afb..412364bc04 100644 --- a/server_addon/houdini/client/ayon_houdini/api/hda_utils.py +++ b/server_addon/houdini/client/ayon_houdini/api/hda_utils.py @@ -435,7 +435,7 @@ class SelectFolderPathDialog(QtWidgets.QDialog): def __init__(self, parent=None): super(SelectFolderPathDialog, self).__init__(parent) - self.setWindowTitle("Select project and folder path..") + self.setWindowTitle("Set project and folder path") self.setStyleSheet(load_stylesheet()) project_widget = QtWidgets.QComboBox()