diff --git a/pype/hosts/harmony/js/.eslintrc.json b/pype/hosts/harmony/js/.eslintrc.json index ffbcae87f4..16e7a6c95e 100644 --- a/pype/hosts/harmony/js/.eslintrc.json +++ b/pype/hosts/harmony/js/.eslintrc.json @@ -1,7 +1,6 @@ { "env": { - "browser": true, - "es2021": true + "browser": true }, "extends": "eslint:recommended", "parserOptions": { @@ -26,6 +25,7 @@ ] }, "globals": { + "$": "readonly", "Action": "readonly", "Backdrop": "readonly", "Button": "readonly", diff --git a/pype/hosts/harmony/js/PypeHarmony.js b/pype/hosts/harmony/js/PypeHarmony.js index 740796feef..20dc1cc95e 100644 --- a/pype/hosts/harmony/js/PypeHarmony.js +++ b/pype/hosts/harmony/js/PypeHarmony.js @@ -11,9 +11,9 @@ * @property {Object} Publish Namespace for Publish plugins JS code. */ var PypeHarmony = { - Loaders: {}, - Creators: {}, - Publish: {} + Loaders: {}, + Creators: {}, + Publish: {} }; @@ -23,7 +23,7 @@ var PypeHarmony = { * @param {string} message Argument containing message. */ PypeHarmony.message = function(message) { - MessageBox.information(message); + MessageBox.information(message); }; @@ -33,29 +33,29 @@ PypeHarmony.message = function(message) { * @param {obj} settings Scene settings. */ PypeHarmony.setSceneSettings = function(settings) { - if (settings['fps']) { - scene.setFrameRate(settings['fps']); - } - - if (settings['frameStart'] && settings['frameEnd']) { - var duration = settings['frameEnd'] - settings['frameStart'] + 1; - - if (frame.numberOf() > duration) { - frame.remove(duration, frame.numberOf() - duration); + if (settings['fps']) { + scene.setFrameRate(settings['fps']); } - if (frame.numberOf() < duration) { - frame.insert(duration, duration - frame.numberOf()); - } + if (settings['frameStart'] && settings['frameEnd']) { + var duration = settings['frameEnd'] - settings['frameStart'] + 1; - scene.setStartFrame(1); - scene.setStopFrame(duration); - } - if (settings['resolutionWidth'] && settings['resolutionHeight']) { - scene.setDefaultResolution( - settings['resolutionWidth'], settings['resolutionHeight'], 41.112 - ); - } + if (frame.numberOf() > duration) { + frame.remove(duration, frame.numberOf() - duration); + } + + if (frame.numberOf() < duration) { + frame.insert(duration, duration - frame.numberOf()); + } + + scene.setStartFrame(1); + scene.setStopFrame(duration); + } + if (settings['resolutionWidth'] && settings['resolutionHeight']) { + scene.setDefaultResolution( + settings['resolutionWidth'], settings['resolutionHeight'], 41.112 + ); + } }; @@ -66,10 +66,10 @@ PypeHarmony.setSceneSettings = function(settings) { * @param {array} rgba array of RGBA components of color. */ PypeHarmony.setColor = function(nodes, rgba) { - for (var i =0; i <= nodes.length - 1; ++i) { - var color = PypeHarmony.color(rgba); - node.setColor(nodes[i], color); - } + for (var i =0; i <= nodes.length - 1; ++i) { + var color = PypeHarmony.color(rgba); + node.setColor(nodes[i], color); + } }; @@ -84,35 +84,35 @@ PypeHarmony.setColor = function(nodes, rgba) { * */ PypeHarmony.exportTemplate = function(args) { - var tempNode = node.add('Top', 'temp_note', 'NOTE', 0, 0, 0); - var templateGroup = node.createGroup(tempNode, 'temp_group'); - node.deleteNode( templateGroup + '/temp_note' ); + var tempNode = node.add('Top', 'temp_note', 'NOTE', 0, 0, 0); + var templateGroup = node.createGroup(tempNode, 'temp_group'); + node.deleteNode( templateGroup + '/temp_note' ); - selection.clearSelection(); - for (var f = 0; f < args[1].length; f++) { - selection.addNodeToSelection(args[1][f]); - } + selection.clearSelection(); + for (var f = 0; f < args[1].length; f++) { + selection.addNodeToSelection(args[1][f]); + } - Action.perform('copy()', 'Node View'); + Action.perform('copy()', 'Node View'); - selection.clearSelection(); - selection.addNodeToSelection(template_group); - Action.perform('onActionEnterGroup()', 'Node View'); - Action.perform('paste()', 'Node View'); + selection.clearSelection(); + selection.addNodeToSelection(templateGroup); + Action.perform('onActionEnterGroup()', 'Node View'); + Action.perform('paste()', 'Node View'); - // Recreate backdrops in group. - for (var i = 0; i < args[0].length; i++) { - MessageLog.trace(args[0][i]); - Backdrop.addBackdrop(template_group, args[0][i]); - }; + // Recreate backdrops in group. + for (var i = 0; i < args[0].length; i++) { + MessageLog.trace(args[0][i]); + Backdrop.addBackdrop(templateGroup, args[0][i]); + } - Action.perform('selectAll()', 'Node View' ); - copyPaste.createTemplateFromSelection(args[2], args[3]); + Action.perform('selectAll()', 'Node View' ); + copyPaste.createTemplateFromSelection(args[2], args[3]); - // Unfocus the group in Node view, delete all nodes and backdrops - // created during the process. - Action.perform('onActionUpToParent()', 'Node View'); - node.deleteNode(template_group, true, true); + // Unfocus the group in Node view, delete all nodes and backdrops + // created during the process. + Action.perform('onActionUpToParent()', 'Node View'); + node.deleteNode(templateGroup, true, true); }; @@ -122,7 +122,7 @@ PypeHarmony.exportTemplate = function(args) { * @param {array} args Instance name and value. */ PypeHarmony.toggleInstance = function(args) { - node.setEnable(args[0], args[1]); + node.setEnable(args[0], args[1]); }; @@ -132,7 +132,7 @@ PypeHarmony.toggleInstance = function(args) { * @param {string} _node Node name. */ PypeHarmony.deleteNode = function(_node) { - node.deleteNode(_node, true, true); + node.deleteNode(_node, true, true); }; @@ -143,9 +143,9 @@ PypeHarmony.deleteNode = function(_node) { * @param {string} dst Destination file name. */ PypeHarmony.copyFile = function(src, dst) { - var srcFile = new PermanentFile(src); - var dstFile = new PermanentFile(dst); - srcFile.copy(dstFile); + var srcFile = new PermanentFile(src); + var dstFile = new PermanentFile(dst); + srcFile.copy(dstFile); }; @@ -156,5 +156,5 @@ PypeHarmony.copyFile = function(src, dst) { * @return {ColorRGBA} ColorRGBA Harmony class. */ PypeHarmony.color = function(rgba) { - return new ColorRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); + return new ColorRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); }; diff --git a/pype/hosts/harmony/js/README.md b/pype/hosts/harmony/js/README.md new file mode 100644 index 0000000000..ca610e49f5 --- /dev/null +++ b/pype/hosts/harmony/js/README.md @@ -0,0 +1,15 @@ +## Pype - ToonBoom Harmony integration + +### Development + +#### Setting up ESLint as linter for javasript code + +You nee [node.js](https://nodejs.org/en/) installed. All you need to do then +is to run: + +```sh +npm intall +``` +in **js** directory. This will install eslint and all requirements locally. + +In [Atom](https://atom.io/) it is enough to install [linter-eslint](https://atom.io/packages/lintecr-eslint) and set global *npm* prefix in its settings. diff --git a/pype/hosts/harmony/js/loaders/ImageSequenceLoader.js b/pype/hosts/harmony/js/loaders/ImageSequenceLoader.js index 090a401344..b888b0bd74 100644 --- a/pype/hosts/harmony/js/loaders/ImageSequenceLoader.js +++ b/pype/hosts/harmony/js/loaders/ImageSequenceLoader.js @@ -1,3 +1,4 @@ +/* global PypeHarmony:writable, include */ // *************************************************************************** // * ImageSequenceLoader * // *************************************************************************** @@ -5,8 +6,8 @@ // check if PypeHarmony is defined and if not, load it. if (typeof PypeHarmony !== 'undefined') { - var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS'); - include(PYPE_HARMONY_JS + '/pype_harmony.js'); + var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS'); + include(PYPE_HARMONY_JS + '/pype_harmony.js'); } @@ -14,12 +15,12 @@ if (typeof PypeHarmony !== 'undefined') { * @namespace * @classdesc Image Sequence loader JS code. */ -ImageSequenceLoader = function() { - this.PNGTransparencyMode = 0; // Premultiplied wih Black - this.TGATransparencyMode = 0; // Premultiplied wih Black - this.SGITransparencyMode = 0; // Premultiplied wih Black - this.LayeredPSDTransparencyMode = 1; // Straight - this.FlatPSDTransparencyMode = 2; // Premultiplied wih White +var ImageSequenceLoader = function() { + this.PNGTransparencyMode = 0; // Premultiplied wih Black + this.TGATransparencyMode = 0; // Premultiplied wih Black + this.SGITransparencyMode = 0; // Premultiplied wih Black + this.LayeredPSDTransparencyMode = 1; // Straight + this.FlatPSDTransparencyMode = 2; // Premultiplied wih White }; @@ -30,18 +31,18 @@ ImageSequenceLoader = function() { * @return {string} Unique column name. */ ImageSequenceLoader.prototype.getUniqueColumnName = function(columnPrefix) { - var suffix = 0; - // finds if unique name for a column - var columnName = columnPrefix; - while (suffix < 2000) { - if (!column.type(columnName)) { - break; - } + var suffix = 0; + // finds if unique name for a column + var columnName = columnPrefix; + while (suffix < 2000) { + if (!column.type(columnName)) { + break; + } - suffix = suffix + 1; - columnName = columnPrefix + '_' + suffix; - } - return columnName; + suffix = suffix + 1; + columnName = columnPrefix + '_' + suffix; + } + return columnName; }; @@ -62,128 +63,129 @@ ImageSequenceLoader.prototype.getUniqueColumnName = function(columnPrefix) { * ]; */ ImageSequenceLoader.prototype.importFiles = function(args) { - var doc = $.scn; - var files = args[0]; - var asset = args[1]; - var subset = args[2]; - var startFrame = args[3]; - var groupId = args[4]; - var vectorFormat = null; - var extension = null; - var filename = files[0]; - var pos = filename.lastIndexOf('.'); - if (pos < 0) { - return null; - } - - // Get the current group - nodeViewWidget = $.app.getWidgetByName('Node View'); - if (!nodeViewWidget) { - $.alert('You must have a Node View open!', 'No Node View!', 'OK!'); - return; - } - - nodeViewWidget.setFocus(); - var nodeView = view.currentView(); - var currentGroup = null; - if (!nodeView) { - currentGroup = doc.root; - } else { - currentGroup = doc.$node(view.group(nodeView)); - } - // Get a unique iterative name for the container read node - var num = 0; - var name = ''; - do { - name = asset + '_' + (num++) + '_' + subset; - } while (current_group.getNodeByName(name) != 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 = this.getUniqueColumnName(name); - column.add(uniqueColumnName, 'DRAWING'); - column.setElementIdOfDrawing(uniqueColumnName, elemId); - var read = node.add(currentGroup, 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(this.PNGTransparencyMode); - } - if (extension === 'tga') { - transparencyModeAttr.setValue(this.TGATransparencyMode); - } - if (extension === 'sgi') { - transparencyModeAttr.setValue(this.SGITransparencyMode); - } - if (extension === 'psd') { - transparencyModeAttr.setValue(this.FlatPSDTransparencyMode); - } - if (extension === 'jpg') { - transparencyModeAttr.setValue(this.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'); - PypeHarmony.copyFile(files[0], drawingFilePath); - // Expose the image for the entire frame range. - for (var i =0; i <= frame.numberOf() - 1; ++i) { - timing = startFrame + i; - column.setEntry(uniqueColumnName, 1, timing, '1'); + var doc = $.scn; + var files = args[0]; + var asset = args[1]; + var subset = args[2]; + var startFrame = args[3]; + var groupId = args[4]; + var vectorFormat = null; + var extension = null; + var filename = files[0]; + var pos = filename.lastIndexOf('.'); + if (pos < 0) { + return null; } - } else { - // Create a drawing for each file. - for (var i =0; i <= files.length - 1; ++i) { - timing = startFrame + 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()); - PypeHarmony.copyFile(files[i], drawingFilePath); - column.setEntry(uniqueColumnName, 1, timing, timing.toString()); - } - } - var greenColor = new ColorRGBA(0, 255, 0, 255); - node.setColor(read, greenColor); - // Add uuid to attribute of the container read node - node.createDynamicAttr(read, 'STRING', 'uuid', 'uuid', false); - node.setTextAttr(read, 'uuid', 1.0, groupId); - return read; + // Get the current group + var nodeViewWidget = $.app.getWidgetByName('Node View'); + if (!nodeViewWidget) { + $.alert('You must have a Node View open!', 'No Node View!', 'OK!'); + return; + } + + nodeViewWidget.setFocus(); + var nodeView = view.currentView(); + var currentGroup = null; + if (!nodeView) { + currentGroup = doc.root; + } else { + currentGroup = doc.$node(view.group(nodeView)); + } + // Get a unique iterative name for the container read node + var num = 0; + var name = ''; + do { + name = asset + '_' + (num++) + '_' + subset; + } while (currentGroup.getNodeByName(name) != 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 = this.getUniqueColumnName(name); + column.add(uniqueColumnName, 'DRAWING'); + column.setElementIdOfDrawing(uniqueColumnName, elemId); + var read = node.add(currentGroup, 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(this.PNGTransparencyMode); + } + if (extension === 'tga') { + transparencyModeAttr.setValue(this.TGATransparencyMode); + } + if (extension === 'sgi') { + transparencyModeAttr.setValue(this.SGITransparencyMode); + } + if (extension === 'psd') { + transparencyModeAttr.setValue(this.FlatPSDTransparencyMode); + } + if (extension === 'jpg') { + transparencyModeAttr.setValue(this.LayeredPSDTransparencyMode); + } + + var drawingFilePath; + 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. + drawingFilePath = Drawing.filename(elemId, '1'); + PypeHarmony.copyFile(files[0], drawingFilePath); + // Expose the image for the entire frame range. + for (var i =0; i <= frame.numberOf() - 1; ++i) { + var timing = startFrame + i; + column.setEntry(uniqueColumnName, 1, timing, '1'); + } + } else { + // Create a drawing for each file. + for (var j =0; j <= files.length - 1; ++j) { + timing = startFrame + j; + // Create a drawing drawing, 'true' indicate that the file exists. + Drawing.create(elemId, timing, true); + // Get the actual path, in tmp folder. + drawingFilePath = Drawing.filename(elemId, timing.toString()); + PypeHarmony.copyFile(files[j], drawingFilePath); + column.setEntry(uniqueColumnName, 1, timing, timing.toString()); + } + } + var greenColor = new ColorRGBA(0, 255, 0, 255); + node.setColor(read, greenColor); + + // Add uuid to attribute of the container read node + node.createDynamicAttr(read, 'STRING', 'uuid', 'uuid', false); + node.setTextAttr(read, 'uuid', 1.0, groupId); + return read; }; @@ -202,74 +204,75 @@ ImageSequenceLoader.prototype.importFiles = function(args) { * ]; */ ImageSequenceLoader.prototype.replaceFiles = function(args) { - var files = args[0]; - MessageLog.trace(files); - MessageLog.trace(files.length); - var _node = args[1]; - var startFrame = 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(this.PNGTransparencyMode); - } - if (extension === 'tga') { - transparencyModeAttr.setValue(this.TGATransparencyMode); - } - if (extension === 'sgi') { - transparencyModeAttr.setValue(this.SGITransparencyMode); - } - if (extension == 'psd') { - transparencyModeAttr.setValue(this.FlatPSDTransparencyMode); - } - if (extension === 'jpg') { - transparencyModeAttr.setValue(this.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'); - PypeHarmony.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 = startFrame + i; - column.setEntry(_column, 1, timing, '1'); + var files = args[0]; + MessageLog.trace(files); + MessageLog.trace(files.length); + var _node = args[1]; + var startFrame = 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])); } - } else { - // Create a drawing for each file. - for (var i =0; i <= files.length - 1; ++i) { - timing = startFrame + 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()); - PypeHarmony.copyFile( files[i], drawingFilePath ); - column.setEntry(_column, 1, timing, timing.toString()); + var filename = files[0]; + var pos = filename.lastIndexOf('.'); + if (pos < 0) { + return null; } - } - var greenColor = new ColorRGBA(0, 255, 0, 255); - node.setColor(_node, greenColor); + 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(this.PNGTransparencyMode); + } + if (extension === 'tga') { + transparencyModeAttr.setValue(this.TGATransparencyMode); + } + if (extension === 'sgi') { + transparencyModeAttr.setValue(this.SGITransparencyMode); + } + if (extension == 'psd') { + transparencyModeAttr.setValue(this.FlatPSDTransparencyMode); + } + if (extension === 'jpg') { + transparencyModeAttr.setValue(this.LayeredPSDTransparencyMode); + } + + var drawingFilePath; + 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. + drawingFilePath = Drawing.filename(elemId, '1'); + PypeHarmony.copyFile(files[0], drawingFilePath); + MessageLog.trace(files[0]); + MessageLog.trace(drawingFilePath); + // Expose the image for the entire frame range. + for (var k =0; k <= frame.numberOf() - 1; ++k) { + var timing = startFrame + k; + column.setEntry(_column, 1, timing, '1'); + } + } else { + // Create a drawing for each file. + for (var l =0; l <= files.length - 1; ++l) { + timing = startFrame + l; + // Create a drawing drawing, 'true' indicate that the file exists. + Drawing.create(elemId, timing, true); + // Get the actual path, in tmp folder. + drawingFilePath = Drawing.filename(elemId, timing.toString()); + PypeHarmony.copyFile( files[l], drawingFilePath ); + column.setEntry(_column, 1, timing, timing.toString()); + } + } + var greenColor = new ColorRGBA(0, 255, 0, 255); + node.setColor(_node, greenColor); }; // add self to Pype Loaders diff --git a/pype/hosts/harmony/js/loaders/TemplateLoader.js b/pype/hosts/harmony/js/loaders/TemplateLoader.js index f9fe24e187..05498cd0ea 100644 --- a/pype/hosts/harmony/js/loaders/TemplateLoader.js +++ b/pype/hosts/harmony/js/loaders/TemplateLoader.js @@ -1,12 +1,13 @@ +/* global PypeHarmony:writable, include */ // *************************************************************************** -// * TemplateLoader * +// * TemplateLoader * // *************************************************************************** // check if PypeHarmony is defined and if not, load it. if (typeof PypeHarmony !== 'undefined') { - var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS'); - include(PYPE_HARMONY_JS + '/pype_harmony.js'); + var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS'); + include(PYPE_HARMONY_JS + '/pype_harmony.js'); } @@ -14,7 +15,7 @@ if (typeof PypeHarmony !== 'undefined') { * @namespace * @classdesc Image Sequence loader JS code. */ -TemplateLoader = function() {}; +var TemplateLoader = function() {}; /** @@ -33,46 +34,47 @@ TemplateLoader = function() {}; * ]; */ TemplateLoader.prototype.loadContainer = function(args) { - var doc = $.scn; - var templatePath = args[0]; - var assetName = args[1]; - var subset = args[2]; - var groupId = args[3]; + var doc = $.scn; + var templatePath = args[0]; + var assetName = args[1]; + var subset = args[2]; + var groupId = args[3]; - // Get the current group - nodeViewWidget = $.app.getWidgetByName('Node View'); - if (!nodeViewWidget) { - $.alert('You must have a Node View open!', 'No Node View!', 'OK!'); - return; - } + // Get the current group + var nodeViewWidget = $.app.getWidgetByName('Node View'); + if (!nodeViewWidget) { + $.alert('You must have a Node View open!', 'No Node View!', 'OK!'); + return; + } - nodeViewWidget.setFocus(); - nodeView = view.currentView(); - if (!nodeView) { - currentGroup = doc.root; - } else { - currentGroup = doc.$node(view.group(nodeView)); - } + nodeViewWidget.setFocus(); + var currentGroup; + var nodeView = view.currentView(); + if (!nodeView) { + currentGroup = doc.root; + } else { + currentGroup = doc.$node(view.group(nodeView)); + } - // Get a unique iterative name for the container group - var num = 0; - var containerGroupName = ''; - do { - containerGroupName = assetName + '_' + (num++) + '_' + subset; - } while (currentGroup.getNodeByName(containerGroupName) != null); + // Get a unique iterative name for the container group + var num = 0; + var containerGroupName = ''; + do { + containerGroupName = assetName + '_' + (num++) + '_' + subset; + } while (currentGroup.getNodeByName(containerGroupName) != null); - // import the template - var tplNodes = currentGroup.importTemplate(templatePath); - MessageLog.trace(tplNodes); - // Create the container group - var groupNode = currentGroup.addGroup( - containerGroupName, false, false, tplNodes); + // import the template + var tplNodes = currentGroup.importTemplate(templatePath); + MessageLog.trace(tplNodes); + // Create the container group + var groupNode = currentGroup.addGroup( + containerGroupName, false, false, tplNodes); - // Add uuid to attribute of the container group - node.createDynamicAttr(groupNode, 'STRING', 'uuid', 'uuid', false); - node.setTextAttr(groupNode, 'uuid', 1.0, groupId); + // Add uuid to attribute of the container group + node.createDynamicAttr(groupNode, 'STRING', 'uuid', 'uuid', false); + node.setTextAttr(groupNode, 'uuid', 1.0, groupId); - return String(groupNode); + return String(groupNode); }; @@ -89,86 +91,86 @@ TemplateLoader.prototype.loadContainer = function(args) { */ TemplateLoader.prototype.replaceNode = function( dstNodePath, srcNodePath, renameSrc, cloneSrc, linkColumns) { - var doc = $.scn; - var srcNode = doc.$node(srcNodePath); - var dstNode = doc.$node(dstNodePath); - // var dstNodeName = dstNode.name; - var replacementNode = srcNode; - // var dstGroup = dstNode.group; - $.beginUndo(); - if (cloneSrc) { - var replacementNode = doc.$node( - Y.nodeTools.copy_paste_node( - srcNodePath, dstNode.name + '_CLONE', dstNode.group.path)); - } else { - if (replacement_node.group.path != src_node.group.path) { - replacement_node.moveToGroup(dst_group); - } - } - var inLinks = dstNode.getInLinks(); - for (l in inLinks) { - if (Object.prototype.hasOwnProperty.call(inLinks, l)) { - var link = inLinks[l]; - inPort = Number(link.inPort); - outPort = Number(link.outPort); - outNode = link.outNode; - success = replacement_node.linkInNode(outNode, inPort, outPort); - if (success) { - log('Successfully connected ' + outNode + ' : ' + - outPort + ' -> ' + replacementNode + ' : ' + inPort); - } else { - log('Failed to connect ' + outNode + ' : ' + - outPort + ' -> ' + replacementNode + ' : ' + inPort); - } - } - } - - var outLinks = dstNode.getOutLinks(); - for (l in outLinks) { - if (Object.prototype.hasOwnProperty.call(outLinks, l)) { - var link = out_links[l]; - inPort = Number(link.inPort); - outPort = Number(link.outPort); - inNode = link.inNode; - // first we must disconnect the port from the node being - // replaced to this links inNode port - inNode.unlinkInPort(inPort); - success = replacement_node.linkOutNode(in_node, out_port, in_port); - if (success) { - log('Successfully connected ' + inNode + ' : ' + - inPort + ' <- ' + replacementNode + ' : ' + outPort); - } else { - if (in_node.type == 'MultiLayerWrite') { - log('Attempting standard api to connect the nodes...'); - success = node.link( - replacementNode, outPort, inNode, - inPort, node.numberOfInputPorts(inNode) + 1); - if (success) { - log('Successfully connected ' + inNode + ' : ' + - inPort + ' <- ' + replacementNode + ' : ' + outPort); - } + var doc = $.scn; + var srcNode = doc.$node(srcNodePath); + var dstNode = doc.$node(dstNodePath); + // var dstNodeName = dstNode.name; + var replacementNode = srcNode; + // var dstGroup = dstNode.group; + $.beginUndo(); + if (cloneSrc) { + replacementNode = doc.$node( + $.nodeTools.copy_paste_node( + srcNodePath, dstNode.name + '_CLONE', dstNode.group.path)); + } else { + if (replacementNode.group.path != srcNode.group.path) { + replacementNode.moveToGroup(dstNode); + } + } + var inLinks = dstNode.getInLinks(); + for (var l in inLinks) { + if (Object.prototype.hasOwnProperty.call(inLinks, l)) { + var link = inLinks[l]; + var inPort = Number(link.inPort); + var outPort = Number(link.outPort); + var outNode = link.outNode; + var success = replacementNode.linkInNode(outNode, inPort, outPort); + if (success) { + $.log('Successfully connected ' + outNode + ' : ' + + outPort + ' -> ' + replacementNode + ' : ' + inPort); + } else { + $.alert('Failed to connect ' + outNode + ' : ' + + outPort + ' -> ' + replacementNode + ' : ' + inPort); + } + } + } + + var outLinks = dstNode.getOutLinks(); + for (l in outLinks) { + if (Object.prototype.hasOwnProperty.call(outLinks, l)) { + link = outLinks[l]; + inPort = Number(link.inPort); + outPort = Number(link.outPort); + var inNode = link.inNode; + // first we must disconnect the port from the node being + // replaced to this links inNode port + inNode.unlinkInPort(inPort); + success = replacementNode.linkOutNode(inNode, outPort, inPort); + if (success) { + $.log('Successfully connected ' + inNode + ' : ' + + inPort + ' <- ' + replacementNode + ' : ' + outPort); + } else { + if (inNode.type == 'MultiLayerWrite') { + $.log('Attempting standard api to connect the nodes...'); + success = node.link( + replacementNode, outPort, inNode, + inPort, node.numberOfInputPorts(inNode) + 1); + if (success) { + $.log('Successfully connected ' + inNode + ' : ' + + inPort + ' <- ' + replacementNode + ' : ' + outPort); + } + } + } + if (!success) { + $.alert('Failed to connect ' + inNode + ' : ' + + inPort + ' <- ' + replacementNode + ' : ' + outPort); + return false; + } } - } - if (!success) { - log('Failed to connect ' + inNode + ' : ' + - inPort + ' <- ' + replacementNode + ' : ' + outPort); - return false; - } } - } }; TemplateLoader.prototype.askForColumnsUpdate = function() { - // Ask user if they want to also update columns and - // linked attributes here - return ($.confirm( - 'Would you like to update in place and reconnect all \n' + + // Ask user if they want to also update columns and + // linked attributes here + return ($.confirm( + 'Would you like to update in place and reconnect all \n' + 'ins/outs, attributes, and columns?', - 'Update & Replace?\n' + + 'Update & Replace?\n' + 'If you choose No, the version will only be loaded.', - 'Yes', - 'No')); + 'Yes', + 'No')); }; // add self to Pype Loaders diff --git a/pype/hosts/harmony/js/loaders/package.json b/pype/hosts/harmony/js/package.json similarity index 82% rename from pype/hosts/harmony/js/loaders/package.json rename to pype/hosts/harmony/js/package.json index b4b89c8050..4415b14393 100644 --- a/pype/hosts/harmony/js/loaders/package.json +++ b/pype/hosts/harmony/js/package.json @@ -1,19 +1,18 @@ { "name": "pype-harmony", "version": "1.0.0", - "description": "Pype Harmony Host integration", - "main": "PypeHarmony.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, + "description": "Avalon Harmony Host integration", "keywords": [ "Pype", "Avalon", "Harmony", "pipeline" ], - "author": "", "license": "MIT", + "main": "PypeHarmony.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, "devDependencies": { "eslint": "^7.11.0" } diff --git a/pype/hosts/harmony/js/publish/CollectPalettes.js b/pype/hosts/harmony/js/publish/CollectPalettes.js new file mode 100644 index 0000000000..b2ed9aa761 --- /dev/null +++ b/pype/hosts/harmony/js/publish/CollectPalettes.js @@ -0,0 +1,33 @@ +/* global PypeHarmony:writable, include */ +// *************************************************************************** +// * CollectPalettes * +// *************************************************************************** + + +// check if PypeHarmony is defined and if not, load it. +if (typeof PypeHarmony !== 'undefined') { + var PYPE_HARMONY_JS = System.getenv('PYPE_HARMONY_JS'); + include(PYPE_HARMONY_JS + '/pype_harmony.js'); +} + + +/** + * @namespace + * @classdesc Image Sequence loader JS code. + */ +var CollectPalettes = function() {}; + +CollectPalettes.prototype.getPalettes = function() { + 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; +}; + +// add self to Pype Loaders +PypeHarmony.Publish.CollectPalettes = new CollectPalettes(); diff --git a/pype/plugins/harmony/load/load_palette.py b/pype/plugins/harmony/load/load_palette.py index ff85fdca5a..fd3f99b06d 100644 --- a/pype/plugins/harmony/load/load_palette.py +++ b/pype/plugins/harmony/load/load_palette.py @@ -7,7 +7,7 @@ from avalon import api, harmony class ImportPaletteLoader(api.Loader): """Import palettes.""" - families = ["harmony.palette"] + families = ["palette"] representations = ["plt"] label = "Import Palette" diff --git a/pype/plugins/harmony/publish/collect_instances.py b/pype/plugins/harmony/publish/collect_instances.py index aab89482ab..21aa00e972 100644 --- a/pype/plugins/harmony/publish/collect_instances.py +++ b/pype/plugins/harmony/publish/collect_instances.py @@ -57,6 +57,11 @@ class CollectInstances(pyblish.api.ContextPlugin): )["result"] instance.data["families"] = self.families_mapping[data["family"]] + # If set in plugin, pair the scene Version in ftrack with + # thumbnails and review media. + if (self.pair_media and instance.data["family"] == "scene"): + context.data["scene_instance"] = instance + # Produce diagnostic message for any graphical # user interface interested in visualising it. self.log.info( diff --git a/pype/plugins/harmony/publish/collect_palettes.py b/pype/plugins/harmony/publish/collect_palettes.py index dc573c381f..e5bd33cff8 100644 --- a/pype/plugins/harmony/publish/collect_palettes.py +++ b/pype/plugins/harmony/publish/collect_palettes.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- +"""Collect palettes from Harmony.""" import os import json @@ -13,23 +15,12 @@ class CollectPalettes(pyblish.api.ContextPlugin): hosts = ["harmony"] def process(self, context): - sig = harmony.signature() - func = """function %s() - { - var palette_list = PaletteObjectManager.getScenePaletteList(); - - var palettes = {}; - for(var i=0; i < palette_list.numPalettes; ++i) + """Collector entry point.""" + self_name = self.__class__.__name__ + palettes = harmony.send( { - var palette = palette_list.getPaletteByIndex(i); - palettes[palette.getName()] = palette.id; - } - - return palettes; - } - %s - """ % (sig, sig) - palettes = harmony.send({"function": func})["result"] + "function": f"PypeHarmony.Loaders.{self_name}.getPalettes", + })["result"] for name, id in palettes.items(): instance = context.create_instance(name) diff --git a/pype/plugins/harmony/publish/collect_workfile.py b/pype/plugins/harmony/publish/collect_workfile.py index 7781eb0774..0be10c3fdf 100644 --- a/pype/plugins/harmony/publish/collect_workfile.py +++ b/pype/plugins/harmony/publish/collect_workfile.py @@ -12,8 +12,9 @@ class CollectWorkfile(pyblish.api.ContextPlugin): def process(self, context): family = "workfile" task = os.getenv("AVALON_TASK", None) - subset = family + task.capitalize() + sanitized_task_name = task[0].upper() + task[1:] basename = os.path.basename(context.data["currentFile"]) + subset = "{}{}".format(family, sanitized_task_name) # Create instance instance = context.create_instance(subset)