diff --git a/colorbleed/maya/menu.json b/colorbleed/maya/menu.json index da3b59e9c7..94aa716c13 100644 --- a/colorbleed/maya/menu.json +++ b/colorbleed/maya/menu.json @@ -925,6 +925,25 @@ } ] }, + { + "type": "menu", + "title": "Rendering", + "items": [ + { + "type": "action", + "command": "$COLORBLEED_SCRIPTS\\pyblish\\open_deadline_submission_settings.py", + "sourcetype": "file", + "tags": [ + "settings", + "deadline", + "globals", + "render" + ], + "title": "DL Submission Settings UI", + "tooltip": "Open the Deadline Submission Settings UI" + } + ] + }, { "type": "menu", "title": "Animation", diff --git a/colorbleed/plugins/maya/create/colorbleed_renderglobals.py b/colorbleed/plugins/maya/create/colorbleed_renderglobals.py new file mode 100644 index 0000000000..5ce04495cc --- /dev/null +++ b/colorbleed/plugins/maya/create/colorbleed_renderglobals.py @@ -0,0 +1,47 @@ +from collections import OrderedDict + +import maya.cmds as cmds + +import avalon.maya + + +class CreateRenderGlobals(avalon.maya.Creator): + + label = "Render Globals" + family = "colorbleed.renderglobals" + icon = "gears" + + def __init__(self, *args, **kwargs): + super(CreateRenderGlobals, self).__init__(*args, **kwargs) + + # We won't be publishing this one + self.data["id"] = "avalon.renderglobals" + + # We don't need subset or asset attributes + self.data.pop("subset", None) + self.data.pop("asset", None) + self.data.pop("active", None) + + data = OrderedDict(**self.data) + + data["suspendPublishJob"] = False + data["includeDefaultRenderLayer"] = False + data["priority"] = 50 + data["whitelist"] = False + data["machineList"] = "" + + self.data = data + self.options = {"useSelection": False} # Force no content + + def process(self): + + exists = cmds.ls(self.name) + assert len(exists) <= 1, ( + "More than one renderglobal exists, this is a bug") + + if exists: + return cmds.warning("%s already exists." % exists[0]) + + super(CreateRenderGlobals, self).process() + + cmds.setAttr("{}.machineList".format(self.name), lock=True) diff --git a/colorbleed/plugins/maya/publish/collect_renderlayers.py b/colorbleed/plugins/maya/publish/collect_renderlayers.py index a8cdc5a40f..71894d136b 100644 --- a/colorbleed/plugins/maya/publish/collect_renderlayers.py +++ b/colorbleed/plugins/maya/publish/collect_renderlayers.py @@ -23,12 +23,28 @@ class CollectMindbenderMayaRenderlayers(pyblish.api.ContextPlugin): relative_file = current_file.replace(registered_root, "{root}") source_file = relative_file.replace("\\", "/") + # Get render globals node + try: + render_globals = cmds.ls("renderglobalsDefault")[0] + except IndexError: + raise RuntimeError("Cannot collect renderlayers without " + "renderGlobals node") + + attr = "{}.includeDefaultRenderLayer".format(render_globals) + use_defaultlayer = cmds.getAttr(attr) + + # Get render layers renderlayers = cmds.ls(type="renderLayer") + if not use_defaultlayer: + renderlayers = [i for i in renderlayers if + not i.endswith("defaultRenderLayer")] + for layer in renderlayers: if layer.endswith("defaultRenderLayer"): - continue + layername = "masterLayer" + else: + layername = layer.split("rs_", 1)[-1] - layername = layer.split("rs_", 1)[-1] data = {"family": "Render Layers", "families": ["colorbleed.renderlayer"], "publish": cmds.getAttr("{}.renderable".format(layer)), @@ -62,13 +78,9 @@ class CollectMindbenderMayaRenderlayers(pyblish.api.ContextPlugin): # Include (optional) global settings # TODO(marcus): Take into account layer overrides - try: - avalon_globals = maya.lsattr("id", "avalon.renderglobals")[0] - except IndexError: - pass - else: - _globals = maya.read(avalon_globals) - data["renderGlobals"] = self.get_global_overrides(_globals) + # Get global overrides and translate to Deadline values + overrides = self.parse_options(render_globals) + data.update(**overrides) instance = context.create_instance(layername) instance.data.update(data) @@ -76,29 +88,34 @@ class CollectMindbenderMayaRenderlayers(pyblish.api.ContextPlugin): def get_render_attribute(self, attr): return cmds.getAttr("defaultRenderGlobals.{}".format(attr)) - def get_global_overrides(self, globals): - """ - Get all overrides with a value, skip those without + def parse_options(self, render_globals): + """Get all overrides with a value, skip those without Here's the kicker. These globals override defaults in the submission integrator, but an empty value means no overriding is made. Otherwise, Frames would override the default frames set under globals. Args: - globals (dict) collection of render globals + render_globals (str): collection of render globals Returns: dict: only overrides with values """ - keys = ["pool", "group", "frames", "priority"] - read_globals = {} - for key in keys: - value = globals[key] - if not value: - continue - read_globals[key.capitalize()] = value - if not read_globals: - self.log.info("Submitting without overrides") + attributes = maya.read(render_globals) - return read_globals \ No newline at end of file + options = {"renderGlobals": {}} + + options['renderGlobals']['Priority'] = attributes['priority'] + + # Machine list + machine_list = attributes["machineList"] + if machine_list: + key = "Whitelist" if attributes["whitelist"] else "Blacklist" + options['renderGlobals'][key] = machine_list + + # Suspend publish job + state = "Suspended" if attributes["suspendPublishJob"] else "Active" + options["suspendPublishJob"] = state + + return options diff --git a/colorbleed/plugins/maya/publish/submit_deadline.py b/colorbleed/plugins/maya/publish/submit_deadline.py index db0611839e..a0e6610744 100644 --- a/colorbleed/plugins/maya/publish/submit_deadline.py +++ b/colorbleed/plugins/maya/publish/submit_deadline.py @@ -194,7 +194,8 @@ class MindbenderSubmitDeadline(pyblish.api.InstancePlugin): }) # Include optional render globals - payload["JobInfo"].update(instance.data.get("renderGlobals", {})) + render_globals = instance.data.get("renderGlobals", {}) + payload["JobInfo"].update(render_globals) self.preflight_check(instance) @@ -215,14 +216,19 @@ class MindbenderSubmitDeadline(pyblish.api.InstancePlugin): with open(json_fpath, "w") as f: json.dump(data, f, indent=4, sort_keys=True) + self.log.info("Creating publish job") + state = instance.data["suspendPublishJob"] publish_job = self.create_publish_job(fname, deadline_user, comment, jobname, render_job, - json_fpath) + json_fpath, + state) if not publish_job: self.log.error("Could not submit publish job!") + else: + self.log.info(publish_job) else: try: @@ -279,15 +285,17 @@ class MindbenderSubmitDeadline(pyblish.api.InstancePlugin): ) def create_publish_job(self, fname, user, comment, jobname, - job, json_fpath): - """ - Make sure all frames are published + job, json_fpath, state): + """Make sure all frames are published + Args: job (dict): the render job data json_fpath (str): file path to json file + state (str): In which state the job needs to when submitted, e.g.: + "Suspended" Returns: - + dict """ url = "{}/api/jobs".format(api.Session["AVALON_DEADLINE"]) @@ -310,6 +318,7 @@ class MindbenderSubmitDeadline(pyblish.api.InstancePlugin): "JobDependency0": job["_id"], "UserName": user, "Comment": comment, + "InitialStatus": state }, "PluginInfo": { "Version": "3.6",