Merge pull request #2689 from pypeclub/feature/OP-2518_Webpublisher-Photoshop-publisher-to-create-a-beauty-png

Webpublisher: Photoshop create a beauty png
This commit is contained in:
Petr Kalis 2022-02-11 13:46:22 +01:00 committed by GitHub
commit e0b27e52f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 207 additions and 151 deletions

View file

@ -186,9 +186,26 @@ class PhotoshopServerStub:
Returns:
<list of PSItem>
"""
parent_ids = set([lay.id for lay in layers])
return self._get_layers_in_layers(parent_ids)
def get_layers_in_layers_ids(self, layers_ids):
"""Return all layers that belong to layers (might be groups).
Args:
layers <list of PSItem>:
Returns:
<list of PSItem>
"""
parent_ids = set(layers_ids)
return self._get_layers_in_layers(parent_ids)
def _get_layers_in_layers(self, parent_ids):
all_layers = self.get_layers()
ret = []
parent_ids = set([lay.id for lay in layers])
for layer in all_layers:
parents = set(layer.parents)

View file

@ -8,12 +8,15 @@ from openpype.lib.plugin_tools import parse_json, get_batch_asset_task_info
from openpype.hosts.photoshop import api as photoshop
class CollectRemoteInstances(pyblish.api.ContextPlugin):
class CollectColorCodedInstances(pyblish.api.ContextPlugin):
"""Creates instances for configured color code of a layer.
Used in remote publishing when artists marks publishable layers by color-
coding.
Can add group for all publishable layers to allow creation of flattened
image. (Cannot contain special background layer as it cannot be grouped!)
Identifier:
id (str): "pyblish.avalon.instance"
"""
@ -26,50 +29,38 @@ class CollectRemoteInstances(pyblish.api.ContextPlugin):
# configurable by Settings
color_code_mapping = []
# TODO check if could be set globally, probably doesn't make sense when
# flattened template cannot
subset_template_name = ""
create_flatten_image = False
# probably not possible to configure this globally
flatten_subset_template = ""
def process(self, context):
self.log.info("CollectRemoteInstances")
self.log.info("CollectColorCodedInstances")
self.log.debug("mapping:: {}".format(self.color_code_mapping))
# parse variant if used in webpublishing, comes from webpublisher batch
batch_dir = os.environ.get("OPENPYPE_PUBLISH_DATA")
task_data = None
if batch_dir and os.path.exists(batch_dir):
# TODO check if batch manifest is same as tasks manifests
task_data = parse_json(os.path.join(batch_dir,
"manifest.json"))
if not task_data:
raise ValueError(
"Cannot parse batch meta in {} folder".format(batch_dir))
variant = task_data["variant"]
existing_subset_names = self._get_existing_subset_names(context)
asset_name, task_name, variant = self._parse_batch()
stub = photoshop.stub()
layers = stub.get_layers()
existing_subset_names = []
for instance in context:
if instance.data.get('publish'):
existing_subset_names.append(instance.data.get('subset'))
asset, task_name, task_type = get_batch_asset_task_info(
task_data["context"])
if not task_name:
task_name = task_type
instance_names = []
publishable_layers = []
created_instances = []
for layer in layers:
self.log.debug("Layer:: {}".format(layer))
if layer.parents:
self.log.debug("!!! Not a top layer, skip")
continue
if not layer.visible:
self.log.debug("Not visible, skip")
continue
resolved_family, resolved_subset_template = self._resolve_mapping(
layer
)
self.log.info("resolved_family {}".format(resolved_family))
self.log.info("resolved_subset_template {}".format(
resolved_subset_template))
if not resolved_subset_template or not resolved_family:
self.log.debug("!!! Not found family or template, skip")
@ -90,24 +81,81 @@ class CollectRemoteInstances(pyblish.api.ContextPlugin):
"Subset {} already created, skipping.".format(subset))
continue
instance = context.create_instance(layer.name)
instance.append(layer)
instance.data["family"] = resolved_family
instance.data["publish"] = layer.visible
instance.data["asset"] = asset
instance.data["task"] = task_name
instance.data["subset"] = subset
instance = self._create_instance(context, layer, resolved_family,
asset_name, subset, task_name)
existing_subset_names.append(subset)
publishable_layers.append(layer)
created_instances.append(instance)
instance_names.append(layer.name)
if self.create_flatten_image and publishable_layers:
self.log.debug("create_flatten_image")
if not self.flatten_subset_template:
self.log.warning("No template for flatten image")
return
fill_pairs.pop("layer")
subset = self.flatten_subset_template.format(
**prepare_template_data(fill_pairs))
first_layer = publishable_layers[0] # dummy layer
first_layer.name = subset
family = created_instances[0].data["family"] # inherit family
instance = self._create_instance(context, first_layer,
family,
asset_name, subset, task_name)
instance.data["ids"] = [layer.id for layer in publishable_layers]
created_instances.append(instance)
for instance in created_instances:
# Produce diagnostic message for any graphical
# user interface interested in visualising it.
self.log.info("Found: \"%s\" " % instance.data["name"])
self.log.info("instance: {} ".format(instance.data))
if len(instance_names) != len(set(instance_names)):
self.log.warning("Duplicate instances found. " +
"Remove unwanted via SubsetManager")
def _get_existing_subset_names(self, context):
"""Collect manually created instances from workfile.
Shouldn't be any as Webpublisher bypass publishing via Openpype, but
might be some if workfile published through OP is reused.
"""
existing_subset_names = []
for instance in context:
if instance.data.get('publish'):
existing_subset_names.append(instance.data.get('subset'))
return existing_subset_names
def _parse_batch(self):
"""Parses asset_name, task_name, variant from batch manifest."""
batch_dir = os.environ.get("OPENPYPE_PUBLISH_DATA")
task_data = None
if batch_dir and os.path.exists(batch_dir):
task_data = parse_json(os.path.join(batch_dir,
"manifest.json"))
if not task_data:
raise ValueError(
"Cannot parse batch meta in {} folder".format(batch_dir))
variant = task_data["variant"]
asset, task_name, task_type = get_batch_asset_task_info(
task_data["context"])
if not task_name:
task_name = task_type
return asset, task_name, variant
def _create_instance(self, context, layer, family,
asset, subset, task_name):
instance = context.create_instance(layer.name)
instance.data["family"] = family
instance.data["publish"] = True
instance.data["asset"] = asset
instance.data["task"] = task_name
instance.data["subset"] = subset
instance.data["layer"] = layer
return instance
def _resolve_mapping(self, layer):
"""Matches 'layer' color code and name to mapping.
@ -147,4 +195,7 @@ class CollectRemoteInstances(pyblish.api.ContextPlugin):
if family_list:
family = family_list.pop()
self.log.debug("resolved_family {}".format(family))
self.log.debug("resolved_subset_template {}".format(
resolved_subset_template))
return family, resolved_subset_template

View file

@ -43,7 +43,7 @@ class CollectInstances(pyblish.api.ContextPlugin):
# continue
instance = context.create_instance(layer_data["subset"])
instance.append(layer)
instance.data["layer"] = layer
instance.data.update(layer_data)
instance.data["families"] = self.families_mapping[
layer_data["family"]

View file

@ -27,8 +27,13 @@ class ExtractImage(openpype.api.Extractor):
self.log.info("Extracting %s" % str(list(instance)))
with photoshop.maintained_visibility():
# Hide all other layers.
layer = instance.data.get("layer")
ids = set([layer.id])
add_ids = instance.data.pop("ids", None)
if add_ids:
ids.update(set(add_ids))
extract_ids = set([ll.id for ll in stub.
get_layers_in_layers([instance[0]])])
get_layers_in_layers_ids(ids)])
for layer in stub.get_layers():
# limit unnecessary calls to client

View file

@ -31,7 +31,7 @@ class ExtractReview(openpype.api.Extractor):
for image_instance in instance.context:
if image_instance.data["family"] != "image":
continue
layers.append(image_instance[0])
layers.append(image_instance.data.get("layer"))
# Perform extraction
output_image = "{}.jpg".format(

View file

@ -248,6 +248,8 @@ class HarmonySubmitDeadline(
secondary_pool = ""
priority = 50
chunk_size = 1000000
group = "none"
department = ""
def get_job_info(self):
job_info = DeadlineJobInfo("Harmony")
@ -264,6 +266,8 @@ class HarmonySubmitDeadline(
job_info.SecondaryPool = self.secondary_pool
job_info.ChunkSize = self.chunk_size
job_info.BatchName = os.path.basename(self._instance.data["source"])
job_info.Department = self.department
job_info.Group = self.group
keys = [
"FTRACK_API_KEY",

View file

@ -36,6 +36,9 @@
],
"celaction": [
".*"
],
"harmony": [
".*"
]
}
},

View file

@ -7,15 +7,10 @@
}
},
"publish": {
"CollectRemoteInstances": {
"color_code_mapping": [
{
"color_code": [],
"layer_name_regex": [],
"family": "image",
"subset_template_name": ""
}
]
"CollectColorCodedInstances": {
"create_flatten_image": false,
"flatten_subset_template": "",
"color_code_mapping": []
},
"ValidateContainers": {
"enabled": true,

View file

@ -71,106 +71,11 @@
}
]
},
{
"type": "dict",
"collapsible": true,
"key": "ProcessSubmittedJobOnFarm",
"label": "ProcessSubmittedJobOnFarm",
"checkbox_key": "enabled",
"is_group": true,
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
},
{
"type": "text",
"key": "deadline_department",
"label": "Deadline department"
},
{
"type": "text",
"key": "deadline_pool",
"label": "Deadline Pool"
},
{
"type": "text",
"key": "deadline_group",
"label": "Deadline Group"
},
{
"type": "number",
"key": "deadline_chunk_size",
"label": "Deadline Chunk Size"
},
{
"type": "number",
"key": "deadline_priority",
"label": "Deadline Priotity"
},
{
"type": "splitter"
},
{
"type": "text",
"key": "publishing_script",
"label": "Publishing script path"
},
{
"type": "list",
"key": "skip_integration_repre_list",
"label": "Skip integration of representation with ext",
"object_type": {
"type": "text"
}
},
{
"type": "dict",
"key": "aov_filter",
"label": "Reviewable subsets filter",
"children": [
{
"type": "list",
"key": "maya",
"label": "Maya",
"object_type": {
"type": "text"
}
},
{
"type": "list",
"key": "nuke",
"label": "Nuke",
"object_type": {
"type": "text"
}
},
{
"type": "list",
"key": "aftereffects",
"label": "After Effects",
"object_type": {
"type": "text"
}
},
{
"type": "list",
"key": "celaction",
"label": "Celaction",
"object_type": {
"type": "text"
}
}
]
}
]
},
{
"type": "dict",
"collapsible": true,
"key": "MayaSubmitDeadline",
"label": "Submit Maya job to Deadline",
"label": "Maya Submit to Deadline",
"checkbox_key": "enabled",
"children": [
{
@ -464,6 +369,72 @@
"label": "Department"
}
]
},
{
"type": "dict",
"collapsible": true,
"key": "ProcessSubmittedJobOnFarm",
"label": "ProcessSubmittedJobOnFarm",
"checkbox_key": "enabled",
"is_group": true,
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
},
{
"type": "text",
"key": "deadline_department",
"label": "Deadline department"
},
{
"type": "text",
"key": "deadline_pool",
"label": "Deadline Pool"
},
{
"type": "text",
"key": "deadline_group",
"label": "Deadline Group"
},
{
"type": "number",
"key": "deadline_chunk_size",
"label": "Deadline Chunk Size"
},
{
"type": "number",
"key": "deadline_priority",
"label": "Deadline Priotity"
},
{
"type": "splitter"
},
{
"type": "text",
"key": "publishing_script",
"label": "Publishing script path"
},
{
"type": "list",
"key": "skip_integration_repre_list",
"label": "Skip integration of representation with ext",
"object_type": {
"type": "text"
}
},
{
"type": "dict-modifiable",
"docstring": "Regular expression to filter for which subset review should be created in publish job.",
"key": "aov_filter",
"label": "Reviewable subsets filter",
"object_type": {
"type": "list",
"object_type": "text"
}
}
]
}
]
}

View file

@ -37,12 +37,22 @@
"type": "dict",
"collapsible": true,
"is_group": true,
"key": "CollectRemoteInstances",
"label": "Collect Instances for Webpublish",
"key": "CollectColorCodedInstances",
"label": "Collect Color Coded Instances",
"children": [
{
"type": "label",
"label": "Set color for publishable layers, set publishable families."
"label": "Set color for publishable layers, set its resulting family and template for subset name. Can create flatten image from published instances"
},
{
"type": "boolean",
"key": "create_flatten_image",
"label": "Create flatten image"
},
{
"type": "text",
"key": "flatten_subset_template",
"label": "Subset template for flatten image"
},
{
"type": "list",