diff --git a/pype/plugins/global/publish/integrate_new.py b/pype/plugins/global/publish/integrate_new.py index bd908901cc..fd76b19eb9 100644 --- a/pype/plugins/global/publish/integrate_new.py +++ b/pype/plugins/global/publish/integrate_new.py @@ -81,7 +81,8 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "assembly", "fbx", "textures", - "action" + "action", + "harmony.template" ] exclude_families = ["clip"] db_representation_context_keys = [ diff --git a/pype/plugins/harmony/create/create_template.py b/pype/plugins/harmony/create/create_template.py new file mode 100644 index 0000000000..babc3fe8d7 --- /dev/null +++ b/pype/plugins/harmony/create/create_template.py @@ -0,0 +1,12 @@ +from avalon import harmony + + +class CreateTemplate(harmony.Creator): + """Composite node for publishing to templates.""" + + name = "templateDefault" + label = "Template" + family = "harmony.template" + + def __init__(self, *args, **kwargs): + super(CreateTemplate, self).__init__(*args, **kwargs) diff --git a/pype/plugins/harmony/load/load_template.py b/pype/plugins/harmony/load/load_template.py new file mode 100644 index 0000000000..0bc9706407 --- /dev/null +++ b/pype/plugins/harmony/load/load_template.py @@ -0,0 +1,48 @@ +import tempfile +import zipfile +import os +import shutil + +from avalon import api, harmony + + +class ImportTemplateLoader(api.Loader): + """Import templates.""" + + families = ["harmony.template"] + representations = ["*"] + label = "Import Template" + + def load(self, context, name=None, namespace=None, data=None): + temp_dir = tempfile.mkdtemp() + zip_file = api.get_representation_path(context["representation"]) + template_path = os.path.join(temp_dir, "temp.tpl") + with zipfile.ZipFile(zip_file, "r") as zip_ref: + zip_ref.extractall(template_path) + + func = """function func(args) + { + var template_path = args[0]; + var drag_object = copyPaste.copyFromTemplate( + template_path, 0, 0, copyPaste.getCurrentCreateOptions() + ); + copyPaste.pasteNewNodes( + drag_object, "", copyPaste.getCurrentPasteOptions() + ); + } + func + """ + + func = """function func(args) + { + var template_path = args[0]; + var drag_object = copyPaste.pasteTemplateIntoGroup( + template_path, "Top", 1 + ); + } + func + """ + + harmony.send({"function": func, "args": [template_path]}) + + shutil.rmtree(temp_dir) diff --git a/pype/plugins/harmony/publish/collect_current_file.py b/pype/plugins/harmony/publish/collect_current_file.py new file mode 100644 index 0000000000..aab66c2b62 --- /dev/null +++ b/pype/plugins/harmony/publish/collect_current_file.py @@ -0,0 +1,27 @@ +import os + +import pyblish.api +from avalon import harmony + + +class CollectCurrentFile(pyblish.api.ContextPlugin): + """Inject the current working file into context""" + + order = pyblish.api.CollectorOrder - 0.5 + label = "Current File" + hosts = ["harmony"] + + def process(self, context): + """Inject the current working file""" + func = """function func() + { + return ( + scene.currentProjectPath() + "/" + + scene.currentVersionName() + ".xstage" + ); + } + func + """ + + current_file = harmony.send({"function": func})["result"] + context.data["currentFile"] = os.path.normpath(current_file) diff --git a/pype/plugins/harmony/publish/extract_template.py b/pype/plugins/harmony/publish/extract_template.py new file mode 100644 index 0000000000..78184217dc --- /dev/null +++ b/pype/plugins/harmony/publish/extract_template.py @@ -0,0 +1,90 @@ +import os +import shutil + +import pype.api +from avalon import harmony + + +class ExtractTemplate(pype.api.Extractor): + """Extract the connected nodes to the composite instance.""" + label = "Extract Template" + hosts = ["harmony"] + families = ["harmony.template"] + + def process(self, instance): + staging_dir = self.staging_dir(instance) + + self.log.info("Outputting template to %s" % staging_dir) + + self.dependencies = [] + self.get_dependencies(instance[0]) + + func = """function func(args) + { + var nodes = args[0]; + selection.clearSelection(); + for (var i = 0 ; i < nodes.length; i++) + { + selection.addNodeToSelection(nodes[i]); + } + } + func + """ + harmony.send({"function": func, "args": [self.dependencies]}) + func = """function func(args) + { + copyPaste.createTemplateFromSelection(args[0], args[1]); + } + func + """ + harmony.send( + { + "function": func, + "args": ["{}.tpl".format(instance.name), staging_dir] + } + ) + + os.chdir(staging_dir) + shutil.make_archive( + "{}".format(instance.name), + "zip", + os.path.join(staging_dir, "{}.tpl".format(instance.name)) + ) + + representation = { + "name": "tpl", + "ext": "zip", + "files": "{}.zip".format(instance.name), + "stagingDir": staging_dir, + } + instance.data["representations"] = [representation] + + def get_dependencies(self, node): + func = """function func(args) + { + var target_node = args[0]; + var numInput = node.numberOfInputPorts(target_node); + var dependencies = []; + for (var i = 0 ; i < numInput; i++) + { + dependencies.push(node.srcNode(target_node, i)); + } + return dependencies; + } + func + """ + + current_dependencies = harmony.send( + {"function": func, "args": [node]} + )["result"] + + for dependency in current_dependencies: + if not dependency: + continue + + if dependency in self.dependencies: + continue + + self.dependencies.append(dependency) + + self.get_dependencies(dependency)