Expanding the scope of mvLook to publish mipmapped textures too, like TDL's

generated by 3delight. During collection, we check to see if the TDL's exist
beside the original texture, and if they do they get added to the collection.

Validation of these will depend on the publish intent and whether
`expectMipMap` is True in the publish set.

If mipmaps are expected and the intent is correct, the mipmaps will be
published along with the original file, which will accelerate rendering,
since 3dl will find that TDL and use it instead of having to generate it.
This commit is contained in:
DMO 2022-05-27 17:52:33 +09:00
parent fe40624135
commit eff55dfce4
3 changed files with 141 additions and 3 deletions

View file

@ -12,3 +12,4 @@ class CreateMultiverseLook(plugin.Creator):
def __init__(self, *args, **kwargs):
super(CreateMultiverseLook, self).__init__(*args, **kwargs)
self.data["fileFormat"] = ["usda", "usd"]
self.data["expectMipMap"] = True

View file

@ -17,6 +17,9 @@ SHAPE_ATTRS = ["castsShadows",
"opposite"]
SHAPE_ATTRS = set(SHAPE_ATTRS)
COLOUR_SPACES = ['sRGB']
MIPMAP_EXTENSIONS = ['tdl']
def get_look_attrs(node):
"""Returns attributes of a node that are important for the look.
@ -103,7 +106,7 @@ def seq_to_glob(path):
"<uvtile>": "<uvtile>",
"#": "#",
"u<u>_v<v>": "<u>|<v>",
"<frame0": "<frame0\d+>", #noqa - copied from collect_look.py
"<frame0": "<frame0\d+>", # noqa - copied from collect_look.py
"<f>": "<f>"
}
@ -189,6 +192,22 @@ def get_file_node_files(node):
return []
def get_mipmap(fname):
for colour_space in COLOUR_SPACES:
for mipmap_ext in MIPMAP_EXTENSIONS:
mipmap_fname = '.'.join([fname, colour_space, mipmap_ext])
if os.path.exists(mipmap_fname):
return mipmap_fname
return None
def is_mipamp(fname):
ext = os.path.splitext(fname)[1][1:]
if ext in MIPMAP_EXTENSIONS:
return True
return False
class CollectMultiverseLookData(pyblish.api.InstancePlugin):
"""Collect Multiverse Look
@ -219,6 +238,7 @@ class CollectMultiverseLookData(pyblish.api.InstancePlugin):
files = []
sets = {}
instance.data["resources"] = []
expectMipMap = instance.data["expectMipMap"]
for node in nodes:
self.log.info("Getting resources for '{}'".format(node))
@ -242,7 +262,7 @@ class CollectMultiverseLookData(pyblish.api.InstancePlugin):
files = cmds.ls(history, type="file", long=True)
for f in files:
resources = self.collect_resource(f)
resources = self.collect_resource(f, expectMipMap)
instance.data["resources"].append(resources)
elif isinstance(matOver, multiverse.MaterialSourceUsdPath):
@ -255,7 +275,7 @@ class CollectMultiverseLookData(pyblish.api.InstancePlugin):
"relationships": sets
}
def collect_resource(self, node):
def collect_resource(self, node, expectMipMap):
"""Collect the link to the file(s) used (resource)
Args:
node (str): name of the node
@ -310,6 +330,7 @@ class CollectMultiverseLookData(pyblish.api.InstancePlugin):
source = source.replace("\\", "/")
files = get_file_node_files(node)
files = self.handle_files(files, expectMipMap)
if len(files) == 0:
self.log.error("No valid files found from node `%s`" % node)
@ -326,3 +347,26 @@ class CollectMultiverseLookData(pyblish.api.InstancePlugin):
"source": source, # required for resources
"files": files,
"color_space": color_space} # required for resources
def handle_files(self, files, expectMipMap):
"""This will go through all the files and make sure that they are
either already mipmapped or have a corresponding mipmap sidecar and
add that to the list."""
if not expectMipMap:
return files
extra_files = []
self.log.debug("Expecting MipMaps, going to look for them.")
for fname in files:
self.log.info("Checking '{}' for mipmaps".format(fname))
if is_mipamp(fname):
self.log.debug(" - file is already MipMap, skipping.")
continue
mipmap = get_mipmap(fname)
if mipmap:
self.log.info(" mipmap found for '{}'".format(fname))
extra_files.append(mipmap)
else:
self.log.warning(" no mipmap found for '{}'".format(fname))
return files + extra_files

View file

@ -0,0 +1,93 @@
import pyblish.api
import openpype.api
import openpype.hosts.maya.api.action
import os
import pprint
COLOUR_SPACES = ['sRGB']
MIPMAP_EXTENSIONS = ['tdl']
class ValidateMvLookContents(pyblish.api.InstancePlugin):
order = openpype.api.ValidateContentsOrder
families = ['mvLook']
hosts = ['maya']
label = 'Validate mvLook Data'
actions = [openpype.hosts.maya.api.action.SelectInvalidAction]
# Allow this validation step to be skipped when you just need to
# get things pushed through.
optional = True
# These intents get enforced checks, other ones get warnings.
enforced_intents = ['-', 'Final']
def process(self, instance):
intent = instance.context.data['intent']['value']
expectMipMap = instance.data["expectMipMap"]
enforced = True
if intent in self.enforced_intents:
self.log.info("This validation will be enforced: '{}'"
.format(intent))
else:
enforced = False
self.log.info("This validation will NOT be enforced: '{}'"
.format(intent))
if not instance[:]:
raise RuntimeError("Instance is empty")
invalid = set()
resources = instance.data.get("resources", [])
for resource in resources:
files = resource["files"]
self.log.debug("Resouce '{}', files: [{}]".format(resource, files))
node = resource["node"]
if len(files) == 0:
self.log.error("File node '{}' uses no or non-existing "
"files".format(node))
invalid.add(node)
continue
for fname in files:
if not self.valid_file(fname):
self.log.error("File node '{}'/'{}' is not valid"
.format(node, fname))
invalid.add(node)
if expectMipMap and not self.is_or_has_mipmap(fname, files):
msg = "File node '{}'/'{}' does not have a mipmap".format(
node, fname)
if enforced:
invalid.add(node)
self.log.error(msg)
raise RuntimeError(msg)
else:
self.log.warning(msg)
if invalid:
raise RuntimeError("'{}' has invalid look "
"content".format(instance.name))
def valid_file(self, fname):
self.log.debug("Checking validity of '{}'".format(fname))
if not os.path.exists(fname):
return False
if os.path.getsize(fname) == 0:
return False
return True
def is_or_has_mipmap(self, fname, files):
ext = os.path.splitext(fname)[1][1:]
if ext in MIPMAP_EXTENSIONS:
self.log.debug("Is a mipmap '{}'".format(fname))
return True
for colour_space in COLOUR_SPACES:
for mipmap_ext in MIPMAP_EXTENSIONS:
mipmap_fname = '.'.join([fname, colour_space, mipmap_ext])
if mipmap_fname in files:
self.log.debug("Has a mipmap '{}'".format(fname))
return True
return False