mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-02 00:44:52 +01:00
Workaround for motion blur
This commit is contained in:
parent
40cf86ea97
commit
1f08a27343
2 changed files with 146 additions and 63 deletions
|
|
@ -1,11 +1,14 @@
|
|||
import os
|
||||
import shutil
|
||||
import copy
|
||||
|
||||
from maya import cmds
|
||||
|
||||
import pyblish.api
|
||||
from openpype.hosts.maya.api import current_file
|
||||
from openpype.hosts.maya.api.lib import extract_alembic
|
||||
from openpype.pipeline import publish
|
||||
from openpype.lib import StringTemplate
|
||||
|
||||
|
||||
class ExtractWorkfileXgen(publish.Extractor):
|
||||
|
|
@ -18,9 +21,22 @@ class ExtractWorkfileXgen(publish.Extractor):
|
|||
hosts = ["maya"]
|
||||
|
||||
def process(self, instance):
|
||||
transfers = []
|
||||
|
||||
# Validate there is any palettes in the scene.
|
||||
if not cmds.ls(type="xgmPalette"):
|
||||
self.log.debug(
|
||||
"No collections found in the scene. Abort Xgen extraction."
|
||||
)
|
||||
return
|
||||
else:
|
||||
import xgenm
|
||||
|
||||
# Validate to extract only when we are publishing a renderlayer as
|
||||
# well.
|
||||
renderlayer = False
|
||||
start_frame = None
|
||||
end_frame = None
|
||||
for i in instance.context:
|
||||
is_renderlayer = (
|
||||
"renderlayer" in i.data.get("families", []) or
|
||||
|
|
@ -28,6 +44,17 @@ class ExtractWorkfileXgen(publish.Extractor):
|
|||
)
|
||||
if is_renderlayer and i.data["publish"]:
|
||||
renderlayer = True
|
||||
|
||||
if start_frame is None:
|
||||
start_frame = i.data["frameStart"]
|
||||
if end_frame is None:
|
||||
end_frame = i.data["frameEnd"]
|
||||
|
||||
if i.data["frameStart"] < start_frame:
|
||||
start_frame = i.data["frameStart"]
|
||||
if i.data["frameEnd"] > end_frame:
|
||||
end_frame = i.data["frameEnd"]
|
||||
|
||||
break
|
||||
|
||||
if not renderlayer:
|
||||
|
|
@ -37,6 +64,51 @@ class ExtractWorkfileXgen(publish.Extractor):
|
|||
)
|
||||
return
|
||||
|
||||
# We decrement start frame and increment end frame so motion blur will
|
||||
# render correctly.
|
||||
start_frame -= 1
|
||||
end_frame += 1
|
||||
|
||||
# Extract patches alembic.
|
||||
basename, _ = os.path.splitext(current_file())
|
||||
dirname = os.path.dirname(current_file())
|
||||
kwargs = {"attrPrefix": ["xgen"], "stripNamespaces": True}
|
||||
alembic_files = []
|
||||
for palette in cmds.ls(type="xgmPalette"):
|
||||
patch_names = []
|
||||
for description in xgenm.descriptions(palette):
|
||||
for name in xgenm.boundGeometry(palette, description):
|
||||
patch_names.append(name)
|
||||
|
||||
alembic_file = os.path.join(
|
||||
dirname,
|
||||
"{}__{}.abc".format(basename, palette.replace(":", "__ns__"))
|
||||
)
|
||||
extract_alembic(
|
||||
alembic_file,
|
||||
root=patch_names,
|
||||
selection=False,
|
||||
startFrame=float(start_frame),
|
||||
endFrame=float(end_frame),
|
||||
verbose=True,
|
||||
**kwargs
|
||||
)
|
||||
alembic_files.append(alembic_file)
|
||||
|
||||
template_data = copy.deepcopy(instance.data["anatomyData"])
|
||||
published_maya_path = StringTemplate(
|
||||
instance.context.data["anatomy"].templates["publish"]["file"]
|
||||
).format(template_data)
|
||||
published_basename, _ = os.path.splitext(published_maya_path)
|
||||
|
||||
for source in alembic_files:
|
||||
destination = os.path.join(
|
||||
os.path.dirname(instance.data["resourcesDir"]),
|
||||
os.path.basename(source.replace(basename, published_basename))
|
||||
)
|
||||
transfers.append((source, destination))
|
||||
|
||||
# Validate that we are using the published workfile.
|
||||
deadline_settings = instance.context.get("deadline")
|
||||
if deadline_settings:
|
||||
publish_settings = deadline_settings["publish"]
|
||||
|
|
@ -76,8 +148,9 @@ class ExtractWorkfileXgen(publish.Extractor):
|
|||
with open(destination, "r") as f:
|
||||
for line in [line.rstrip() for line in f]:
|
||||
if line.startswith("\txgProjectPath"):
|
||||
path = os.path.dirname(instance.data["resourcesDir"])
|
||||
line = "\txgProjectPath\t\t{}/".format(
|
||||
instance.data["resourcesDir"].replace("\\", "/")
|
||||
path.replace("\\", "/")
|
||||
)
|
||||
|
||||
lines.append(line)
|
||||
|
|
@ -88,31 +161,30 @@ class ExtractWorkfileXgen(publish.Extractor):
|
|||
sources.append(destination)
|
||||
|
||||
# Add resource files to workfile instance.
|
||||
transfers = []
|
||||
for source in sources:
|
||||
basename = os.path.basename(source)
|
||||
destination = os.path.join(instance.data["resourcesDir"], basename)
|
||||
destination = os.path.join(
|
||||
os.path.dirname(instance.data["resourcesDir"]), basename
|
||||
)
|
||||
transfers.append((source, destination))
|
||||
|
||||
import xgenm
|
||||
destination_dir = os.path.join(
|
||||
instance.data["resourcesDir"], "collections"
|
||||
)
|
||||
for palette in cmds.ls(type="xgmPalette"):
|
||||
relative_data_path = xgenm.getAttr(
|
||||
"xgDataPath", palette.replace("|", "")
|
||||
).split(os.pathsep)[0]
|
||||
absolute_data_path = relative_data_path.replace(
|
||||
"${PROJECT}",
|
||||
xgenm.getAttr("xgProjectPath", palette.replace("|", ""))
|
||||
)
|
||||
|
||||
for root, _, files in os.walk(absolute_data_path):
|
||||
for file in files:
|
||||
source = os.path.join(root, file).replace("\\", "/")
|
||||
destination = os.path.join(
|
||||
instance.data["resourcesDir"],
|
||||
relative_data_path.replace("${PROJECT}", ""),
|
||||
source.replace(absolute_data_path, "")[1:]
|
||||
)
|
||||
transfers.append((source, destination.replace("\\", "/")))
|
||||
project_path = xgenm.getAttr("xgProjectPath", palette)
|
||||
data_path = xgenm.getAttr("xgDataPath", palette)
|
||||
data_path = data_path.replace("${PROJECT}", project_path)
|
||||
for path in data_path.split(os.pathsep):
|
||||
for root, _, files in os.walk(path):
|
||||
for f in files:
|
||||
source = os.path.join(root, f)
|
||||
destination = "{}/{}{}".format(
|
||||
destination_dir,
|
||||
palette.replace(":", "__ns__"),
|
||||
source.replace(path, "")
|
||||
)
|
||||
transfers.append((source, destination))
|
||||
|
||||
for source, destination in transfers:
|
||||
self.log.debug("Transfer: {} > {}".format(source, destination))
|
||||
|
|
@ -120,21 +192,26 @@ class ExtractWorkfileXgen(publish.Extractor):
|
|||
instance.data["transfers"] = transfers
|
||||
|
||||
# Set palette attributes in preparation for workfile publish.
|
||||
attrs = ["xgFileName", "xgBaseFile"]
|
||||
attrs = {"xgFileName": None, "xgBaseFile": ""}
|
||||
data = {}
|
||||
for palette in cmds.ls(type="xgmPalette"):
|
||||
for attr in attrs:
|
||||
value = cmds.getAttr(palette + "." + attr)
|
||||
if value:
|
||||
new_value = "resources/{}".format(value)
|
||||
node_attr = "{}.{}".format(palette, attr)
|
||||
self.log.info(
|
||||
"Setting \"{}\" on \"{}\"".format(new_value, node_attr)
|
||||
)
|
||||
cmds.setAttr(node_attr, new_value, type="string")
|
||||
try:
|
||||
data[palette][attr] = value
|
||||
except KeyError:
|
||||
data[palette] = {attr: value}
|
||||
attrs["xgFileName"] = "resources/{}.xgen".format(
|
||||
palette.replace(":", "__ns__")
|
||||
)
|
||||
for attr, value in attrs.items():
|
||||
node_attr = palette + "." + attr
|
||||
|
||||
old_value = cmds.getAttr(node_attr)
|
||||
try:
|
||||
data[palette][attr] = old_value
|
||||
except KeyError:
|
||||
data[palette] = {attr: old_value}
|
||||
|
||||
cmds.setAttr(node_attr, value, type="string")
|
||||
self.log.info(
|
||||
"Setting \"{}\" on \"{}\"".format(value, node_attr)
|
||||
)
|
||||
|
||||
cmds.setAttr(palette + "." + "xgExportAsDelta", False)
|
||||
|
||||
instance.data["xgenAttributes"] = data
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import copy
|
||||
import tempfile
|
||||
|
||||
from maya import cmds
|
||||
import xgenm
|
||||
|
|
@ -16,6 +17,7 @@ class ExtractXgenCache(publish.Extractor):
|
|||
- Duplicate nodes used for patches.
|
||||
- Export palette and import onto duplicate nodes.
|
||||
- Export/Publish duplicate nodes and palette.
|
||||
- Export duplicate palette to .xgen file and add to publish.
|
||||
- Publish all xgen files as resources.
|
||||
"""
|
||||
|
||||
|
|
@ -32,29 +34,6 @@ class ExtractXgenCache(publish.Extractor):
|
|||
maya_filename = "{}.{}".format(instance.data["name"], self.scene_type)
|
||||
maya_filepath = os.path.join(staging_dir, maya_filename)
|
||||
|
||||
# Get published xgen file name.
|
||||
template_data = copy.deepcopy(instance.data["anatomyData"])
|
||||
template_data.update({"ext": "xgen"})
|
||||
templates = instance.context.data["anatomy"].templates["publish"]
|
||||
xgen_filename = StringTemplate(templates["file"]).format(template_data)
|
||||
name = instance.data["xgmPalette"].replace(":", "__").replace("|", "")
|
||||
xgen_filename = xgen_filename.replace(".xgen", "__" + name + ".xgen")
|
||||
|
||||
# Export xgen palette files.
|
||||
xgen_path = os.path.join(staging_dir, xgen_filename).replace("\\", "/")
|
||||
xgenm.exportPalette(
|
||||
instance.data["xgmPalette"].replace("|", ""), xgen_path
|
||||
)
|
||||
self.log.info("Extracted to {}".format(xgen_path))
|
||||
|
||||
representation = {
|
||||
"name": name,
|
||||
"ext": "xgen",
|
||||
"files": xgen_filename,
|
||||
"stagingDir": staging_dir,
|
||||
}
|
||||
instance.data["representations"].append(representation)
|
||||
|
||||
# Collect nodes to export.
|
||||
duplicate_nodes = []
|
||||
for node, connections in instance.data["xgenConnections"].items():
|
||||
|
|
@ -74,17 +53,43 @@ class ExtractXgenCache(publish.Extractor):
|
|||
|
||||
duplicate_nodes.append(duplicate_transform)
|
||||
|
||||
# Export temp xgen palette files.
|
||||
temp_xgen_path = os.path.join(
|
||||
tempfile.gettempdir(), "temp.xgen"
|
||||
).replace("\\", "/")
|
||||
xgenm.exportPalette(
|
||||
instance.data["xgmPalette"].replace("|", ""), temp_xgen_path
|
||||
)
|
||||
self.log.info("Extracted to {}".format(temp_xgen_path))
|
||||
|
||||
# Import xgen onto the duplicate.
|
||||
with maintained_selection():
|
||||
cmds.select(duplicate_nodes)
|
||||
palette = xgenm.importPalette(xgen_path, [])
|
||||
palette = xgenm.importPalette(temp_xgen_path, [])
|
||||
|
||||
attribute_data = {
|
||||
"{}.xgFileName".format(palette): xgen_filename
|
||||
# Get published xgen file name.
|
||||
template_data = copy.deepcopy(instance.data["anatomyData"])
|
||||
template_data.update({"ext": "xgen"})
|
||||
templates = instance.context.data["anatomy"].templates["publish"]
|
||||
xgen_filename = StringTemplate(templates["file"]).format(template_data)
|
||||
|
||||
# Export duplicated palette.
|
||||
xgen_path = os.path.join(staging_dir, xgen_filename).replace("\\", "/")
|
||||
xgenm.exportPalette(palette, xgen_path)
|
||||
|
||||
representation = {
|
||||
"name": "xgen",
|
||||
"ext": "xgen",
|
||||
"files": xgen_filename,
|
||||
"stagingDir": staging_dir,
|
||||
}
|
||||
instance.data["representations"].append(representation)
|
||||
|
||||
# Export Maya file.
|
||||
type = "mayaAscii" if self.scene_type == "ma" else "mayaBinary"
|
||||
attribute_data = {
|
||||
"{}.xgFileName".format(palette): xgen_filename
|
||||
}
|
||||
with attribute_values(attribute_data):
|
||||
with maintained_selection():
|
||||
cmds.select(duplicate_nodes + [palette])
|
||||
|
|
@ -106,12 +111,13 @@ class ExtractXgenCache(publish.Extractor):
|
|||
"name": self.scene_type,
|
||||
"ext": self.scene_type,
|
||||
"files": maya_filename,
|
||||
"stagingDir": staging_dir,
|
||||
"data": {"xgenName": palette}
|
||||
"stagingDir": staging_dir
|
||||
}
|
||||
instance.data["representations"].append(representation)
|
||||
|
||||
# Clean up.
|
||||
cmds.delete(duplicate_nodes + [palette])
|
||||
os.remove(temp_xgen_path)
|
||||
|
||||
# Collect all files under palette root as resources.
|
||||
data_path = xgenm.getAttr(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue