diff --git a/pype/hosts/celaction/cli.py b/pype/hosts/celaction/cli.py index fa55db3200..8cf2bcc791 100644 --- a/pype/hosts/celaction/cli.py +++ b/pype/hosts/celaction/cli.py @@ -11,7 +11,7 @@ import pyblish.util from pype.api import Logger import pype -import pype.celaction +from pype.hosts import celaction log = Logger().get_logger("Celaction_cli_publisher") @@ -49,7 +49,7 @@ def cli(): # parser.add_argument("--programDir", # help=("Directory with celaction program installation")) - pype.celaction.kwargs = parser.parse_args(sys.argv[1:]).__dict__ + celaction.kwargs = parser.parse_args(sys.argv[1:]).__dict__ def _prepare_publish_environments(): diff --git a/pype/hosts/maya/expected_files.py b/pype/hosts/maya/expected_files.py index 3292b867ce..a7204cba93 100644 --- a/pype/hosts/maya/expected_files.py +++ b/pype/hosts/maya/expected_files.py @@ -536,6 +536,15 @@ class ExpectedFilesVray(AExpectedFiles): prefix = "{}_".format(prefix) return prefix + def _get_layer_data(self): + """Override to get vray specific extension.""" + layer_data = super(ExpectedFilesVray, self)._get_layer_data() + default_ext = cmds.getAttr("vraySettings.imageFormatStr") + if default_ext == "exr (multichannel)" or default_ext == "exr (deep)": + default_ext = "exr" + layer_data["defaultExt"] = default_ext + return layer_data + def get_files(self): """Get expected files. diff --git a/pype/modules/adobe_communicator/lib/publish.py b/pype/modules/adobe_communicator/lib/publish.py index 6a9faf0403..b222a1bd59 100644 --- a/pype/modules/adobe_communicator/lib/publish.py +++ b/pype/modules/adobe_communicator/lib/publish.py @@ -18,7 +18,7 @@ def main(env): # Register Host (and it's pyblish plugins) host_name = env["AVALON_APP"] # TODO not sure if use "pype." or "avalon." for host import - host_import_str = f"pype.{host_name}" + host_import_str = f"pype.hosts.{host_name}" try: host_module = importlib.import_module(host_import_str) diff --git a/pype/plugins/celaction/publish/collect_celaction_cli_kwargs.py b/pype/plugins/celaction/publish/collect_celaction_cli_kwargs.py index 5042a7b700..f4a9ec341d 100644 --- a/pype/plugins/celaction/publish/collect_celaction_cli_kwargs.py +++ b/pype/plugins/celaction/publish/collect_celaction_cli_kwargs.py @@ -1,5 +1,5 @@ import pyblish.api -import pype.celaction +from pype.hosts import celaction class CollectCelactionCliKwargs(pyblish.api.Collector): @@ -9,7 +9,7 @@ class CollectCelactionCliKwargs(pyblish.api.Collector): order = pyblish.api.Collector.order - 0.1 def process(self, context): - kwargs = pype.celaction.kwargs.copy() + kwargs = celaction.kwargs.copy() self.log.info("Storing kwargs: %s" % kwargs) context.set_data("kwargs", kwargs) diff --git a/pype/plugins/celaction/publish/collect_celaction_instances.py b/pype/plugins/celaction/publish/collect_celaction_instances.py index aa2bb5da5d..431ab722d3 100644 --- a/pype/plugins/celaction/publish/collect_celaction_instances.py +++ b/pype/plugins/celaction/publish/collect_celaction_instances.py @@ -16,6 +16,7 @@ class CollectCelactionInstances(pyblish.api.ContextPlugin): scene_file = os.path.basename(current_file) version = context.data["version"] asset_entity = context.data["assetEntity"] + project_entity = context.data["projectEntity"] shared_instance_data = { "asset": asset_entity["name"], @@ -24,8 +25,12 @@ class CollectCelactionInstances(pyblish.api.ContextPlugin): "handleStart": asset_entity["data"]["handleStart"], "handleEnd": asset_entity["data"]["handleEnd"], "fps": asset_entity["data"]["fps"], - "resolutionWidth": asset_entity["data"]["resolutionWidth"], - "resolutionHeight": asset_entity["data"]["resolutionHeight"], + "resolutionWidth": asset_entity["data"].get( + "resolutionWidth", + project_entity["data"]["resolutionWidth"]), + "resolutionHeight": asset_entity["data"].get( + "resolutionHeight", + project_entity["data"]["resolutionHeight"]), "pixelAspect": 1, "step": 1, "version": version diff --git a/pype/plugins/celaction/publish/collect_render_path.py b/pype/plugins/celaction/publish/collect_render_path.py index cddd2643d8..d5fe6c07a5 100644 --- a/pype/plugins/celaction/publish/collect_render_path.py +++ b/pype/plugins/celaction/publish/collect_render_path.py @@ -1,5 +1,6 @@ import os import pyblish.api +import copy class CollectRenderPath(pyblish.api.InstancePlugin): @@ -7,19 +8,21 @@ class CollectRenderPath(pyblish.api.InstancePlugin): label = "Collect Render Path" order = pyblish.api.CollectorOrder + 0.495 + families = ["render.farm"] def process(self, instance): anatomy = instance.context.data["anatomy"] - current_file = instance.context.data["currentFile"] - work_dir = os.path.dirname(current_file) + anatomy_data = copy.deepcopy(instance.data["anatomyData"]) padding = anatomy.templates.get("frame_padding", 4) - render_dir = os.path.join( - work_dir, "render", "celaction" - ) - render_path = os.path.join( - render_dir, - ".".join([instance.data["subset"], f"%0{padding}d", "png"]) - ) + anatomy_data.update({ + "frame": f"%0{padding}d", + "representation": "png" + }) + + anatomy_filled = anatomy.format(anatomy_data) + + render_dir = anatomy_filled["render_tmp"]["folder"] + render_path = anatomy_filled["render_tmp"]["path"] # create dir if it doesnt exists os.makedirs(render_dir, exist_ok=True) diff --git a/pype/plugins/celaction/publish/submit_celaction_deadline.py b/pype/plugins/celaction/publish/submit_celaction_deadline.py index 0bb346f7cf..c749ec111f 100644 --- a/pype/plugins/celaction/publish/submit_celaction_deadline.py +++ b/pype/plugins/celaction/publish/submit_celaction_deadline.py @@ -27,6 +27,12 @@ class ExtractCelactionDeadline(pyblish.api.InstancePlugin): deadline_group = "" deadline_chunk_size = 1 + enviro_filter = [ + "FTRACK_API_USER", + "FTRACK_API_KEY", + "FTRACK_SERVER" + ] + def process(self, instance): context = instance.context @@ -155,6 +161,19 @@ class ExtractCelactionDeadline(pyblish.api.InstancePlugin): plugin = payload["JobInfo"]["Plugin"] self.log.info("using render plugin : {}".format(plugin)) + i = 0 + for key, values in dict(os.environ).items(): + if key.upper() in self.enviro_filter: + payload["JobInfo"].update( + { + "EnvironmentKeyValue%d" + % i: "{key}={value}".format( + key=key, value=values + ) + } + ) + i += 1 + self.log.info("Submitting..") self.log.info(json.dumps(payload, indent=4, sort_keys=True)) diff --git a/pype/plugins/global/publish/extract_review.py b/pype/plugins/global/publish/extract_review.py index 0f15295118..30d1de8328 100644 --- a/pype/plugins/global/publish/extract_review.py +++ b/pype/plugins/global/publish/extract_review.py @@ -285,6 +285,20 @@ class ExtractReview(pyblish.api.InstancePlugin): # Prepare input and output filepaths self.input_output_paths(new_repre, output_def, temp_data) + # Set output frames len to 1 when ouput is single image + if ( + temp_data["output_ext_is_image"] + and not temp_data["output_is_sequence"] + ): + output_frames_len = 1 + + else: + output_frames_len = ( + temp_data["output_frame_end"] + - temp_data["output_frame_start"] + + 1 + ) + if temp_data["input_is_sequence"]: # Set start frame ffmpeg_input_args.append( @@ -303,31 +317,14 @@ class ExtractReview(pyblish.api.InstancePlugin): ) elif temp_data["without_handles"]: - # TODO use frames ubstead if `-ss`: - # `select="gte(n\,{handle_start}),setpts=PTS-STARTPTS` - # Pros: - # 1.) Python is not good at float operation - # 2.) FPS on instance may not be same as input's start_sec = float(temp_data["handle_start"]) / temp_data["fps"] ffmpeg_input_args.append("-ss {:0.2f}".format(start_sec)) - # Set output frames len to 1 when ouput is single image - if ( - temp_data["output_ext_is_image"] - and not temp_data["output_is_sequence"] - ): - output_frames_len = 1 + duration_sec = float(output_frames_len / temp_data["fps"]) + ffmpeg_output_args.append("-t {:0.2f}".format(duration_sec)) - else: - output_frames_len = ( - temp_data["output_frame_end"] - - temp_data["output_frame_start"] - + 1 - ) - - # NOTE used `-frames` instead of `-t` - should work the same way - # NOTE this also replaced `-shortest` argument - ffmpeg_output_args.append("-frames {}".format(output_frames_len)) + # Use shortest input + ffmpeg_output_args.append("-shortest") # Add video/image input path ffmpeg_input_args.append( diff --git a/pype/plugins/global/publish/submit_publish_job.py b/pype/plugins/global/publish/submit_publish_job.py index 82de2ec099..7a73e921e2 100644 --- a/pype/plugins/global/publish/submit_publish_job.py +++ b/pype/plugins/global/publish/submit_publish_job.py @@ -166,8 +166,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "FTRACK_SERVER", "PYPE_METADATA_FILE", "AVALON_PROJECT", - "PYPE_LOG_NO_COLORS", - "PYPE_PYTHON_EXE" + "PYPE_LOG_NO_COLORS" ] # custom deadline atributes @@ -191,6 +190,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): # list of family names to transfer to new family if present families_transfer = ["render3d", "render2d", "ftrack", "slate"] + plugin_python_version = "3.7" def _submit_deadline_post_job(self, instance, job): """Submit publish job to Deadline. @@ -202,9 +202,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): """ data = instance.data.copy() subset = data["subset"] - job_name = "{batch} - {subset} [publish image sequence]".format( - batch=job["Props"]["Name"], subset=subset - ) + job_name = "Publish - {subset}".format(subset=subset) output_dir = instance.data["outputDir"] # Convert output dir to `{root}/rest/of/path/...` with Anatomy @@ -240,7 +238,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "OutputDirectory0": output_dir }, "PluginInfo": { - "Version": "3.6", + "Version": self.plugin_python_version, "ScriptFile": _get_script(), "Arguments": "", "SingleFrameOnly": "True", diff --git a/pype/plugins/maya/publish/submit_maya_deadline.py b/pype/plugins/maya/publish/submit_maya_deadline.py index 8750d88b90..d81d43749c 100644 --- a/pype/plugins/maya/publish/submit_maya_deadline.py +++ b/pype/plugins/maya/publish/submit_maya_deadline.py @@ -59,7 +59,7 @@ payload_skeleton = { } -def get_renderer_variables(renderlayer=None): +def get_renderer_variables(renderlayer, root): """Retrieve the extension which has been set in the VRay settings. Will return None if the current renderer is not VRay @@ -68,6 +68,7 @@ def get_renderer_variables(renderlayer=None): Args: renderlayer (str): the node name of the renderlayer. + root (str): base path to render Returns: dict @@ -87,6 +88,7 @@ def get_renderer_variables(renderlayer=None): filename_0 = filename_0.replace('_', '_beauty') prefix_attr = "defaultRenderGlobals.imageFilePrefix" if renderer == "vray": + renderlayer = renderlayer.split("_")[-1] # Maya's renderSettings function does not return V-Ray file extension # so we get the extension from vraySettings extension = cmds.getAttr("vraySettings.imageFormatStr") @@ -101,6 +103,16 @@ def get_renderer_variables(renderlayer=None): extension = "exr" prefix_attr = "vraySettings.fileNamePrefix" + filename_prefix = cmds.getAttr(prefix_attr) + # we need to determine path for vray as maya `renderSettings` query + # does not work for vray. + scene = cmds.file(query=True, sceneName=True) + scene, _ = os.path.splitext(os.path.basename(scene)) + filename_0 = filename_prefix.replace('', scene) + filename_0 = filename_0.replace('', renderlayer) + filename_0 = "{}.{}.{}".format( + filename_0, "#" * int(padding), extension) + filename_0 = os.path.normpath(os.path.join(root, filename_0)) elif renderer == "renderman": prefix_attr = "rmanGlobals.imageFileFormat" elif renderer == "redshift": @@ -236,7 +248,7 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): jobname = "%s - %s" % (filename, instance.name) # Get the variables depending on the renderer - render_variables = get_renderer_variables(renderlayer) + render_variables = get_renderer_variables(renderlayer, dirname) filename_0 = render_variables["filename_0"] if self.use_published: new_scene = os.path.splitext(filename)[0] @@ -267,6 +279,11 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): payload_data["workspace"] = workspace payload_data["dirname"] = dirname + self.log.info("--- Submission data:") + for k, v in payload_data.items(): + self.log.info("- {}: {}".format(k, v)) + self.log.info("-" * 20) + frame_pattern = payload_skeleton["JobInfo"]["Frames"] payload_skeleton["JobInfo"]["Frames"] = frame_pattern.format( start=int(self._instance.data["frameStartHandle"]), @@ -295,9 +312,7 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): dependencies = instance.context.data["fileDependencies"] dependencies.append(filepath) for dependency in dependencies: - self.log.info(dependency) key = "AssetDependency" + str(dependencies.index(dependency)) - self.log.info(key) payload_skeleton["JobInfo"][key] = dependency # Handle environments ----------------------------------------------- @@ -311,8 +326,7 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): "AVALON_TASK", "PYPE_USERNAME", "PYPE_DEV", - "PYPE_LOG_NO_COLORS", - "PYPE_SETUP_PATH" + "PYPE_LOG_NO_COLORS" ] environment = dict({key: os.environ[key] for key in keys @@ -388,7 +402,7 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): raise Exception(response.text) # Store output dir for unified publisher (filesequence) - instance.data["outputDir"] = os.path.dirname(filename_0) + instance.data["outputDir"] = os.path.dirname(output_filename_0) instance.data["deadlineSubmissionJob"] = response.json() def _get_maya_payload(self, data): @@ -423,6 +437,13 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): def _get_vray_export_payload(self, data): payload = copy.deepcopy(payload_skeleton) + vray_settings = cmds.ls(type="VRaySettingsNode") + node = vray_settings[0] + template = cmds.getAttr("{}.vrscene_filename".format(node)) + scene, _ = os.path.splitext(data["filename"]) + first_file = self.format_vray_output_filename(scene, template) + first_file = "{}/{}".format(data["workspace"], first_file) + output = os.path.dirname(first_file) job_info_ext = { # Job name, as seen in Monitor "Name": "Export {} [{}-{}]".format( @@ -444,7 +465,8 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): "UsingRenderLayers": True, "UseLegacyRenderLayers": True, "RenderLayer": data["renderlayer"], - "ProjectPath": data["workspace"] + "ProjectPath": data["workspace"], + "OutputFilePath": output } payload["JobInfo"].update(job_info_ext) @@ -545,6 +567,8 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): "Width": self._instance.data["resolutionWidth"], "Height": self._instance.data["resolutionHeight"], + "OutputFilePath": payload["JobInfo"]["OutputDirectory0"], + "OutputFileName": payload["JobInfo"]["OutputFilename0"] } payload["JobInfo"].update(job_info_ext) @@ -669,11 +693,13 @@ class MayaSubmitDeadline(pyblish.api.InstancePlugin): # Ensure filename has no extension file_name, _ = os.path.splitext(filename) + layer = self._instance.data['setMembers'] + # Reformat without tokens output_path = smart_replace( template, {"": file_name, - "": self._instance.data['setMembers']}) + "": layer}) if dir: return output_path.replace("\\", "/") diff --git a/pype/plugins/maya/publish/validate_rendersettings.py b/pype/plugins/maya/publish/validate_rendersettings.py index 16484affad..297ead5ebb 100644 --- a/pype/plugins/maya/publish/validate_rendersettings.py +++ b/pype/plugins/maya/publish/validate_rendersettings.py @@ -56,7 +56,7 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin): 'arnold': 'maya///_', 'redshift': 'maya///', - 'vray': 'maya///', + 'vray': 'maya///', 'renderman': '_..' } @@ -77,7 +77,7 @@ class ValidateRenderSettings(pyblish.api.InstancePlugin): R_SCENE_TOKEN = re.compile(r'%s|', re.IGNORECASE) DEFAULT_PADDING = 4 - VRAY_PREFIX = "maya///" + VRAY_PREFIX = "maya///" DEFAULT_PREFIX = "maya///_" def process(self, instance): diff --git a/pype/plugins/maya/publish/validate_vray_translator_settings.py b/pype/plugins/maya/publish/validate_vray_translator_settings.py index 493febf49a..592f24e36f 100644 --- a/pype/plugins/maya/publish/validate_vray_translator_settings.py +++ b/pype/plugins/maya/publish/validate_vray_translator_settings.py @@ -46,7 +46,7 @@ class ValidateVRayTranslatorEnabled(pyblish.api.ContextPlugin): invalid = True vrscene_filename = cmds.getAttr("{}.vrscene_filename".format(node)) - if vrscene_filename != "vrayscene//_/": + if vrscene_filename != "vrayscene///": cls.log.error("Template for file name is wrong") invalid = True @@ -65,5 +65,5 @@ class ValidateVRayTranslatorEnabled(pyblish.api.ContextPlugin): cmds.setAttr("{}.vrscene_on".format(node), True) cmds.setAttr("{}.misc_eachFrameInFile".format(node), True) cmds.setAttr("{}.vrscene_filename".format(node), - "vrayscene//_/", + "vrayscene///", type="string")