import re
from importlib import reload
from PySide6 import QtCore, QtWidgets
import cgl.ui.tools.assetizer.back_end as back_end
from cgl.core.config.query import AlchemyConfigManager
from cgl.core.path.object import PathObject
from cgl.core.path.support import start
from cgl.ui.widgets.widgets import AdvComboBox
CFG = AlchemyConfigManager()
reload(back_end)
[docs]
class Assetizer(QtWidgets.QDialog):
"""
This is the main widget for the Assetizer tool.
It allows you to select a mesh inside of a scene and create it to the asset you've defined
within the Assetizer.
It has 3 rows on a gridLayout:
Asset Category: [ComboBox]
Asset Name: [AdvComboBox]
message: [QLabel]
"""
def __init__(
self,
project=None,
company=None,
task="mdl",
ext=".ma",
dcc="maya",
asset_name=None,
parent=None,
):
super(Assetizer, self).__init__(parent=parent)
self.project = project
self.company = company
self.dcc = dcc
self.asset_selection = str(asset_name)
if not project:
print("No Project Specified")
self.accept()
return
self.task = task
self.ext = ext
self.setObjectName("Assetizer")
self.setWindowTitle("Assetizer")
self.setWindowFlags(QtCore.Qt.Window)
self.resize(400, 100)
self.gridLayout = QtWidgets.QGridLayout(self)
self.asset_category_label = QtWidgets.QLabel()
self.asset_category = QtWidgets.QComboBox()
self.asset_name_label = QtWidgets.QLabel()
self.asset_name_combo = AdvComboBox()
self.message = QtWidgets.QLabel()
self.create_button = QtWidgets.QPushButton("Create Asset")
self.gridLayout.addWidget(self.asset_category_label, 0, 0, 1, 1)
self.gridLayout.addWidget(self.asset_category, 0, 1, 1, 1)
self.gridLayout.addWidget(self.asset_name_label, 1, 0, 1, 1)
self.gridLayout.addWidget(self.asset_name_combo, 1, 1, 1, 1)
self.gridLayout.addWidget(self.message, 2, 0, 1, 2)
self.gridLayout.addWidget(self.create_button, 3, 0, 1, 2)
self.asset_category_label.setText("Asset Category:")
self.asset_name_label.setText("Asset Name:")
self.message.setText("")
self.create_button.clicked.connect(self.create_asset_clicked)
self.asset_category.currentIndexChanged.connect(self.update_asset_name)
self.asset_name_combo.lineEdit().textChanged.connect(self.update_message)
self.set_categories()
[docs]
def create_asset_clicked(self):
"""
This function creates the asset on disk and in the database.
"""
category_name = self.asset_category.currentText()
sn_category = CFG.shotgrid_config["asset_categories"][category_name]
asset_name = self.asset_name_combo.currentText()
po = self.get_path_object()
filename = ""
# see if it ends with an extension:
if self.ext:
filename = po.get_path()
back_end.create_asset(self.project, sn_category, asset_name)
self.export_selection(filename)
[docs]
def export_selection(self, filename, open_result=True):
"""
Uses the smart task sysemt to auotmatically pull out an export function for the current selection.
Args:
filename:
Returns:
"""
if not self.dcc:
print("No DCC Specified, skipping file export on asset creation")
return
print("loading smart task: ", self.dcc, self.task)
print("running export on: ", filename)
if self.dcc == "maya":
import cgl.ui.tools.assetizer.maya as maya
reload(maya)
maya.recenter_selected(
self.asset_name_combo.currentText(), filename=filename
)
self.close()
if open_result:
start(filename)
[docs]
def get_path_object(self):
"""
This function returns a PathObject based on the asset_category and asset_name combobox selections.
Returns:
"""
category_name = self.asset_category.currentText()
sn_category = CFG.shotgrid_config["asset_categories"][category_name]
asset_name = self.asset_name_combo.currentText()
user = CFG.user_config["user_info"]["alc_user"]
d_ = {
"project": self.project,
"company": self.company,
"entity_type": "assets",
"sequence": sn_category,
"shot": asset_name,
"task": self.task,
"tree": "source",
"sync_root": "VERSIONS",
"user": user,
"version": "000.000",
"variant": "default",
"resolution": "high",
}
po = PathObject().from_dict(d_)
if self.ext:
po = po.copy(latest=True, set_filename=True, ext=self.ext)
print("setting filename", po.get_path())
else:
print("not setting filename")
po = po.copy(latest=True)
return po
[docs]
def update_asset_name(self):
"""
This function is called when the user selects a new asset category.
It will update the asset_name combobox with the assets that are available for that category.
"""
self.asset_name_combo.clear()
self.asset_name_combo.addItems(self.get_assets())
if self.asset_selection:
self.asset_name_combo.setCurrentText(self.asset_selection)
[docs]
def update_message(self):
"""
This function is called when the user selects a new asset name.
It will update the message label with the path to the asset.
"""
category, name = self.get_asset_path().split(":")
if not self.is_valid_name(name):
# set the message to
self.message.setStyleSheet("color: red;")
else:
# set the message to black
self.message.setStyleSheet("color: black;")
message = "Create selected Model as: {}".format(self.get_asset_path())
self.message.setText(message)
[docs]
def get_categories(self):
"""
This function returns a list of asset categories.
"""
return CFG.shotgrid_config["asset_categories"].keys()
[docs]
def set_categories(self):
"""
This function sets the asset_category combobox with the asset categories.
"""
self.asset_category.addItems(self.get_categories())
[docs]
def get_assets(self):
"""
This function returns a list of assets based on the asset_category combobox selection.
"""
category = self.asset_category.currentText()
sn_category = CFG.shotgrid_config["asset_categories"][category]
d_ = {
"project": "JLT",
"company": "CGL",
"sequence": sn_category,
"tree": "source",
"entity_type": "assets",
"sync_root": "VERSIONS",
}
po = PathObject().from_dict(d_)
try:
assets = po.get_project_msd_dict()["data"]["assets"][sn_category].keys()
except KeyError:
assets = []
assets = list(assets)
assets.insert(0, "")
return list(assets)
[docs]
def get_asset_path(self):
"""
This function returns the path to the asset based on the asset_category and asset_name combobox selections.
"""
return (
f"{self.asset_category.currentText()}:{self.asset_name_combo.currentText()}"
)
[docs]
def model_selected(self, selected):
"""
This function acts as a way to interact with the UI from the outside when somnething is selcted.
Returns:
"""
print("model selected", selected)
[docs]
def is_valid_name(self, asset_name):
"""
This function checks if the asset name is valid.
valid asset names are camelCase starting with lower case letter
and they are less than 15 characters long.
we'll use the re module to check if the name is valid.
Args:
asset_name:
Returns:
"""
if len(asset_name) > 15 or len(asset_name) == 0:
return False
if not re.match("^[a-z]*$|^[a-z]*[A-Z][a-z]*|^[a-z]*[A-Z]$", asset_name):
return False
return True
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
assetizer = Assetizer(project="JLT")
assetizer.show()
sys.exit(app.exec())