-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add slapcomp compatibility #5
base: master
Are you sure you want to change the base?
Changes from 6 commits
d92ad10
d2363a1
564df18
bcc7b8c
88662d1
3793eec
6df9853
0528d2e
02a4bc0
03226f4
6540062
865eac3
bd01af9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from .app import show | ||
|
||
|
||
__all__ = [ | ||
"show" | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,26 @@ | ||
import sys | ||
# import pprint | ||
|
||
from avalon import api, io | ||
from avalon.tools import lib as tools_lib | ||
from avalon.vendor.Qt import QtWidgets, QtCore | ||
from avalon.vendor import qtawesome as qta | ||
|
||
from . import lib | ||
from . import mayalib | ||
|
||
module = sys.modules[__name__] | ||
module.window = None | ||
|
||
|
||
class App(QtWidgets.QWidget): | ||
"""Main application for alter settings per render job (layer)""" | ||
|
||
def __init__(self): | ||
QtWidgets.QWidget.__init__(self) | ||
def __init__(self, parent=None): | ||
QtWidgets.QWidget.__init__(self, parent) | ||
|
||
self.setWindowTitle("Deadline Submission setting") | ||
self.setFixedSize(250, 500) | ||
self.setFixedSize(250, 480) | ||
|
||
self.setup_ui() | ||
self.connections() | ||
|
@@ -29,14 +38,28 @@ def setup_ui(self): | |
|
||
publish = QtWidgets.QCheckBox("Suspend Publish Job") | ||
defaultlayer = QtWidgets.QCheckBox("Include Default Render Layer") | ||
run_slap_comp = QtWidgets.QCheckBox("Run Slap Comp") | ||
|
||
brows_hlayout = QtWidgets.QHBoxLayout() | ||
file_line = QtWidgets.QLineEdit() | ||
|
||
brows_icon = qta.icon("fa.folder", color="white") | ||
brows_btn = QtWidgets.QPushButton() | ||
brows_btn.setIcon(brows_icon) | ||
|
||
file_line.setPlaceholderText("<Slap Comp File>") | ||
file_line.setEnabled(False) | ||
brows_btn.setEnabled(False) | ||
|
||
brows_hlayout.addWidget(file_line) | ||
brows_hlayout.addWidget(brows_btn) | ||
|
||
# region Priority | ||
priority_grp = QtWidgets.QGroupBox("Priority") | ||
priority_hlayout = QtWidgets.QHBoxLayout() | ||
|
||
priority_value = QtWidgets.QSpinBox() | ||
priority_value.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons) | ||
priority_value.setEnabled(False) | ||
priority_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) | ||
priority_slider.setMinimum(0) | ||
priority_slider.setMaximum(99) | ||
|
@@ -94,6 +117,8 @@ def setup_ui(self): | |
|
||
layout.addWidget(defaultlayer) | ||
layout.addWidget(publish) | ||
layout.addWidget(run_slap_comp) | ||
layout.addLayout(brows_hlayout) | ||
layout.addWidget(priority_grp) | ||
layout.addWidget(list_type_grp) | ||
layout.addLayout(machines_hlayout) | ||
|
@@ -102,6 +127,9 @@ def setup_ui(self): | |
# Enable access for all methods | ||
self.publish = publish | ||
self.defaultlayer = defaultlayer | ||
self.run_slap_comp = run_slap_comp | ||
self.flow_file = file_line | ||
self.brows_file_btn = brows_btn | ||
self.priority_value = priority_value | ||
self.priority_slider = priority_slider | ||
self.black_list = black_list | ||
|
@@ -115,16 +143,36 @@ def setup_ui(self): | |
self.setLayout(layout) | ||
|
||
def connections(self): | ||
|
||
self.run_slap_comp.toggled.connect(self.on_run_slap_comp_toggled) | ||
self.brows_file_btn.clicked.connect(self.on_brows_clicked) | ||
|
||
self.priority_slider.valueChanged[int].connect( | ||
self.priority_value.setValue) | ||
|
||
self.priority_value.valueChanged.connect(self.priority_slider.setValue) | ||
|
||
self.add_machine_btn.clicked.connect(self.add_selected_machines) | ||
self.remove_machine_btn.clicked.connect(self.remove_selected_machines) | ||
self.accept.clicked.connect(self.parse_settings) | ||
|
||
self.priority_slider.setValue(50) | ||
|
||
def add_per_job_settings(self): | ||
"""Create a mini settings for each render layer which is discovered""" | ||
pass | ||
def on_run_slap_comp_toggled(self): | ||
state = self.run_slap_comp.isChecked() | ||
self.flow_file.setEnabled(state) | ||
self.brows_file_btn.setEnabled(state) | ||
|
||
def on_brows_clicked(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo, |
||
|
||
workdir = lib.get_work_directory() | ||
file_path, _ = QtWidgets.QFileDialog.getOpenFileName( | ||
self, "Choose comp", workdir, filter="*.comp") | ||
|
||
if not file_path: | ||
return | ||
|
||
self.flow_file.setText(file_path) | ||
|
||
def add_selected_machines(self): | ||
"""Add selected machines to the list which is going to be used""" | ||
|
@@ -153,68 +201,51 @@ def create_machine_limit_options(self): | |
for name in lib.get_machine_list(): | ||
self.machine_list.addItem(name) | ||
|
||
def create_pools_options(self): | ||
pools = lib.get_pool_list() | ||
for pool in pools: | ||
self.pools.addItem(pool) | ||
|
||
def create_groups_options(self): | ||
groups = lib.get_group_list() | ||
for group in groups: | ||
self.groups.addItem(group) | ||
|
||
def refresh(self): | ||
|
||
self.pools.clear() | ||
self.groups.clear() | ||
self.machine_list.clear() | ||
|
||
self.create_machine_limit_options() | ||
self.create_pools_options() | ||
self.create_groups_options() | ||
|
||
def parse_settings(self): | ||
|
||
# Get the node, create node if none exists | ||
# Get UI settings as dict | ||
job_info = {} | ||
|
||
machine_limits = self._get_listed_machines() | ||
machine_limits = " ".join(machine_limits) | ||
|
||
job_info["priority"] = self.priority_value.value() | ||
job_info["suspendPublishJob"] = self.publish.isChecked() | ||
job_info["includeDefaultRenderLayer"] = self.defaultlayer.isChecked() | ||
row_slap_coml = self.run_slap_comp.isChecked() | ||
if row_slap_coml: | ||
job_info["runSlapComp"] = row_slap_coml | ||
job_info["flowFile"] = self.flow_file.text() | ||
|
||
job_info["whitelist"] = self._get_list_type() | ||
job_info["machineList"] = machine_limits | ||
|
||
# Get the node and apply settings | ||
instance = mayalib.find_render_instance() | ||
if not instance: | ||
instance = mayalib.create_renderglobals_node() | ||
|
||
# Get UI settings as dict | ||
job_info = self._get_settings() | ||
self.renderglobals_message() | ||
return | ||
|
||
mayalib.apply_settings(instance, job_info) | ||
|
||
def renderglobals_message(self): | ||
|
||
message = ("Please use the Creator from the Avalon menu to create " | ||
"a renderglobalsDefault isntance or use the button on the " | ||
"bottom of the screen.") | ||
message = ("Please use the Creator from the Avalon menu to create" | ||
"a renderglobalsDefault instance") | ||
|
||
button = QtWidgets.QMessageBox.StandardButton.Ok | ||
|
||
QtWidgets.QMessageBox.critical(self, | ||
"Missing renderglobalsDefault node", | ||
"Missing instance", | ||
message, | ||
button) | ||
return | ||
|
||
def _get_settings(self): | ||
|
||
settings = {} | ||
machine_list_type = self._get_list_type() | ||
|
||
machine_limits = self._get_listed_machines() | ||
machine_limits = " ".join(machine_limits) | ||
|
||
settings["priority"] = self.priority_value.value() | ||
settings["includeDefaultRenderLayer"] = self.defaultlayer.isChecked() | ||
settings["suspendPublishJob"] = self.publish.isChecked() | ||
|
||
settings[machine_list_type] = machine_limits | ||
|
||
return settings | ||
|
||
def _apply_settings(self): | ||
|
||
instance = mayalib.find_render_instance() | ||
|
@@ -225,37 +256,58 @@ def _apply_settings(self): | |
|
||
# Apply settings from node | ||
self.publish.setChecked(settings["suspendPublishJob"]) | ||
self.defaultlayer.setChecked(settings["includeDefaultRenderLayer"]) | ||
self.priority_slider.setValue(settings["priority"]) | ||
self.defaultlayer.setChecked(settings["includeDefaultRenderLayer"]) | ||
self.run_slap_comp.setChecked(settings["runSlapComp"]) | ||
|
||
if settings.get("flowFile", None): | ||
self.flow_file.setText(settings["flowFile"]) | ||
|
||
white_list = "Whitelist" in settings | ||
white_list = "whiteList" in settings | ||
self.white_list.setChecked(white_list) | ||
self.black_list.setChecked(not white_list) | ||
|
||
self.listed_machines.addItems(settings["machineList"].split(" ")) | ||
|
||
def _get_list_type(self): | ||
if self.white_list.isChecked(): | ||
return "Whitelist" | ||
else: | ||
return "Blacklist" | ||
return self.white_list.isChecked | ||
|
||
def _get_listed_machines(self): | ||
items = [self.listed_machines.item(r) for r in | ||
range(self.listed_machines.count())] | ||
listed_machines = [i.text() for i in items] | ||
# Turn unicode to strings | ||
return [str(self.listed_machines.item(r).text()) for r in | ||
range(self.listed_machines.count())] | ||
|
||
return listed_machines | ||
|
||
def show(root=None, debug=False, parent=None): | ||
"""Display Loader GUI | ||
|
||
Arguments: | ||
debug (bool, optional): Run loader in debug-mode, | ||
defaults to False | ||
|
||
""" | ||
|
||
try: | ||
module.window.close() | ||
del module.window | ||
except (RuntimeError, AttributeError): | ||
pass | ||
|
||
if debug is True: | ||
io.install() | ||
|
||
def launch(): | ||
global application | ||
application = App() | ||
application.show() | ||
any_project = next( | ||
project for project in io.projects() | ||
if project.get("active", True) is not False | ||
) | ||
|
||
api.Session["AVALON_PROJECT"] = any_project["name"] | ||
|
||
if __name__ == '__main__': | ||
import sys | ||
with tools_lib.application(): | ||
window = App(parent) | ||
# Do not apply stylesheet, not nessecary in Maya | ||
# window.setStyleSheet(style.load_stylesheet()) | ||
window.show() | ||
window.refresh() | ||
|
||
app = QtWidgets.QApplication(sys.argv) | ||
test = App() | ||
test.show() | ||
app.exec_() | ||
module.window = window |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,13 +6,35 @@ | |
|
||
import logging | ||
|
||
import avalon | ||
import os | ||
|
||
from avalon import io, api, pipeline | ||
from avalon.vendor import requests | ||
|
||
|
||
log = logging.getLogger("DSS - Lib") | ||
|
||
|
||
def get_work_directory(): | ||
"""Get the work directory to Fusion through the template""" | ||
|
||
session = api.Session.copy() | ||
project = io.find_one({"type": "project", | ||
"name": api.Session["AVALON_PROJECT"]}) | ||
assert project, "This is a bug" | ||
template = project["config"]["template"]["work"] | ||
|
||
session["AVALON_TASK"] = "comp" | ||
session["AVALON_APP"] = "fusion" | ||
work_directory = pipeline._format_work_template(template, session) | ||
|
||
if not os.path.isdir(work_directory): | ||
print("Fusion app folder does not exist:\n%s" % work_directory) | ||
work_directory = pipeline._format_work_template(template, api.Session) | ||
|
||
return work_directory | ||
|
||
|
||
def query(argument): | ||
"""Lazy wrapper for request.get""" | ||
|
||
|
@@ -29,21 +51,21 @@ def query(argument): | |
|
||
def get_machine_list(debug=None): | ||
"""Fetch the machine list (slaves) from Deadline""" | ||
AVALON_SESSION = debug or avalon.Session["AVALON_DEADLINE"] | ||
AVALON_SESSION = debug or api.Session["AVALON_DEADLINE"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make more sense to call this variable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LOL, this slipped in without me even noticing. I know I wanted to call it AVALON_DEADLINE :') |
||
argument = "{}/api/slaves?NamesOnly=true".format(AVALON_SESSION) | ||
return query(argument=argument) | ||
|
||
|
||
def get_pool_list(debug=None): | ||
"""Get all pools from Deadline""" | ||
AVALON_SESSION = debug or avalon.Session["AVALON_DEADLINE"] | ||
AVALON_SESSION = debug or api.Session["AVALON_DEADLINE"] | ||
argument = "{}/api/pools?NamesOnly=true".format(AVALON_SESSION) | ||
return query(argument) | ||
|
||
|
||
def get_group_list(debug=None): | ||
"""Get all groups from Deadline""" | ||
AVALON_SESSION = debug or avalon.Session["AVALON_DEADLINE"] | ||
AVALON_SESSION = debug or api.Session["AVALON_DEADLINE"] | ||
argument = "{}/api/groups?NamesOnly=true".format(AVALON_SESSION) | ||
return query(argument) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hehe, sorry @aardschok - noticed just right now there are actually much more variables with
brows
instead ofbrowse
- this line and the lines below (45 to 54, 120, 131)