mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Flag Outdated containers
- on startup as message box appears, and outdated containers are coloured red. - on publish the "Validate Containers" errors. - loaded image containers are coloured green.
This commit is contained in:
parent
ae4518159b
commit
85a298e4f5
3 changed files with 217 additions and 32 deletions
|
|
@ -1,8 +1,9 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
from avalon import api, harmony
|
||||
from avalon import api, io, harmony
|
||||
from avalon.vendor import Qt
|
||||
import avalon.tools.sceneinventory
|
||||
import pyblish.api
|
||||
from pype import lib
|
||||
|
||||
|
|
@ -92,6 +93,101 @@ def ensure_scene_settings():
|
|||
set_scene_settings(valid_settings)
|
||||
|
||||
|
||||
def check_inventory():
|
||||
if not lib.any_outdated():
|
||||
return
|
||||
|
||||
host = avalon.api.registered_host()
|
||||
outdated_containers = []
|
||||
for container in host.ls():
|
||||
representation = container['representation']
|
||||
representation_doc = io.find_one(
|
||||
{
|
||||
"_id": io.ObjectId(representation),
|
||||
"type": "representation"
|
||||
},
|
||||
projection={"parent": True}
|
||||
)
|
||||
if representation_doc and not lib.is_latest(representation_doc):
|
||||
outdated_containers.append(container)
|
||||
|
||||
# Colour nodes.
|
||||
func = """function func(args){
|
||||
for( var i =0; i <= args[0].length - 1; ++i)
|
||||
{
|
||||
var red_color = new ColorRGBA(255, 0, 0, 255);
|
||||
node.setColor(args[0][i], red_color);
|
||||
}
|
||||
}
|
||||
func
|
||||
"""
|
||||
outdated_nodes = [x["node"] for x in outdated_containers]
|
||||
harmony.send({"function": func, "args": [outdated_nodes]})
|
||||
|
||||
# Warn about outdated containers.
|
||||
print("Starting new QApplication..")
|
||||
app = Qt.QtWidgets.QApplication(sys.argv)
|
||||
|
||||
message_box = Qt.QtWidgets.QMessageBox()
|
||||
message_box.setIcon(Qt.QtWidgets.QMessageBox.Warning)
|
||||
msg = "There are outdated containers in the scene."
|
||||
message_box.setText(msg)
|
||||
message_box.exec_()
|
||||
|
||||
# Garbage collect QApplication.
|
||||
del app
|
||||
|
||||
|
||||
def application_launch():
|
||||
ensure_scene_settings()
|
||||
check_inventory()
|
||||
|
||||
|
||||
def export_template(backdrops, nodes, filepath):
|
||||
func = """function func(args)
|
||||
{
|
||||
// Add an extra node just so a new group can be created.
|
||||
var temp_node = node.add("Top", "temp_note", "NOTE", 0, 0, 0);
|
||||
var template_group = node.createGroup(temp_node, "temp_group");
|
||||
node.deleteNode( template_group + "/temp_note" );
|
||||
|
||||
// This will make Node View to focus on the new group.
|
||||
selection.clearSelection();
|
||||
selection.addNodeToSelection(template_group);
|
||||
Action.perform("onActionEnterGroup()", "Node View");
|
||||
|
||||
// Recreate backdrops in group.
|
||||
for (var i = 0 ; i < args[0].length; i++)
|
||||
{
|
||||
Backdrop.addBackdrop(template_group, args[0][i]);
|
||||
};
|
||||
|
||||
// Copy-paste the selected nodes into the new group.
|
||||
var drag_object = copyPaste.copy(args[1], 1, frame.numberOf, "");
|
||||
copyPaste.pasteNewNodes(drag_object, template_group, "");
|
||||
|
||||
// Select all nodes within group and export as template.
|
||||
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);
|
||||
}
|
||||
func
|
||||
"""
|
||||
harmony.send({
|
||||
"function": func,
|
||||
"args": [
|
||||
backdrops,
|
||||
nodes,
|
||||
os.path.basename(filepath),
|
||||
os.path.dirname(filepath)
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
def install():
|
||||
print("Installing Pype config...")
|
||||
|
||||
|
|
@ -116,7 +212,7 @@ def install():
|
|||
"instanceToggled", on_pyblish_instance_toggled
|
||||
)
|
||||
|
||||
api.on("application.launched", ensure_scene_settings)
|
||||
api.on("application.launched", application_launch)
|
||||
|
||||
|
||||
def on_pyblish_instance_toggled(instance, old_value, new_value):
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class ValidateContainers(pyblish.api.ContextPlugin):
|
|||
|
||||
label = "Validate Containers"
|
||||
order = pyblish.api.ValidatorOrder
|
||||
hosts = ["maya", "houdini", "nuke"]
|
||||
hosts = ["maya", "houdini", "nuke", "harmony"]
|
||||
optional = True
|
||||
actions = [ShowInventory]
|
||||
|
||||
|
|
|
|||
|
|
@ -98,33 +98,63 @@ function import_files(args)
|
|||
transparencyModeAttr.setValue(SGITransparencyMode);
|
||||
if (extension == "psd")
|
||||
transparencyModeAttr.setValue(FlatPSDTransparencyMode);
|
||||
if (extension == "jpg")
|
||||
transparencyModeAttr.setValue(LayeredPSDTransparencyMode);
|
||||
|
||||
node.linkAttr(read, "DRAWING.ELEMENT", uniqueColumnName);
|
||||
|
||||
// Create a drawing for each file.
|
||||
for( var i =0; i <= files.length - 1; ++i)
|
||||
if (files.length == 1)
|
||||
{
|
||||
timing = start_frame + i
|
||||
// Create a drawing drawing, 'true' indicate that the file exists.
|
||||
Drawing.create(elemId, timing, true);
|
||||
Drawing.create(elemId, 1, true);
|
||||
// Get the actual path, in tmp folder.
|
||||
var drawingFilePath = Drawing.filename(elemId, timing.toString());
|
||||
copyFile( files[i], drawingFilePath );
|
||||
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());
|
||||
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 = """function replace_files(args)
|
||||
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);
|
||||
|
|
@ -133,20 +163,62 @@ replace_files = """function replace_files(args)
|
|||
column.deleteDrawingAt(_column, parseInt(timings[i]));
|
||||
}
|
||||
|
||||
// Create new drawings.
|
||||
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(node.getElementId(_node), timing, true);
|
||||
// Get the actual path, in tmp folder.
|
||||
var drawingFilePath = Drawing.filename(
|
||||
node.getElementId(_node), timing.toString()
|
||||
);
|
||||
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 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
|
||||
"""
|
||||
|
|
@ -156,8 +228,8 @@ class ImageSequenceLoader(api.Loader):
|
|||
"""Load images
|
||||
Stores the imported asset in a container named after the asset.
|
||||
"""
|
||||
families = ["shot", "render"]
|
||||
representations = ["jpeg", "png"]
|
||||
families = ["shot", "render", "image"]
|
||||
representations = ["jpeg", "png", "jpg"]
|
||||
|
||||
def load(self, context, name=None, namespace=None, data=None):
|
||||
|
||||
|
|
@ -165,9 +237,18 @@ class ImageSequenceLoader(api.Loader):
|
|||
os.listdir(os.path.dirname(self.fname))
|
||||
)
|
||||
files = []
|
||||
for f in list(collections[0]):
|
||||
if collections:
|
||||
for f in list(collections[0]):
|
||||
files.append(
|
||||
os.path.join(
|
||||
os.path.dirname(self.fname), f
|
||||
).replace("\\", "/")
|
||||
)
|
||||
else:
|
||||
files.append(
|
||||
os.path.join(os.path.dirname(self.fname), f).replace("\\", "/")
|
||||
os.path.join(
|
||||
os.path.dirname(self.fname), remainder[0]
|
||||
).replace("\\", "/")
|
||||
)
|
||||
|
||||
read_node = harmony.send(
|
||||
|
|
@ -190,15 +271,23 @@ class ImageSequenceLoader(api.Loader):
|
|||
def update(self, container, representation):
|
||||
node = container.pop("node")
|
||||
|
||||
path = api.get_representation_path(representation)
|
||||
collections, remainder = clique.assemble(
|
||||
os.listdir(
|
||||
os.path.dirname(api.get_representation_path(representation))
|
||||
)
|
||||
os.listdir(os.path.dirname(path))
|
||||
)
|
||||
files = []
|
||||
for f in list(collections[0]):
|
||||
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(self.fname), f).replace("\\", "/")
|
||||
os.path.join(
|
||||
os.path.dirname(path), remainder[0]
|
||||
).replace("\\", "/")
|
||||
)
|
||||
|
||||
harmony.send(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue