From 279b221e33d8a1cca99736326570c978fb9b3f39 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Sun, 28 Jun 2020 15:40:00 +0100 Subject: [PATCH 1/4] Initial working version for palettes. --- pype/hosts/harmony/__init__.py | 5 +- pype/plugins/global/publish/integrate_new.py | 3 +- .../harmony/load/load_imagesequence.py | 22 +++++ pype/plugins/harmony/load/load_palette.py | 93 +++++++++++++++++++ .../harmony/publish/collect_palettes.py | 45 +++++++++ .../harmony/publish/extract_palette.py | 34 +++++++ 6 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 pype/plugins/harmony/load/load_palette.py create mode 100644 pype/plugins/harmony/publish/collect_palettes.py create mode 100644 pype/plugins/harmony/publish/extract_palette.py diff --git a/pype/hosts/harmony/__init__.py b/pype/hosts/harmony/__init__.py index 628397e777..4dc06cdf84 100644 --- a/pype/hosts/harmony/__init__.py +++ b/pype/hosts/harmony/__init__.py @@ -121,7 +121,10 @@ def check_inventory(): } func """ - outdated_nodes = [x["node"] for x in outdated_containers] + outdated_nodes = [] + for container in outdated_containers: + if container["loader"] == "ImageSequenceLoader": + outdated_nodes.append(container["name"]) harmony.send({"function": func, "args": [outdated_nodes]}) # Warn about outdated containers. diff --git a/pype/plugins/global/publish/integrate_new.py b/pype/plugins/global/publish/integrate_new.py index 040ed9cd67..a33db2bcec 100644 --- a/pype/plugins/global/publish/integrate_new.py +++ b/pype/plugins/global/publish/integrate_new.py @@ -83,6 +83,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "textures", "action", "harmony.template", + "harmony.palette", "editorial" ] exclude_families = ["clip"] @@ -605,7 +606,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "type": "subset", "name": subset_name, "data": { - "families": instance.data.get('families') + "families": instance.data.get("families", []) }, "parent": asset["_id"] }).inserted_id diff --git a/pype/plugins/harmony/load/load_imagesequence.py b/pype/plugins/harmony/load/load_imagesequence.py index b56dba03d4..615188572e 100644 --- a/pype/plugins/harmony/load/load_imagesequence.py +++ b/pype/plugins/harmony/load/load_imagesequence.py @@ -3,6 +3,7 @@ import os import clique from avalon import api, harmony +import pype.lib copy_files = """function copyFile(srcFilename, dstFilename) { @@ -297,6 +298,27 @@ class ImageSequenceLoader(api.Loader): } ) + # Colour node. + func = """function func(args){ + for( var i =0; i <= args[0].length - 1; ++i) + { + var red_color = new ColorRGBA(255, 0, 0, 255); + var green_color = new ColorRGBA(0, 255, 0, 255); + if (args[1] == "red"){ + node.setColor(args[0], red_color); + } + if (args[1] == "green"){ + node.setColor(args[0], green_color); + } + } + } + func + """ + if pype.lib.is_latest(representation): + harmony.send({"function": func, "args": [node, "green"]}) + else: + harmony.send({"function": func, "args": [node, "red"]}) + harmony.imprint( node, {"representation": str(representation["_id"])} ) diff --git a/pype/plugins/harmony/load/load_palette.py b/pype/plugins/harmony/load/load_palette.py new file mode 100644 index 0000000000..cfb88ac841 --- /dev/null +++ b/pype/plugins/harmony/load/load_palette.py @@ -0,0 +1,93 @@ +import os +import shutil +import uuid + +from bson.objectid import ObjectId + +from avalon import api, harmony + + +class ImportPaletteLoader(api.Loader): + """Import palettes.""" + + families = ["harmony.palette"] + representations = ["plt"] + label = "Import Palette" + + def load(self, context, name=None, namespace=None, data=None): + name = self.load_palette(context["representation"]) + + return harmony.containerise( + name, + namespace, + name, + context, + self.__class__.__name__ + ) + + def load_palette(self, representation): + subset_name = representation["context"]["subset"] + name = subset_name.replace("palette", "") + name += "_{}".format(uuid.uuid4()) + + # Import new palette. + scene_path = harmony.send( + {"function": "scene.currentProjectPath"} + )["result"] + src = api.get_representation_path(representation) + dst = os.path.join( + scene_path, + "palette-library", + "{}.plt".format(name) + ) + shutil.copy(src, dst) + + func = """function func(args) + { + var palette_list = PaletteObjectManager.getScenePaletteList(); + var palette = palette_list.addPaletteAtLocation( + PaletteObjectManager.Constants.Location.SCENE, 0, args[0] + ); + for(var i=0; i < palette_list.numPalettes; ++i) + { + palette_list.movePaletteUp(palette.id); + } + return palette.id; + } + func + """ + harmony.send({"function": func, "args": [name]}) + + return name + + def remove(self, container): + # Replace any palettes with same name. + func = """function func(args) + { + var pom = PaletteObjectManager; + var palette_list = pom.getScenePaletteList(); + for(var i=0; i < palette_list.numPalettes; ++i) + { + var palette = palette_list.getPaletteByIndex(i); + if(palette.getName() == args[0]) + pom.removePaletteReferencesAndDeleteOnDisk(palette.id); + } + } + func + """ + harmony.send({"function": func, "args": [container["name"]]}) + + harmony.remove(container["name"]) + + harmony.save_scene() + + def switch(self, container, representation): + self.update(container, representation) + + def update(self, container, representation): + self.remove(container) + name = self.load_palette(representation) + + container["representation"] = str(representation["_id"]) + container["name"] = name + harmony.imprint(name, container) diff --git a/pype/plugins/harmony/publish/collect_palettes.py b/pype/plugins/harmony/publish/collect_palettes.py new file mode 100644 index 0000000000..2a2c1066c0 --- /dev/null +++ b/pype/plugins/harmony/publish/collect_palettes.py @@ -0,0 +1,45 @@ +import os +import json + +import pyblish.api +from avalon import harmony + + +class CollectPalettes(pyblish.api.ContextPlugin): + """Gather palettes from scene when publishing templates.""" + + label = "Palettes" + order = pyblish.api.CollectorOrder + hosts = ["harmony"] + + def process(self, context): + func = """function func() + { + var palette_list = PaletteObjectManager.getScenePaletteList(); + + var palettes = {}; + for(var i=0; i < palette_list.numPalettes; ++i) + { + var palette = palette_list.getPaletteByIndex(i); + palettes[palette.getName()] = palette.id; + } + + return palettes; + } + func + """ + palettes = harmony.send({"function": func})["result"] + + for name, id in palettes.items(): + instance = context.create_instance(name) + instance.data.update({ + "id": id, + "family": "harmony.palette", + "asset": os.environ["AVALON_ASSET"], + "subset": "palette" + name + }) + self.log.info( + "Created instance:\n" + json.dumps( + instance.data, sort_keys=True, indent=4 + ) + ) diff --git a/pype/plugins/harmony/publish/extract_palette.py b/pype/plugins/harmony/publish/extract_palette.py new file mode 100644 index 0000000000..9bca005278 --- /dev/null +++ b/pype/plugins/harmony/publish/extract_palette.py @@ -0,0 +1,34 @@ +import os + +from avalon import harmony +import pype.api +import pype.hosts.harmony + + +class ExtractPalette(pype.api.Extractor): + """Extract palette.""" + + label = "Extract Palette" + hosts = ["harmony"] + families = ["harmony.palette"] + + def process(self, instance): + func = """function func(args) + { + var palette_list = PaletteObjectManager.getScenePaletteList(); + var palette = palette_list.getPaletteById(args[0]); + return (palette.getPath() + "/" + palette.getName() + ".plt"); + } + func + """ + palette_file = harmony.send( + {"function": func, "args": [instance.data["id"]]} + )["result"] + + representation = { + "name": "plt", + "ext": "plt", + "files": os.path.basename(palette_file), + "stagingDir": os.path.dirname(palette_file) + } + instance.data["representations"] = [representation] From 1a15dc78ce8dc41a8bd886e03bab29b91b73cbfe Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Sun, 28 Jun 2020 16:23:05 +0100 Subject: [PATCH 2/4] Convert imageseuqnece loader --- pype/hosts/harmony/__init__.py | 4 +++- pype/plugins/harmony/load/load_imagesequence.py | 12 +++++++----- pype/plugins/harmony/load/load_palette.py | 2 -- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pype/hosts/harmony/__init__.py b/pype/hosts/harmony/__init__.py index 4dc06cdf84..3345c3134a 100644 --- a/pype/hosts/harmony/__init__.py +++ b/pype/hosts/harmony/__init__.py @@ -124,7 +124,9 @@ def check_inventory(): outdated_nodes = [] for container in outdated_containers: if container["loader"] == "ImageSequenceLoader": - outdated_nodes.append(container["name"]) + outdated_nodes.append( + harmony.find_node_by_name(container["name"]), "READ" + ) harmony.send({"function": func, "args": [outdated_nodes]}) # Warn about outdated containers. diff --git a/pype/plugins/harmony/load/load_imagesequence.py b/pype/plugins/harmony/load/load_imagesequence.py index 615188572e..f81018d0fb 100644 --- a/pype/plugins/harmony/load/load_imagesequence.py +++ b/pype/plugins/harmony/load/load_imagesequence.py @@ -1,4 +1,5 @@ import os +import uuid import clique @@ -252,15 +253,15 @@ class ImageSequenceLoader(api.Loader): ).replace("\\", "/") ) + name = context["subset"]["name"] + name += "_{}".format(uuid.uuid4()) read_node = harmony.send( { "function": copy_files + import_files, - "args": ["Top", files, context["subset"]["name"], 1] + "args": ["Top", files, name, 1] } )["result"] - self[:] = [read_node] - return harmony.containerise( name, namespace, @@ -270,7 +271,7 @@ class ImageSequenceLoader(api.Loader): ) def update(self, container, representation): - node = container.pop("node") + node = harmony.find_node_by_name(container["name"], "READ") path = api.get_representation_path(representation) collections, remainder = clique.assemble( @@ -324,7 +325,8 @@ class ImageSequenceLoader(api.Loader): ) def remove(self, container): - node = container.pop("node") + node = harmony.find_node_by_name(container["name"], "READ") + func = """function deleteNode(_node) { node.deleteNode(_node, true, true); diff --git a/pype/plugins/harmony/load/load_palette.py b/pype/plugins/harmony/load/load_palette.py index cfb88ac841..44aaf76aa5 100644 --- a/pype/plugins/harmony/load/load_palette.py +++ b/pype/plugins/harmony/load/load_palette.py @@ -2,8 +2,6 @@ import os import shutil import uuid -from bson.objectid import ObjectId - from avalon import api, harmony From 4ccc052f83dae3b346a7e0a0c8ccca05c4d9a9bd Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Sun, 28 Jun 2020 17:16:17 +0100 Subject: [PATCH 3/4] Fix check inventory --- pype/hosts/harmony/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/hosts/harmony/__init__.py b/pype/hosts/harmony/__init__.py index 3345c3134a..3cae695852 100644 --- a/pype/hosts/harmony/__init__.py +++ b/pype/hosts/harmony/__init__.py @@ -125,7 +125,7 @@ def check_inventory(): for container in outdated_containers: if container["loader"] == "ImageSequenceLoader": outdated_nodes.append( - harmony.find_node_by_name(container["name"]), "READ" + harmony.find_node_by_name(container["name"], "READ") ) harmony.send({"function": func, "args": [outdated_nodes]}) From af8bcfafaadfa6139aec6a2b5f49284875714d13 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Wed, 1 Jul 2020 10:33:03 +0100 Subject: [PATCH 4/4] Only overwrite the .plt file and warn users about visual changes. --- pype/plugins/harmony/load/load_palette.py | 47 ++++++----------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/pype/plugins/harmony/load/load_palette.py b/pype/plugins/harmony/load/load_palette.py index 44aaf76aa5..001758d5a8 100644 --- a/pype/plugins/harmony/load/load_palette.py +++ b/pype/plugins/harmony/load/load_palette.py @@ -1,8 +1,8 @@ import os import shutil -import uuid from avalon import api, harmony +from avalon.vendor import Qt class ImportPaletteLoader(api.Loader): @@ -26,9 +26,8 @@ class ImportPaletteLoader(api.Loader): def load_palette(self, representation): subset_name = representation["context"]["subset"] name = subset_name.replace("palette", "") - name += "_{}".format(uuid.uuid4()) - # Import new palette. + # Overwrite palette on disk. scene_path = harmony.send( {"function": "scene.currentProjectPath"} )["result"] @@ -40,45 +39,21 @@ class ImportPaletteLoader(api.Loader): ) shutil.copy(src, dst) - func = """function func(args) - { - var palette_list = PaletteObjectManager.getScenePaletteList(); - var palette = palette_list.addPaletteAtLocation( - PaletteObjectManager.Constants.Location.SCENE, 0, args[0] - ); - for(var i=0; i < palette_list.numPalettes; ++i) - { - palette_list.movePaletteUp(palette.id); - } - return palette.id; - } - func - """ - harmony.send({"function": func, "args": [name]}) + harmony.save_scene() + + # Dont allow instances with the same name. + message_box = Qt.QtWidgets.QMessageBox() + message_box.setIcon(Qt.QtWidgets.QMessageBox.Warning) + msg = "Updated {}.".format(subset_name) + msg += " You need to reload the scene to see the changes." + message_box.setText(msg) + message_box.exec_() return name def remove(self, container): - # Replace any palettes with same name. - func = """function func(args) - { - var pom = PaletteObjectManager; - var palette_list = pom.getScenePaletteList(); - for(var i=0; i < palette_list.numPalettes; ++i) - { - var palette = palette_list.getPaletteByIndex(i); - if(palette.getName() == args[0]) - pom.removePaletteReferencesAndDeleteOnDisk(palette.id); - } - } - func - """ - harmony.send({"function": func, "args": [container["name"]]}) - harmony.remove(container["name"]) - harmony.save_scene() - def switch(self, container, representation): self.update(container, representation)