diff --git a/openpype/hosts/aftereffects/api/extension.zxp b/openpype/hosts/aftereffects/api/extension.zxp index 217d06098f..e7b3bcac8a 100644 Binary files a/openpype/hosts/aftereffects/api/extension.zxp and b/openpype/hosts/aftereffects/api/extension.zxp differ diff --git a/openpype/hosts/aftereffects/api/extension/js/main.js b/openpype/hosts/aftereffects/api/extension/js/main.js index 2105ea82dc..bb0f3b1f0c 100644 --- a/openpype/hosts/aftereffects/api/extension/js/main.js +++ b/openpype/hosts/aftereffects/api/extension/js/main.js @@ -237,7 +237,7 @@ function main(websocket_url){ RPC.addRoute('AfterEffects.get_render_info', function (data) { log.warn('Server called client route "get_render_info":', data); - return runEvalScript("getRenderInfo()") + return runEvalScript("getRenderInfo(" + data.comp_id +")") .then(function(result){ log.warn("get_render_info: " + result); return result; @@ -289,7 +289,7 @@ function main(websocket_url){ RPC.addRoute('AfterEffects.render', function (data) { log.warn('Server called client route "render":', data); var escapedPath = EscapeStringForJSX(data.folder_url); - return runEvalScript("render('" + escapedPath +"')") + return runEvalScript("render('" + escapedPath +"', " + data.comp_id + ")") .then(function(result){ log.warn("render: " + result); return result; diff --git a/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx b/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx index 91df433908..c72b423af8 100644 --- a/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx +++ b/openpype/hosts/aftereffects/api/extension/jsx/hostscript.jsx @@ -395,25 +395,52 @@ function saveAs(path){ app.project.save(fp = new File(path)); } -function getRenderInfo(){ +function getRenderInfo(comp_id){ /*** Get info from render queue. Currently pulls only file name to parse extension and if it is sequence in Python **/ - try{ - var render_item = app.project.renderQueue.item(1); - if (render_item.status == RQItemStatus.DONE){ - render_item.duplicate(); // create new, cannot change status if DONE - render_item.remove(); // remove existing to limit duplications - render_item = app.project.renderQueue.item(1); - } + var item = app.project.itemByID(comp_id); + if (!item){ + return _prepareError("Composition with '" + comp_id + "' wasn't found! Recreate publishable instance(s)") + } - render_item.render = true; // always set render queue to render - var item = render_item.outputModule(1); + var comp_name = item.name; + try{ + var comp_id_count = 0; + for (i = 1; i <= app.project.renderQueue.numItems; ++i){ + var render_item = app.project.renderQueue.item(i); + if (render_item.comp.id != comp_id){ + continue; + } + comp_id_count += 1; + + if (render_item.status == RQItemStatus.DONE){ + var new_item = render_item.duplicate(); // create new, cannot change status if DONE + render_item.remove(); // remove existing to limit duplications + render_item = new_item; + } + + render_item.render = true; // always set render queue to render + var item = render_item.outputModule(1); + } } catch (error) { return _prepareError("There is no render queue, create one"); } + + if (comp_id_count > 1){ + return _prepareError("There cannot be more items in Render Queue for '" + comp_name + "'!") + } + + if (comp_id_count == 0){ + return _prepareError("There is no item in Render Queue for '" + comp_name + "'! Add composition to Render Queue.") + } + + if (render_item.numOutputModules !=1){ + return _prepareError("There must be just 1 Output Module in Render Queue for '" + comp_name + "'! Keep only correct one.") + } + var file_url = item.file.toString(); return JSON.stringify({ @@ -689,30 +716,42 @@ function isFileSequence (item){ return false; } -function render(target_folder){ +function render(target_folder, comp_id){ var out_dir = new Folder(target_folder); var out_dir = out_dir.fsName; for (i = 1; i <= app.project.renderQueue.numItems; ++i){ var render_item = app.project.renderQueue.item(i); - var om1 = app.project.renderQueue.item(i).outputModule(1); - var file_name = File.decode( om1.file.name ).replace('℗', ''); // Name contains special character, space? + var composition = render_item.comp; + if (composition.id == comp_id){ + if (render_item.status == RQItemStatus.DONE){ + var new_item = render_item.duplicate(); + render_item.remove(); + render_item = new_item; + } + + render_item.render = true; + + var om1 = app.project.renderQueue.item(i).outputModule(1); + var file_name = File.decode( om1.file.name ).replace('℗', ''); // Name contains special character, space? + + var omItem1_settable_str = app.project.renderQueue.item(i).outputModule(1).getSettings( GetSettingsFormat.STRING_SETTABLE ); + + var targetFolder = new Folder(target_folder); + if (!targetFolder.exists) { + targetFolder.create(); + } + + om1.file = new File(targetFolder.fsName + '/' + file_name); + }else{ + if (render_item.status != RQItemStatus.DONE){ + render_item.render = false; + } + } - var omItem1_settable_str = app.project.renderQueue.item(i).outputModule(1).getSettings( GetSettingsFormat.STRING_SETTABLE ); - - if (render_item.status == RQItemStatus.DONE){ - render_item.duplicate(); - render_item.remove(); - continue; - } - - var targetFolder = new Folder(target_folder); - if (!targetFolder.exists) { - targetFolder.create(); - } - - om1.file = new File(targetFolder.fsName + '/' + file_name); } + app.beginSuppressDialogs(); app.project.renderQueue.render(); + app.endSuppressDialogs(false); } function close(){ @@ -730,3 +769,6 @@ function _prepareSingleValue(value){ function _prepareError(error_msg){ return JSON.stringify({"error": error_msg}) } + +// render("c:/projects/test", 2); +getRenderInfo(1); \ No newline at end of file diff --git a/openpype/hosts/aftereffects/api/ws_stub.py b/openpype/hosts/aftereffects/api/ws_stub.py index 8719a8f46e..32125a7d99 100644 --- a/openpype/hosts/aftereffects/api/ws_stub.py +++ b/openpype/hosts/aftereffects/api/ws_stub.py @@ -418,14 +418,15 @@ class AfterEffectsServerStub(): return self._handle_return(res) - def get_render_info(self): + def get_render_info(self, comp_id): """ Get render queue info for render purposes Returns: (AEItem): with 'file_name' field """ res = self.websocketserver.call(self.client.call - ('AfterEffects.get_render_info')) + ('AfterEffects.get_render_info', + comp_id=comp_id)) records = self._to_records(self._handle_return(res)) if records: @@ -522,7 +523,7 @@ class AfterEffectsServerStub(): if records: return records.pop() - def render(self, folder_url): + def render(self, folder_url, comp_id): """ Render all renderqueueitem to 'folder_url' Args: @@ -531,7 +532,8 @@ class AfterEffectsServerStub(): """ res = self.websocketserver.call(self.client.call ('AfterEffects.render', - folder_url=folder_url)) + folder_url=folder_url, + comp_id=comp_id)) return self._handle_return(res) def get_extension_version(self): diff --git a/openpype/hosts/aftereffects/plugins/publish/collect_render.py b/openpype/hosts/aftereffects/plugins/publish/collect_render.py index d444ead6dc..2b37c1f101 100644 --- a/openpype/hosts/aftereffects/plugins/publish/collect_render.py +++ b/openpype/hosts/aftereffects/plugins/publish/collect_render.py @@ -64,14 +64,13 @@ class CollectAERender(publish.AbstractCollectRender): if family not in ["render", "renderLocal"]: # legacy continue - item_id = inst.data["members"][0] + comp_id = int(inst.data["members"][0]) - work_area_info = CollectAERender.get_stub().get_work_area( - int(item_id)) + work_area_info = CollectAERender.get_stub().get_work_area(comp_id) if not work_area_info: self.log.warning("Orphaned instance, deleting metadata") - inst_id = inst.get("instance_id") or item_id + inst_id = inst.get("instance_id") or str(comp_id) CollectAERender.get_stub().remove_instance(inst_id) continue @@ -84,7 +83,7 @@ class CollectAERender(publish.AbstractCollectRender): task_name = inst.data.get("task") # legacy - render_q = CollectAERender.get_stub().get_render_info() + render_q = CollectAERender.get_stub().get_render_info(comp_id) if not render_q: raise ValueError("No file extension set in Render Queue") @@ -118,13 +117,13 @@ class CollectAERender(publish.AbstractCollectRender): file_name=render_q.file_name ) - comp = compositions_by_id.get(int(item_id)) + comp = compositions_by_id.get(comp_id) if not comp: raise ValueError("There is no composition for item {}". - format(item_id)) + format(comp_id)) instance.outputDir = self._get_output_dir(instance) instance.comp_name = comp.name - instance.comp_id = item_id + instance.comp_id = comp_id is_local = "renderLocal" in inst.data["family"] # legacy if inst.data.get("creator_attributes"): diff --git a/openpype/hosts/aftereffects/plugins/publish/extract_local_render.py b/openpype/hosts/aftereffects/plugins/publish/extract_local_render.py index dc65cee61d..f2ae91c341 100644 --- a/openpype/hosts/aftereffects/plugins/publish/extract_local_render.py +++ b/openpype/hosts/aftereffects/plugins/publish/extract_local_render.py @@ -24,22 +24,28 @@ class ExtractLocalRender(publish.Extractor): self.log.info("staging_dir::{}".format(staging_dir)) # pull file name from Render Queue Output module - render_q = stub.get_render_info() - stub.render(staging_dir) + comp_id = instance.data['comp_id'] + render_q = stub.get_render_info(comp_id) # re queue render item if not render_q: raise ValueError("No file extension set in Render Queue") + + stub.render(staging_dir, comp_id) + _, ext = os.path.splitext(os.path.basename(render_q.file_name)) ext = ext[1:] first_file_path = None files = [] - self.log.info("files::{}".format(os.listdir(staging_dir))) for file_name in os.listdir(staging_dir): files.append(file_name) if first_file_path is None: first_file_path = os.path.join(staging_dir, file_name) + self.log.debug("files::{}".format(os.listdir(staging_dir))) + if not files: + raise ValueError("Nothing rendered!") + resulting_files = files if len(files) == 1: resulting_files = files[0]