Skip to content

Commit

Permalink
Merge branch 'develop' into enhancement/lop_load_shot
Browse files Browse the repository at this point in the history
  • Loading branch information
BigRoy authored Jul 30, 2024
2 parents c56bbf9 + f5c5ea8 commit b2264a6
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 55 deletions.
150 changes: 121 additions & 29 deletions client/ayon_houdini/api/hda_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

from ayon_houdini.api import lib

from qtpy import QtCore, QtWidgets
from qtpy import QtCore, QtWidgets, QtGui
import hou


Expand Down Expand Up @@ -129,14 +129,6 @@ def update_info(node, context):
if node.evalParm(key) != value}
parms["load_message"] = "" # clear any warnings/errors

# Update the product type filter to match the type
current = node.evalParm("product_type")
product_type = context["product"]["productType"]
if current and current != product_type:
# If current is empty we consider no filtering applied and we allow
# that to be a state that needs no switching
parms["product_type"] = product_type

# 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
Expand Down Expand Up @@ -555,38 +547,138 @@ def _select_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.
class SelectProductDialog(QtWidgets.QDialog):
"""Simple dialog to allow a user to select a product."""

Args:
node (hou.OpNode): The HDA node.
def __init__(self, project_name, folder_id, parent=None):
super(SelectProductDialog, self).__init__(parent)
self.setWindowTitle("Select a Product")
self.setStyleSheet(load_stylesheet())

self.project_name = project_name
self.folder_id = folder_id

# Create widgets and layout
product_types_widget = QtWidgets.QComboBox()
products_widget = QtWidgets.QListWidget()
accept_button = QtWidgets.QPushButton("Set product name")

main_layout = QtWidgets.QVBoxLayout(self)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.addWidget(product_types_widget, 0)
main_layout.addWidget(products_widget, 1)
main_layout.addWidget(accept_button, 0)

self.product_types_widget = product_types_widget
self.products_widget = products_widget

# Connect Signals
product_types_widget.currentTextChanged.connect(self.on_product_type_changed)
products_widget.itemDoubleClicked.connect(self.accept)
accept_button.clicked.connect(self.accept)

# Initialize widgets contents
product_types_widget.addItems(self.get_product_types())
product_type = self.get_selected_product_type()
self.set_product_type(product_type)

def get_selected_product(self) -> str:
if self.products_widget.currentItem():
return self.products_widget.currentItem().text()
return ""

def get_selected_product_type(self) -> str:
return self.product_types_widget.currentText()

def get_product_types(self) -> List[str]:
"""return default product types.
"""

return [
"*",
"animation",
"camera",
"model",
"pointcache",
"usd",
]

def on_product_type_changed(self, product_type: str):
self.set_product_type(product_type)

def set_product_type(self, product_type: str):
self.product_types_widget.setCurrentText(product_type)

if self.product_types_widget.currentText() != product_type:
# Product type does not exist
return

# Populate products list
products = self.get_available_products(product_type)
self.products_widget.clear()
if products:
self.products_widget.addItems(products)

def set_selected_product_name(self, product_name: str):
matching_items = self.products_widget.findItems(
product_name, QtCore.Qt.MatchFixedString)
if matching_items:
self.products_widget.setCurrentItem(matching_items[0])

def get_available_products(self, product_type):

if product_type == "*":
product_type = ""

product_types = [product_type] if product_type else None

products = ayon_api.get_products(
self.project_name,
folder_ids=[self.folder_id],
product_types=product_types
)

return list(sorted(product["name"] for product in products))


def select_product_name(node):
"""Show a modal pop-up dialog to allow user to select a product name
under the current folder entity as defined on the node's parameters.
Applies the chosen value to the `product_name` parm on the node."""

cursor_pos = QtGui.QCursor.pos()

Returns:
list[str]: Product names for Products menu.
"""
project_name = node.evalParm("project_name")
folder_path = node.evalParm("folder_path")
product_type = node.evalParm("product_type")
product_parm = node.parm("product_name")

folder_entity = ayon_api.get_folder_by_path(project_name,
folder_path,
fields={"id"})
if not folder_entity:
return []

# Apply filter only if any value is set
product_types = [product_type] if product_type else None

products = ayon_api.get_products(
return

dialog = SelectProductDialog(
project_name,
folder_ids=[folder_entity["id"]],
product_types=product_types
folder_entity["id"],
parent=lib.get_main_window()
)
dialog.set_selected_product_name(product_parm.eval())

dialog.resize(300, 600)
dialog.setWindowFlags(QtCore.Qt.Popup)
pos = dialog.mapToGlobal(cursor_pos - QtCore.QPoint(300, 0))
dialog.move(pos)
result = dialog.exec_()

if result != QtWidgets.QDialog.Accepted:
return
selected_product = dialog.get_selected_product()

return list(sorted(product["name"] for product in products))
if selected_product:
product_parm.set(selected_product)
product_parm.pressButton() # allow any callbacks to trigger


def set_to_latest_version(node):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,36 +47,13 @@
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" }
menu {
"" "*"
"animation" "animation"
"camera" "camera"
"model" "model"
"pointcache" "pointcache"
"usd" "usd"
}
}
parm {
name "product_name"
label "Product"
type string
default { "usdAsset" }
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_action" "from ayon_houdini.api.hda_utils import select_product_name;select_product_name(kwargs['node'])" }
parmtag { "script_action_icon" "BUTTONS_reselect" }
parmtag { "script_callback" "hou.phm().set_to_latest_version(kwargs['node'])\nhou.phm().on_representation_parms_changed(kwargs['node'])" }
parmtag { "script_callback_language" "python" }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ from ayon_houdini.api.hda_utils import (
on_representation_parms_changed,
setup_flag_changed_callback,
get_available_versions,
get_available_products,
select_product_name,
set_to_latest_version
)

0 comments on commit b2264a6

Please sign in to comment.