From 18100497a68eb6a52bab3fe58a86d6e718f79615 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 12 Aug 2020 18:53:25 +0200 Subject: [PATCH 1/3] prep for background loading --- pype/plugins/harmony/load/load_background.py | 348 ++++++++++++++++++ .../harmony/load/load_imagesequence00.py | 23 ++ 2 files changed, 371 insertions(+) create mode 100644 pype/plugins/harmony/load/load_background.py create mode 100644 pype/plugins/harmony/load/load_imagesequence00.py diff --git a/pype/plugins/harmony/load/load_background.py b/pype/plugins/harmony/load/load_background.py new file mode 100644 index 0000000000..1e305678e6 --- /dev/null +++ b/pype/plugins/harmony/load/load_background.py @@ -0,0 +1,348 @@ +import os +import uuid + +import clique + +from avalon import api, harmony +import pype.lib +import json + +copy_files = """function copyFile(srcFilename, dstFilename) +{ + var srcFile = new PermanentFile(srcFilename); + var dstFile = new PermanentFile(dstFilename); + srcFile.copy(dstFile); +} +""" + +import_files = """var PNGTransparencyMode = 0; //Premultiplied wih Black +var TGATransparencyMode = 0; //Premultiplied wih Black +var SGITransparencyMode = 0; //Premultiplied wih Black +var LayeredPSDTransparencyMode = 1; //Straight +var FlatPSDTransparencyMode = 2; //Premultiplied wih White + +function getUniqueColumnName( column_prefix ) +{ + var suffix = 0; + // finds if unique name for a column + var column_name = column_prefix; + while(suffix < 2000) + { + if(!column.type(column_name)) + break; + + suffix = suffix + 1; + column_name = column_prefix + "_" + suffix; + } + return column_name; +} + +function import_files(args) +{ + var root = args[0]; + var files = args[1]; + var name = args[2]; + var start_frame = args[3]; + + var vectorFormat = null; + var extension = null; + var filename = files[0]; + + var pos = filename.lastIndexOf("."); + if( pos < 0 ) + return null; + + extension = filename.substr(pos+1).toLowerCase(); + + if(extension == "jpeg") + extension = "jpg"; + if(extension == "tvg") + { + vectorFormat = "TVG" + extension ="SCAN"; // element.add() will use this. + } + + var elemId = element.add( + name, + "BW", + scene.numberOfUnitsZ(), + extension.toUpperCase(), + vectorFormat + ); + if (elemId == -1) + { + // hum, unknown file type most likely -- let's skip it. + return null; // no read to add. + } + + var uniqueColumnName = getUniqueColumnName(name); + column.add(uniqueColumnName , "DRAWING"); + column.setElementIdOfDrawing(uniqueColumnName, elemId); + + var read = node.add(root, name, "READ", 0, 0, 0); + var transparencyAttr = node.getAttr( + read, frame.current(), "READ_TRANSPARENCY" + ); + var opacityAttr = node.getAttr(read, frame.current(), "OPACITY"); + transparencyAttr.setValue(true); + opacityAttr.setValue(true); + + var alignmentAttr = node.getAttr(read, frame.current(), "ALIGNMENT_RULE"); + alignmentAttr.setValue("ASIS"); + + var transparencyModeAttr = node.getAttr( + read, frame.current(), "applyMatteToColor" + ); + if (extension == "png") + transparencyModeAttr.setValue(PNGTransparencyMode); + if (extension == "tga") + transparencyModeAttr.setValue(TGATransparencyMode); + if (extension == "sgi") + transparencyModeAttr.setValue(SGITransparencyMode); + if (extension == "psd") + transparencyModeAttr.setValue(FlatPSDTransparencyMode); + if (extension == "jpg") + transparencyModeAttr.setValue(LayeredPSDTransparencyMode); + + node.linkAttr(read, "DRAWING.ELEMENT", uniqueColumnName); + + if (files.length == 1) + { + // Create a drawing drawing, 'true' indicate that the file exists. + Drawing.create(elemId, 1, true); + // Get the actual path, in tmp folder. + var drawingFilePath = Drawing.filename(elemId, "1"); + copyFile(files[0], drawingFilePath); + // Expose the image for the entire frame range. + for( var i =0; i <= frame.numberOf() - 1; ++i) + { + timing = start_frame + i + column.setEntry(uniqueColumnName, 1, timing, "1"); + } + } else { + // Create a drawing for each file. + for( var i =0; i <= files.length - 1; ++i) + { + timing = start_frame + i + // Create a drawing drawing, 'true' indicate that the file exists. + Drawing.create(elemId, timing, true); + // Get the actual path, in tmp folder. + var drawingFilePath = Drawing.filename(elemId, timing.toString()); + copyFile( files[i], drawingFilePath ); + + column.setEntry(uniqueColumnName, 1, timing, timing.toString()); + } + } + + var green_color = new ColorRGBA(0, 255, 0, 255); + node.setColor(read, green_color); + + return read; +} +import_files +""" + +replace_files = """var PNGTransparencyMode = 0; //Premultiplied wih Black +var TGATransparencyMode = 0; //Premultiplied wih Black +var SGITransparencyMode = 0; //Premultiplied wih Black +var LayeredPSDTransparencyMode = 1; //Straight +var FlatPSDTransparencyMode = 2; //Premultiplied wih White + +function replace_files(args) +{ + var files = args[0]; + MessageLog.trace(files); + MessageLog.trace(files.length); + var _node = args[1]; + var start_frame = args[2]; + + var _column = node.linkedColumn(_node, "DRAWING.ELEMENT"); + var elemId = column.getElementIdOfDrawing(_column); + + // Delete existing drawings. + var timings = column.getDrawingTimings(_column); + for( var i =0; i <= timings.length - 1; ++i) + { + column.deleteDrawingAt(_column, parseInt(timings[i])); + } + + + var filename = files[0]; + var pos = filename.lastIndexOf("."); + if( pos < 0 ) + return null; + var extension = filename.substr(pos+1).toLowerCase(); + + if(extension == "jpeg") + extension = "jpg"; + + var transparencyModeAttr = node.getAttr( + _node, frame.current(), "applyMatteToColor" + ); + if (extension == "png") + transparencyModeAttr.setValue(PNGTransparencyMode); + if (extension == "tga") + transparencyModeAttr.setValue(TGATransparencyMode); + if (extension == "sgi") + transparencyModeAttr.setValue(SGITransparencyMode); + if (extension == "psd") + transparencyModeAttr.setValue(FlatPSDTransparencyMode); + if (extension == "jpg") + transparencyModeAttr.setValue(LayeredPSDTransparencyMode); + + if (files.length == 1) + { + // Create a drawing drawing, 'true' indicate that the file exists. + Drawing.create(elemId, 1, true); + // Get the actual path, in tmp folder. + var drawingFilePath = Drawing.filename(elemId, "1"); + copyFile(files[0], drawingFilePath); + MessageLog.trace(files[0]); + MessageLog.trace(drawingFilePath); + // Expose the image for the entire frame range. + for( var i =0; i <= frame.numberOf() - 1; ++i) + { + timing = start_frame + i + column.setEntry(_column, 1, timing, "1"); + } + } else { + // Create a drawing for each file. + for( var i =0; i <= files.length - 1; ++i) + { + timing = start_frame + i + // Create a drawing drawing, 'true' indicate that the file exists. + Drawing.create(elemId, timing, true); + // Get the actual path, in tmp folder. + var drawingFilePath = Drawing.filename(elemId, timing.toString()); + copyFile( files[i], drawingFilePath ); + + column.setEntry(_column, 1, timing, timing.toString()); + } + } + + var green_color = new ColorRGBA(0, 255, 0, 255); + node.setColor(_node, green_color); +} +replace_files +""" + + +class BackgroundLoader(api.Loader): + """Load images + Stores the imported asset in a container named after the asset. + """ + families = ["background", "image"] + representations = ["json"] + + def load(self, context, name=None, namespace=None, data=None): + + with open(file) as json_file: + data = json.load(json_file) + + layers = list() + + for child in data['children']: + if child.get("filename"): + print(child["filename"]) + layers.append(child["filename"]) + else: + for layer in child['children']: + if layer.get("filename"): + print(layer["filename"]) + layers.append(layer["filename"]) + + print(layers) + + bg_folder = os.path.dirname(self.fname).replace("\\", "/") + + subset_name = context["subset"]["name"] + subset_name += "_{}".format(uuid.uuid4()) + + for layer in sorted(sorted): + file_to_import = os.path.join(bg_folder, layer) + + read_node = harmony.send( + { + "function": copy_files + import_files, + "args": ["Top", file_to_import, layer, 1] + } + )["result"] + + + return harmony.containerise( + subset_name, + namespace, + subset_name, + context, + self.__class__.__name__ + ) + + def update(self, container, representation): + node = harmony.find_node_by_name(container["name"], "READ") + + path = api.get_representation_path(representation) + collections, remainder = clique.assemble( + os.listdir(os.path.dirname(path)) + ) + files = [] + if collections: + for f in list(collections[0]): + files.append( + os.path.join( + os.path.dirname(path), f + ).replace("\\", "/") + ) + else: + files.append( + os.path.join( + os.path.dirname(path), remainder[0] + ).replace("\\", "/") + ) + + harmony.send( + { + "function": copy_files + replace_files, + "args": [files, node, 1] + } + ) + + # 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"])} + ) + + def remove(self, container): + node = harmony.find_node_by_name(container["name"], "READ") + + func = """function deleteNode(_node) + { + node.deleteNode(_node, true, true); + } + deleteNode + """ + harmony.send( + {"function": func, "args": [node]} + ) + + def switch(self, container, representation): + self.update(container, representation) diff --git a/pype/plugins/harmony/load/load_imagesequence00.py b/pype/plugins/harmony/load/load_imagesequence00.py new file mode 100644 index 0000000000..82a33678ce --- /dev/null +++ b/pype/plugins/harmony/load/load_imagesequence00.py @@ -0,0 +1,23 @@ +import os + +import json + +file = r"G:\My Drive\pypeRoot\milo_s01\episodes\ml102\ml102_shots\ml102_sh0850\publish\image\imageForComp\v001\ml_ml102_sh0850_imageForComp_v001.json" + +with open(file) as json_file: + data = json.load(json_file) + +layers = list() + +for child in data['children']: + if child.get("filename"): + print(child["filename"]) + layers.append(child["filename"]) + else: + for layer in child['children']: + if layer.get("filename"): + print(layer["filename"]) + layers.append(layer["filename"]) + +for layer in sorted(layers): + print(layer) From 94b5b86caec850c90e362ffe20585ed3fee503fa Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 12 Aug 2020 22:03:13 +0200 Subject: [PATCH 2/3] .x/feature/maya_image_plane_containerize: --- pype/plugins/harmony/load/load_background.py | 151 +++++++++++------- .../harmony/load/load_imagesequence.py | 4 +- 2 files changed, 92 insertions(+), 63 deletions(-) diff --git a/pype/plugins/harmony/load/load_background.py b/pype/plugins/harmony/load/load_background.py index 1e305678e6..f8de1e1145 100644 --- a/pype/plugins/harmony/load/load_background.py +++ b/pype/plugins/harmony/load/load_background.py @@ -15,7 +15,7 @@ copy_files = """function copyFile(srcFilename, dstFilename) } """ -import_files = """var PNGTransparencyMode = 0; //Premultiplied wih Black +import_files = """var PNGTransparencyMode = 1; //Premultiplied wih Black var TGATransparencyMode = 0; //Premultiplied wih Black var SGITransparencyMode = 0; //Premultiplied wih Black var LayeredPSDTransparencyMode = 1; //Straight @@ -142,7 +142,7 @@ function import_files(args) import_files """ -replace_files = """var PNGTransparencyMode = 0; //Premultiplied wih Black +replace_files = """var PNGTransparencyMode = 1; //Premultiplied wih Black var TGATransparencyMode = 0; //Premultiplied wih Black var SGITransparencyMode = 0; //Premultiplied wih Black var LayeredPSDTransparencyMode = 1; //Straight @@ -231,12 +231,12 @@ class BackgroundLoader(api.Loader): """Load images Stores the imported asset in a container named after the asset. """ - families = ["background", "image"] + families = ["background"] representations = ["json"] def load(self, context, name=None, namespace=None, data=None): - with open(file) as json_file: + with open(self.fname) as json_file: data = json.load(json_file) layers = list() @@ -252,14 +252,18 @@ class BackgroundLoader(api.Loader): layers.append(layer["filename"]) print(layers) + print(data) - bg_folder = os.path.dirname(self.fname).replace("\\", "/") + bg_folder = os.path.dirname(self.fname) subset_name = context["subset"]["name"] - subset_name += "_{}".format(uuid.uuid4()) + # read_node_name += "_{}".format(uuid.uuid4()) + container_nodes = [] - for layer in sorted(sorted): - file_to_import = os.path.join(bg_folder, layer) + for layer in sorted(layers): + file_to_import = [os.path.join(bg_folder, layer).replace("\\", "/")] + + print(f"FILE TO IMPORT: {file_to_import}") read_node = harmony.send( { @@ -267,6 +271,7 @@ class BackgroundLoader(api.Loader): "args": ["Top", file_to_import, layer, 1] } )["result"] + container_nodes.append(read_node) return harmony.containerise( @@ -274,75 +279,99 @@ class BackgroundLoader(api.Loader): namespace, subset_name, context, - self.__class__.__name__ + self.__class__.__name__, + nodes=container_nodes ) def update(self, container, representation): - node = harmony.find_node_by_name(container["name"], "READ") path = api.get_representation_path(representation) - collections, remainder = clique.assemble( - os.listdir(os.path.dirname(path)) - ) - files = [] - if collections: - for f in list(collections[0]): - files.append( - os.path.join( - os.path.dirname(path), f - ).replace("\\", "/") + + with open(path) as json_file: + data = json.load(json_file) + + layers = list() + + for child in data['children']: + if child.get("filename"): + print(child["filename"]) + layers.append(child["filename"]) + else: + for layer in child['children']: + if layer.get("filename"): + print(layer["filename"]) + layers.append(layer["filename"]) + + bg_folder = os.path.dirname(path) + + path = api.get_representation_path(representation) + + print(container) + + for layer in sorted(layers): + file_to_import = [os.path.join(bg_folder, layer).replace("\\", "/")] + print(20*"#") + print(f"FILE TO REPLACE: {file_to_import}") + print(f"LAYER: {layer}") + node = harmony.find_node_by_name(layer, "READ") + print(f"{node}") + + if node in container['nodes']: + harmony.send( + { + "function": copy_files + replace_files, + "args": [file_to_import, node, 1] + } ) - else: - files.append( - os.path.join( - os.path.dirname(path), remainder[0] - ).replace("\\", "/") - ) + else: + read_node = harmony.send( + { + "function": copy_files + import_files, + "args": ["Top", file_to_import, layer, 1] + } + )["result"] + container['nodes'].append(read_node) - harmony.send( - { - "function": copy_files + replace_files, - "args": [files, node, 1] - } - ) - # 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); + # 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"]}) + 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"])} + container['name'], {"representation": str(representation["_id"]), + "nodes": container['nodes']} ) def remove(self, container): - node = harmony.find_node_by_name(container["name"], "READ") + for node in container.get("nodes"): - func = """function deleteNode(_node) - { - node.deleteNode(_node, true, true); - } - deleteNode - """ - harmony.send( - {"function": func, "args": [node]} - ) + func = """function deleteNode(_node) + { + node.deleteNode(_node, true, true); + } + deleteNode + """ + harmony.send( + {"function": func, "args": [node]} + ) + harmony.imprint(container['name'], {}, remove=True) def switch(self, container, representation): self.update(container, representation) diff --git a/pype/plugins/harmony/load/load_imagesequence.py b/pype/plugins/harmony/load/load_imagesequence.py index f81018d0fb..0bc7c07ce5 100644 --- a/pype/plugins/harmony/load/load_imagesequence.py +++ b/pype/plugins/harmony/load/load_imagesequence.py @@ -14,7 +14,7 @@ copy_files = """function copyFile(srcFilename, dstFilename) } """ -import_files = """var PNGTransparencyMode = 0; //Premultiplied wih Black +import_files = """var PNGTransparencyMode = 1; //Premultiplied wih Black var TGATransparencyMode = 0; //Premultiplied wih Black var SGITransparencyMode = 0; //Premultiplied wih Black var LayeredPSDTransparencyMode = 1; //Straight @@ -141,7 +141,7 @@ function import_files(args) import_files """ -replace_files = """var PNGTransparencyMode = 0; //Premultiplied wih Black +replace_files = """var PNGTransparencyMode = 1; //Premultiplied wih Black var TGATransparencyMode = 0; //Premultiplied wih Black var SGITransparencyMode = 0; //Premultiplied wih Black var LayeredPSDTransparencyMode = 1; //Straight From 7cee74677dfbd66afb99673e672d02b7a7f37a87 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 12 Aug 2020 22:20:25 +0200 Subject: [PATCH 3/3] containerise all loaders --- pype/plugins/harmony/load/load_audio.py | 16 +++++++++++++ pype/plugins/harmony/load/load_background.py | 8 ------- .../harmony/load/load_imagesequence.py | 6 +++-- .../harmony/load/load_imagesequence00.py | 23 ------------------- .../harmony/load/load_template_workfile.py | 16 +++++++++++++ 5 files changed, 36 insertions(+), 33 deletions(-) delete mode 100644 pype/plugins/harmony/load/load_imagesequence00.py diff --git a/pype/plugins/harmony/load/load_audio.py b/pype/plugins/harmony/load/load_audio.py index a17af78964..694fda3247 100644 --- a/pype/plugins/harmony/load/load_audio.py +++ b/pype/plugins/harmony/load/load_audio.py @@ -40,3 +40,19 @@ class ImportAudioLoader(api.Loader): harmony.send( {"function": func, "args": [context["subset"]["name"], wav_file]} ) + + subset_name = context["subset"]["name"] + + return harmony.containerise( + subset_name, + namespace, + subset_name, + context, + self.__class__.__name__ + ) + + def update(self, container, representation): + pass + + def remove(self, container): + pass diff --git a/pype/plugins/harmony/load/load_background.py b/pype/plugins/harmony/load/load_background.py index f8de1e1145..f96fc275be 100644 --- a/pype/plugins/harmony/load/load_background.py +++ b/pype/plugins/harmony/load/load_background.py @@ -243,17 +243,12 @@ class BackgroundLoader(api.Loader): for child in data['children']: if child.get("filename"): - print(child["filename"]) layers.append(child["filename"]) else: for layer in child['children']: if layer.get("filename"): - print(layer["filename"]) layers.append(layer["filename"]) - print(layers) - print(data) - bg_folder = os.path.dirname(self.fname) subset_name = context["subset"]["name"] @@ -263,8 +258,6 @@ class BackgroundLoader(api.Loader): for layer in sorted(layers): file_to_import = [os.path.join(bg_folder, layer).replace("\\", "/")] - print(f"FILE TO IMPORT: {file_to_import}") - read_node = harmony.send( { "function": copy_files + import_files, @@ -273,7 +266,6 @@ class BackgroundLoader(api.Loader): )["result"] container_nodes.append(read_node) - return harmony.containerise( subset_name, namespace, diff --git a/pype/plugins/harmony/load/load_imagesequence.py b/pype/plugins/harmony/load/load_imagesequence.py index 0bc7c07ce5..774782b092 100644 --- a/pype/plugins/harmony/load/load_imagesequence.py +++ b/pype/plugins/harmony/load/load_imagesequence.py @@ -230,7 +230,7 @@ class ImageSequenceLoader(api.Loader): """Load images Stores the imported asset in a container named after the asset. """ - families = ["shot", "render", "image"] + families = ["shot", "render", "image", "plate"] representations = ["jpeg", "png", "jpg"] def load(self, context, name=None, namespace=None, data=None): @@ -267,7 +267,8 @@ class ImageSequenceLoader(api.Loader): namespace, read_node, context, - self.__class__.__name__ + self.__class__.__name__, + nodes=[read_node] ) def update(self, container, representation): @@ -336,6 +337,7 @@ class ImageSequenceLoader(api.Loader): harmony.send( {"function": func, "args": [node]} ) + harmony.imprint(node, {}, remove=True) def switch(self, container, representation): self.update(container, representation) diff --git a/pype/plugins/harmony/load/load_imagesequence00.py b/pype/plugins/harmony/load/load_imagesequence00.py deleted file mode 100644 index 82a33678ce..0000000000 --- a/pype/plugins/harmony/load/load_imagesequence00.py +++ /dev/null @@ -1,23 +0,0 @@ -import os - -import json - -file = r"G:\My Drive\pypeRoot\milo_s01\episodes\ml102\ml102_shots\ml102_sh0850\publish\image\imageForComp\v001\ml_ml102_sh0850_imageForComp_v001.json" - -with open(file) as json_file: - data = json.load(json_file) - -layers = list() - -for child in data['children']: - if child.get("filename"): - print(child["filename"]) - layers.append(child["filename"]) - else: - for layer in child['children']: - if layer.get("filename"): - print(layer["filename"]) - layers.append(layer["filename"]) - -for layer in sorted(layers): - print(layer) diff --git a/pype/plugins/harmony/load/load_template_workfile.py b/pype/plugins/harmony/load/load_template_workfile.py index db67f20ff7..3e79cc1903 100644 --- a/pype/plugins/harmony/load/load_template_workfile.py +++ b/pype/plugins/harmony/load/load_template_workfile.py @@ -35,6 +35,22 @@ class ImportTemplateLoader(api.Loader): shutil.rmtree(temp_dir) + subset_name = context["subset"]["name"] + + return harmony.containerise( + subset_name, + namespace, + subset_name, + context, + self.__class__.__name__ + ) + + def update(self, container, representation): + pass + + def remove(self, container): + pass + class ImportWorkfileLoader(ImportTemplateLoader): """Import workfiles."""