Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Maya: abc options for Pointcache/Animation family - OP-5920 #5173

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
e19e7e1
initial working version of abc options.
tokejepsen Jun 21, 2023
d87e64e
Docs
tokejepsen Jun 22, 2023
c07729d
Hound
tokejepsen Jun 22, 2023
e4a7641
Backwards compatibility attributes.
tokejepsen Jun 22, 2023
cda9089
Debug logging
tokejepsen Jun 22, 2023
1a5201a
Remove redundant code.
tokejepsen Jun 22, 2023
0342870
Failsafe
tokejepsen Jun 22, 2023
fab76c6
Ensure includeUserDefinedAttributes gets correct value
tokejepsen Jun 22, 2023
9923328
Update openpype/hosts/maya/plugins/publish/collect_pointcache.py
tokejepsen Jun 23, 2023
b601aa6
Hound
tokejepsen Jun 23, 2023
b63f5c5
Ensure list arguments are valid
tokejepsen Jun 28, 2023
e722fbe
BigRoy feedback
tokejepsen Jun 28, 2023
38be2be
Fix list arguments.
tokejepsen Jul 3, 2023
5aa5215
Working animation family
tokejepsen Jul 4, 2023
2f8dafd
Hound
tokejepsen Jul 4, 2023
e447e6a
Initial working animation family
tokejepsen Jul 6, 2023
db3dac4
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
tokejepsen Jul 13, 2023
9ac4017
Working pointcache
tokejepsen Jul 14, 2023
c1e771b
Revert post_imprint
tokejepsen Jul 14, 2023
9887035
Combine CreateAnimation and CreatePointCache
tokejepsen Jul 14, 2023
711fe5d
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
tokejepsen Aug 22, 2023
eafe2d0
Working merge of develop
tokejepsen Aug 22, 2023
7d1f009
Working hidden animation creator
tokejepsen Aug 22, 2023
d8ee0a6
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
tokejepsen Aug 22, 2023
178f184
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
tokejepsen Sep 1, 2023
fcf1c1e
Fix writeNormals
tokejepsen Sep 1, 2023
ee8b230
Remove redundant code.
tokejepsen Sep 1, 2023
de5c1ce
Add tooltip to preRollStartFrame
tokejepsen Sep 1, 2023
af6f157
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
tokejepsen Sep 18, 2023
7f152b9
Sync with develop plugin.py
tokejepsen Sep 18, 2023
99f7191
Merge origin/develop
Minkiu Nov 13, 2023
bb8b4c1
`maya` Define Alembic attributes as enums
Minkiu Nov 13, 2023
14fc3ab
`maya` Display Alembic settings for Animation
Minkiu Nov 14, 2023
f4be711
`maya.api.alembic` Move all the Alembic methods into it's own
Minkiu Nov 14, 2023
38a3ea4
`maya.api.alembic` Alphabetically order arguments
Minkiu Nov 14, 2023
6363064
`maya` Rename Alemebic settings, update `pointcache` creator
Minkiu Nov 14, 2023
3a14c8e
`maya.publish.pointcache` Use the `api.alembic` instead of `lib`
Minkiu Nov 14, 2023
33784f7
`maya.api.alembic` Fix missing `cmds` import
Minkiu Nov 15, 2023
fca2442
`maya.plugin.pointcache` Rework settings names
Minkiu Nov 15, 2023
608c7eb
`maya.extract_pointcache` Adapt to new settings
Minkiu Nov 15, 2023
2427477
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
Minkiu Nov 15, 2023
70e4883
`maya.api.alembic` Fix missing imports
Minkiu Nov 15, 2023
c379e7f
`maya.create_animation_pointcache` Fix publisher widgets population
Minkiu Nov 15, 2023
b0ab45b
Merge remote-tracking branch 'origin/develop' into enhancement/OP-592…
Minkiu Nov 20, 2023
e700f28
`maya.publish.pointcache` Log out the Alembic argumetns used.
Minkiu Nov 20, 2023
5935ef5
`maya.create_animation_pointcache` Ensure we set defaults
Minkiu Nov 20, 2023
326c210
`schemas.maya.create` Remove `stripNameSpaces` setting
Minkiu Nov 21, 2023
ca7998e
`maya.settings` Add AYON settings for Animation and PointCache
Minkiu Nov 21, 2023
0e905f3
`maya` Fix faulty logic in pointcache creator
Minkiu Dec 12, 2023
cd26a89
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
Minkiu Dec 12, 2023
f2f8345
`maya.create_animation_pointcache` Ensure there are `maya_cached_subs…
Minkiu Jan 4, 2024
749b3b4
`maya.create_animation_pointcache` Fix `_ensure_defaults` logic
Minkiu Jan 15, 2024
afc7967
`maya.creat_pointcache` Fix boolean arguments not being correctly par…
Minkiu Jan 15, 2024
a9fbb68
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
Minkiu Jan 31, 2024
97e8ccd
`server_addons.maya` Fix creator settings using legacy `Field`
Minkiu Jan 31, 2024
8c999fb
`server_addons.maya` Fix creator settings using legacy `Field`
Minkiu Jan 31, 2024
8e284aa
`settings.maya` Rename Alembic settings
Minkiu Jan 31, 2024
2652397
`maya.plugins.pointcache` Fix togglable flags defaults and adapt to n…
Minkiu Jan 31, 2024
76a6e2e
`maya.plugins` Fix create pointcache and apply format
Minkiu Jan 31, 2024
534bc82
`server_addons.maya.settings` fix missing `Literal` type in creators
Minkiu Feb 1, 2024
43bbf5a
`server_addons.maya.settings` Fix missing `creator` defaults
Minkiu Feb 1, 2024
87b3d7f
`hosts.maya.create` Ensure we get a `set` in `abc_args_overrides` in …
Minkiu Feb 1, 2024
698e5db
Working version of attributes on extractor
tokejepsen Feb 20, 2024
4e8ea03
Tidy up changes.
tokejepsen Feb 20, 2024
70982d9
Backwards compatibility wip
tokejepsen Feb 20, 2024
64b366c
Backwards compatibility
tokejepsen Feb 21, 2024
05dd980
Revert AYON settings
tokejepsen Feb 21, 2024
c123e83
revert ayon settings
tokejepsen Feb 21, 2024
8fee7b5
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
LiborBatek Feb 22, 2024
1f1d7c3
Missing writeNormals flag
tokejepsen Feb 22, 2024
242ea77
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
LiborBatek Feb 26, 2024
0c40340
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
LiborBatek Mar 5, 2024
59c0079
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
tokejepsen Mar 7, 2024
2e76f27
Change labels and export_overrides key
tokejepsen Mar 7, 2024
370e422
Fix plugin
tokejepsen Mar 7, 2024
3def9fe
Validate alembic options defaults
tokejepsen Mar 28, 2024
b645c62
Hound
tokejepsen Mar 28, 2024
50ff436
Merge branch 'develop' into enhancement/OP-5920_abc-options-for-Point…
antirotor Apr 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
306 changes: 306 additions & 0 deletions openpype/hosts/maya/api/alembic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
import json
import logging
Minkiu marked this conversation as resolved.
Show resolved Hide resolved
import os

from maya import cmds # noqa

from openpype.hosts.maya.api.lib import evaluation

log = logging.getLogger(__name__)

# The maya alembic export types
ALEMBIC_ARGS = {
"attr": (list, tuple),
"attrPrefix": (list, tuple),
"autoSubd": bool,
"dataFormat": str,
"dontSkipUnwrittenFrames": bool,
"endFrame": float,
"eulerFilter": bool,
"frameRange": str, # "start end"; overrides startFrame & endFrame
"frameRelativeSample": float,
"melPerFrameCallback": str,
"melPostJobCallback": str,
"noNormals": bool,
"preRoll": bool,
"preRollStartFrame": int,
"pythonPerFrameCallback": str,
"pythonPostJobCallback": str,
"renderableOnly": bool,
"root": (list, tuple),
"selection": bool,
"startFrame": float,
"step": float,
"stripNamespaces": bool,
"userAttr": (list, tuple),
"userAttrPrefix": (list, tuple),
"uvWrite": bool,
"uvsOnly": bool,
"verbose": bool,
"wholeFrameGeo": bool,
"worldSpace": bool,
"writeColorSets": bool,
"writeCreases": bool, # Maya 2015 Ext1+
"writeFaceSets": bool,
"writeUVSets": bool, # Maya 2017+
"writeVisibility": bool,
}


def extract_alembic(
file,
attr=None,
attrPrefix=None,
dataFormat="ogawa",
endFrame=None,
eulerFilter=True,
frameRange="",
noNormals=False,
preRoll=False,
preRollStartFrame=0,
renderableOnly=False,
root=None,
selection=True,
startFrame=None,
step=1.0,
stripNamespaces=True,
uvWrite=True,
verbose=False,
wholeFrameGeo=False,
worldSpace=False,
writeColorSets=False,
writeCreases=False,
writeNormals=False,
writeFaceSets=False,
writeUVSets=False,
writeVisibility=False
):
"""Extract a single Alembic Cache.
This extracts an Alembic cache using the `-selection` flag to minimize
the extracted content to solely what was Collected into the instance.
Arguments:
startFrame (float): Start frame of output. Ignored if `frameRange`
provided.
endFrame (float): End frame of output. Ignored if `frameRange`
provided.
frameRange (tuple or str): Two-tuple with start and end frame or a
string formatted as: "startFrame endFrame". This argument
overrides `startFrame` and `endFrame` arguments.
eulerFilter (bool): When on, X, Y, and Z rotation data is filtered with
an Euler filter. Euler filtering helps resolve irregularities in
rotations especially if X, Y, and Z rotations exceed 360 degrees.
Defaults to True.
noNormals (bool): When on, normal data from the original polygon
objects is not included in the exported Alembic cache file.
preRoll (bool): This frame range will not be sampled.
Defaults to False.
renderableOnly (bool): When on, any non-renderable nodes or hierarchy,
such as hidden objects, are not included in the Alembic file.
Defaults to False.
selection (bool): Write out all all selected nodes from the
active selection list that are descendents of the roots specified
with -root. Defaults to False.
uvWrite (bool): When on, UV data from polygon meshes and subdivision
objects are written to the Alembic file. Only the current UV map is
included.
writeColorSets (bool): Write all color sets on MFnMeshes as
color 3 or color 4 indexed geometry parameters with face varying
scope. Defaults to False.
writeFaceSets (bool): Write all Face sets on MFnMeshes.
Defaults to False.
wholeFrameGeo (bool): Data for geometry will only be written
out on whole frames. Defaults to False.
worldSpace (bool): When on, the top node in the node hierarchy is
stored as world space. By default, these nodes are stored as local
space. Defaults to False.
writeVisibility (bool): Visibility state will be stored in
the Alembic file. Otherwise everything written out is treated as
visible. Defaults to False.
writeUVSets (bool): Write all uv sets on MFnMeshes as vector
2 indexed geometry parameters with face varying scope. Defaults to
False.
writeCreases (bool): If the mesh has crease edges or crease
vertices, the mesh (OPolyMesh) would now be written out as an OSubD
and crease info will be stored in the Alembic file. Otherwise,
creases info won't be preserved in Alembic file unless a custom
Boolean attribute SubDivisionMesh has been added to mesh node and
its value is true. Defaults to False.
dataFormat (str): The data format to use for the cache,
defaults to "ogawa"
step (float): The time interval (expressed in frames) at
which the frame range is sampled. Additional samples around each
frame can be specified with -frs. Defaults to 1.0.
attr (list of str, optional): A specific geometric attribute to write
out. Defaults to [].
attrPrefix (list of str, optional): Prefix filter for determining which
geometric attributes to write out. Defaults to ["ABC_"].
root (list of str): Maya dag path which will be parented to
the root of the Alembic file. Defaults to [], which means the
entire scene will be written out.
stripNamespaces (bool): When on, any namespaces associated with the
exported objects are removed from the Alembic file. For example, an
object with the namespace taco:foo:bar appears as bar in the
Alembic file.
verbose (bool): When on, outputs frame number information to the
Script Editor or output window during extraction.
preRollStartFrame (float): The frame to start scene
evaluation at. This is used to set the starting frame for time
dependent translations and can be used to evaluate run-up that
isn't actually translated. Defaults to 0.
"""

# Ensure alembic exporter is loaded
cmds.loadPlugin('AbcExport', quiet=True)

# Alembic Exporter requires forward slashes
file = file.replace('\\', '/')

# Ensure list arguments are valid.
attr = attr or []
attrPrefix = attrPrefix or []
root = root or []

# Pass the start and end frame on as `frameRange` so that it
# never conflicts with that argument
if not frameRange:
# Fallback to maya timeline if no start or end frame provided.
if startFrame is None:
startFrame = cmds.playbackOptions(query=True,
animationStartTime=True)
if endFrame is None:
endFrame = cmds.playbackOptions(query=True,
animationEndTime=True)

# Ensure valid types are converted to frame range
assert isinstance(startFrame, ALEMBIC_ARGS["startFrame"])
assert isinstance(endFrame, ALEMBIC_ARGS["endFrame"])
frameRange = "{0} {1}".format(startFrame, endFrame)
else:
# Allow conversion from tuple for `frameRange`
if isinstance(frameRange, (list, tuple)):
assert len(frameRange) == 2
frameRange = "{0} {1}".format(frameRange[0], frameRange[1])

# Assemble options
options = {
"selection": selection,
"frameRange": frameRange,
"eulerFilter": eulerFilter,
"noNormals": noNormals,
"preRoll": preRoll,
"renderableOnly": renderableOnly,
"uvWrite": uvWrite,
"writeColorSets": writeColorSets,
"writeFaceSets": writeFaceSets,
"wholeFrameGeo": wholeFrameGeo,
"worldSpace": worldSpace,
"writeVisibility": writeVisibility,
"writeUVSets": writeUVSets,
"writeCreases": writeCreases,
"dataFormat": dataFormat,
"step": step,
"attr": attr,
"attrPrefix": attrPrefix,
"stripNamespaces": stripNamespaces,
"verbose": verbose,
"preRollStartFrame": preRollStartFrame
}

# Validate options
for key, value in options.copy().items():

# Discard unknown options
if key not in ALEMBIC_ARGS:
log.warning("extract_alembic() does not support option '%s'. "
"Flag will be ignored..", key)
options.pop(key)
continue

# Validate value type
valid_types = ALEMBIC_ARGS[key]
if not isinstance(value, valid_types):
raise TypeError("Alembic option unsupported type: "
"{0} (expected {1})".format(value, valid_types))

# Ignore empty values, like an empty string, since they mess up how
# job arguments are built
if isinstance(value, (list, tuple)):
value = [x for x in value if x.strip()]

# Ignore option completely if no values remaining
if not value:
options.pop(key)
continue

options[key] = value

# The `writeCreases` argument was changed to `autoSubd` in Maya 2018+
maya_version = int(cmds.about(version=True))
if maya_version >= 2018:
options['autoSubd'] = options.pop('writeCreases', False)

# Format the job string from options
job_args = list()
for key, value in options.items():
if isinstance(value, (list, tuple)):
for entry in value:
job_args.append("-{} {}".format(key, entry))
elif isinstance(value, bool):
# Add only when state is set to True
if value:
job_args.append("-{0}".format(key))
else:
job_args.append("-{0} {1}".format(key, value))

job_str = " ".join(job_args)
job_str += ' -file "%s"' % file

# Ensure output directory exists
parent_dir = os.path.dirname(file)
if not os.path.exists(parent_dir):
os.makedirs(parent_dir)

if verbose:
log.debug("Preparing Alembic export with options: %s",
json.dumps(options, indent=4))
log.debug("Extracting Alembic with job arguments: %s", job_str)

# Perform extraction
print("Alembic Job Arguments : {}".format(job_str))

# Disable the parallel evaluation temporarily to ensure no buggy
# exports are made. (PLN-31)
# TODO: Make sure this actually fixes the issues
with evaluation("off"):
cmds.AbcExport(j=job_str, verbose=verbose)

if verbose:
log.debug("Extracted Alembic to: %s", file)

return file
Loading
Loading