From 698e5db01e882f72f36d45563be5843c74494057 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Tue, 20 Feb 2024 15:48:51 +0000 Subject: [PATCH] Working version of attributes on extractor --- openpype/hosts/maya/api/alembic.py | 1 + .../create/create_animation_pointcache.py | 221 +-------------- .../plugins/publish/collect_pointcache.py | 5 - .../plugins/publish/extract_pointcache.py | 262 ++++++++++++++---- .../defaults/project_settings/maya.json | 26 ++ .../schemas/schema_maya_create.json | 104 ------- .../schemas/schema_maya_publish.json | 179 ++++++++++-- openpype/tools/publisher/widgets/widgets.py | 2 +- 8 files changed, 404 insertions(+), 396 deletions(-) diff --git a/openpype/hosts/maya/api/alembic.py b/openpype/hosts/maya/api/alembic.py index 63f826299f..b657262b4d 100644 --- a/openpype/hosts/maya/api/alembic.py +++ b/openpype/hosts/maya/api/alembic.py @@ -70,6 +70,7 @@ def extract_alembic( worldSpace=False, writeColorSets=False, writeCreases=False, + writeNormals=False, writeFaceSets=False, writeUVSets=False, writeVisibility=False diff --git a/openpype/hosts/maya/plugins/create/create_animation_pointcache.py b/openpype/hosts/maya/plugins/create/create_animation_pointcache.py index 353a4402ee..6fe078f2ad 100644 --- a/openpype/hosts/maya/plugins/create/create_animation_pointcache.py +++ b/openpype/hosts/maya/plugins/create/create_animation_pointcache.py @@ -1,26 +1,16 @@ from maya import cmds from openpype.hosts.maya.api import lib, plugin -from openpype.hosts.maya.api.alembic import ALEMBIC_ARGS from openpype.lib import ( BoolDef, - TextDef, NumberDef, - EnumDef, - UISeparatorDef, - UILabelDef, ) from openpype.pipeline import CreatedInstance def _get_animation_attr_defs(cls): - """Get Animation generic definitions. - - The line is blurry between what's "Animation" generic and "Alembic", - but the rule of thumb is that whatever "AlembicExport -h" accepts - is "Alembic" and the other ones are "Animation". - """ + """Get Animation generic definitions.""" defs = lib.collect_animation_defs() defs.extend( [ @@ -30,205 +20,16 @@ def _get_animation_attr_defs(cls): BoolDef( "includeParentHierarchy", label="Include Parent Hierarchy" ), + BoolDef( + "includeUserDefinedAttributes", + label="Include User Defined Attributes" + ), ] ) return defs -def _get_abc_export_flags(cls): - """Get two sets with the Alembic Export flags. - - Alembic flags are treated as booleans, so here we get all the possible - options, and work out a list with all the ones that can be toggled by - the user, and the ones defined in the settings. - """ - - # The Arguments that can be modified by the Publisher - abc_export_overrides = set(getattr(cls, "abc_export_overrides", set())) - - # What we have set in the Settings as defaults. - default_abc_export_flags = set(getattr(cls, "abc_export_flags", set())) - - # Set of un-toggleable flags, specified by the settings - abc_export_flags = { - arg - for arg in default_abc_export_flags - if arg not in abc_export_overrides - } - - # Set of all the available Alembic Export Flags - abc_boolean_flags = { - arg for arg, arg_type in ALEMBIC_ARGS.items() if arg_type is bool - } - - # Set of togglable flags - abc_export_toggleable_flags = { - arg for arg in abc_export_overrides if arg in abc_boolean_flags - } - return abc_export_flags, abc_export_toggleable_flags - - -def _get_animation_abc_attr_defs(cls): - """Get definitions relating to Alembic. - - An admin can define in settings the default arguments, which are then not - modifiable by the person publishing, unless they are added to the Alembic - Overrides setting, which is mapped to `abc_args_overrides`. - - Most of the Alembic Arguments are flags, treated as booleans, and there are - two possible lists: the defaults (from settings) and the the toggleable by - the user, these two define an EnumDef respectively. - - We use a combination of the two above to only show a muiltiselection - dropdown for booleans, and disabling the non-boolean arguments on the - interface. - - There's also a new separator so it's clearer what belongs to common - Animation publishes versus what is Almebic specific, the line is blurry, - but the rule of thumb is that whatever "AlembicExport -h" accepts is - "Alembic" and the other ones are "Animation". - """ - abc_defs = None - abc_defs = [ - UISeparatorDef("sep_alembic_options"), - UILabelDef("Alembic Options"), - ] - - # The Arguments that can be modified by the Publisher - abc_args_overrides = set(getattr(cls, "abc_args_overrides", set())) - - # What we have set in the Settings as defaults. - default_abc_export_flags = set(getattr(cls, "abc_export_flags", set())) - - ( - abc_export_flags, - abc_export_toggleable_flags, - ) = _get_abc_export_flags(cls) - - abc_defs.append( - EnumDef( - "abcExportFlags", - list(abc_export_flags), - default=list(abc_export_flags), - multiselection=True, - label="Settings Defined Arguments", - disabled=True, - hidden=True, - ) - ) - - # Only display Boolan flags that the Admin defined as overrideable - abc_export_toggleable_defaults = [ - arg - for arg in abc_export_toggleable_flags - if arg in default_abc_export_flags - ] - abc_defs.append( - EnumDef( - "abcExportTogglableFlags", - list(abc_export_toggleable_flags) - if abc_export_toggleable_flags - else [""], - default=abc_export_toggleable_defaults, - multiselection=True, - label="Export Flags", - disabled=True if not abc_export_toggleable_flags else False, - ) - ) - - abc_defs.append( - TextDef( - "attr", - label="Custom Attributes", - default=getattr(cls, "attr", None), - placeholder="attr1; attr2; ...", - disabled=True if "attr" not in abc_args_overrides else False, - ) - ) - - abc_defs.append( - TextDef( - "attrPrefix", - label="Custom Attributes Prefix", - default=getattr(cls, "attrPrefix", None), - placeholder="prefix1; prefix2; ...", - disabled=True if "attrPrefix" not in abc_args_overrides else False, - ) - ) - - abc_defs.append( - EnumDef( - "dataFormat", - label="Data Format", - default=getattr(cls, "dataFormat", None), - items=["ogawa", "HDF"], - disabled=True if "dataFormat" not in abc_args_overrides else False, - ) - ) - - abc_defs.append( - NumberDef( - "preRollStartFrame", - label="Start frame for preroll", - default=getattr(cls, "preRollStartFrame", None), - tooltip=( - "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." - ), - disabled=True - if "preRollStartFrame" not in abc_args_overrides - else False, - ) - ) - - return abc_defs - - -def _ensure_defaults(cls, instance_data): - """Ensure we get default values when an attribute is not overrideable. - - In instances where an attribute used to be modifiable, and then was locked - again, we want to make sure that we pass the default (what's on the - settings) instead of any value that might have been stored in the scene - when the attribute was modifiable. - """ - abc_args_overrides = set(getattr(cls, "abc_args_overrides", set())) - creator_attr = instance_data["creator_attributes"] - attr_default = getattr(cls, "attr", "") - - if "attr" not in abc_args_overrides: - creator_attr["attr"] = attr_default - - if "attrPrefix" not in abc_args_overrides: - creator_attr["attrPrefix"] = getattr(cls, "attrPrefix", "") - - if "dataFormat" not in abc_args_overrides: - creator_attr["dataFormat"] = getattr(cls, "dataFormat", "") - - if "preRollStartFrame" not in abc_args_overrides: - creator_attr["preRollStartFrame"] = getattr( - cls, "preRollStartFrame", "" - ) - - ( - abc_boolean_defaults, - abc_boolean_overrides, - ) = _get_abc_export_flags(cls) - - creator_attr["abcExportFlags"] = list(abc_boolean_defaults) - - if creator_attr.get("abcExportTogglableFlags", []): - abc_boolean_args = creator_attr["abcExportTogglableFlags"].copy() - - creator_attr["abcExportTogglableFlags"] = [ - arg for arg in abc_boolean_args if arg not in abc_boolean_overrides - ] - - return instance_data - - class CreateAnimation(plugin.MayaHiddenCreator): """Animation output for character rigs @@ -257,18 +58,12 @@ class CreateAnimation(plugin.MayaHiddenCreator): for node in cached_subsets.get(self.identifier, []): node_data = self.read_instance_node(node) - _ensure_defaults(self, node_data) - created_instance = CreatedInstance.from_existing(node_data, self) self._add_instance_to_context(created_instance) def get_instance_attr_defs(self): super(CreateAnimation, self).get_instance_attr_defs() defs = _get_animation_attr_defs(self) - abc_defs = _get_animation_abc_attr_defs(self) - if abc_defs: - defs.extend(abc_defs) - return defs @@ -292,18 +87,12 @@ class CreatePointCache(plugin.MayaCreator): for node in cached_subsets.get(self.identifier, []): node_data = self.read_instance_node(node) - _ensure_defaults(self, node_data) - created_instance = CreatedInstance.from_existing(node_data, self) self._add_instance_to_context(created_instance) def get_instance_attr_defs(self): super(CreatePointCache, self).get_instance_attr_defs() defs = _get_animation_attr_defs(self) - abc_defs = _get_animation_abc_attr_defs(self) - if abc_defs: - defs.extend(abc_defs) - return defs def create(self, subset_name, instance_data, pre_create_data): diff --git a/openpype/hosts/maya/plugins/publish/collect_pointcache.py b/openpype/hosts/maya/plugins/publish/collect_pointcache.py index 389f16a5bf..5578a57f31 100644 --- a/openpype/hosts/maya/plugins/publish/collect_pointcache.py +++ b/openpype/hosts/maya/plugins/publish/collect_pointcache.py @@ -10,11 +10,6 @@ class CollectPointcache(pyblish.api.InstancePlugin): families = ["pointcache"] label = "Collect Pointcache" hosts = ["maya"] - legacy_settings = { - "write_color_sets": "writeColorSets", - "write_face_sets": "writeFaceSets", - "include_user_defined_attributes": "includeUserDefinedAttributes" - } def process(self, instance): if instance.data.get("farm"): diff --git a/openpype/hosts/maya/plugins/publish/extract_pointcache.py b/openpype/hosts/maya/plugins/publish/extract_pointcache.py index 4bfd5e2fe0..26957b02f5 100644 --- a/openpype/hosts/maya/plugins/publish/extract_pointcache.py +++ b/openpype/hosts/maya/plugins/publish/extract_pointcache.py @@ -9,9 +9,18 @@ from openpype.hosts.maya.api.lib import ( maintained_selection, iter_visible_nodes_in_range, ) +from openpype.lib import ( + BoolDef, + TextDef, + NumberDef, + EnumDef, + UISeparatorDef, + UILabelDef, +) +from openpype.pipeline.publish import OpenPypePyblishPluginMixin -class ExtractAlembic(publish.Extractor): +class ExtractAlembic(publish.Extractor, OpenPypePyblishPluginMixin): """Produce an alembic of just point positions and normals. Positions and normals, uvs, creases are preserved, but nothing more, @@ -25,6 +34,19 @@ class ExtractAlembic(publish.Extractor): hosts = ["maya"] families = ["pointcache", "model", "vrayproxy.alembic"] targets = ["local", "remote"] + flags = [] + attr = [] + attrPrefix = [] + dataFormat = "ogawa" + melPerFrameCallback = "" + melPostJobCallback = "" + preRollStartFrame = 0 + pythonPerFrameCallback = "" + pythonPostJobCallback = "" + stripNamespaces = -1 + userAttr = "" + userAttrPrefix = "" + export_overrides = [] def process(self, instance): if instance.data.get("farm"): @@ -37,20 +59,22 @@ class ExtractAlembic(publish.Extractor): start = float(instance.data.get("frameStartHandle", 1)) end = float(instance.data.get("frameEndHandle", 1)) - # Collect Alembic Arguments - creator_attributes = instance.data.get("creator_attributes") - abc_flags = creator_attributes.get( - "abcExportTogglableFlags" - ) + creator_attributes.get("abcExportTogglableFlags") + attribute_values = self.get_attr_values_from_data( + instance.data + ) - abc_attrs = [ + attrs = [ attr.strip() - for attr in creator_attributes.get("attr", "").split(";") + for attr in attribute_values.get("attr", "").split(";") + if attr.strip() ] + attrs += instance.data.get("userDefinedAttributes", []) + attrs += ["cbId"] - abc_attr_prefixes = [ - attr_prefix.strip() - for attr_prefix in instance.data.get("attrPrefix", "").split(";") + attr_prefixes = [ + attr.strip() + for attr in attribute_values.get("attrPrefix", "").split(";") + if attr.strip() ] self.log.debug("Extracting pointcache...") @@ -60,51 +84,52 @@ class ExtractAlembic(publish.Extractor): filename = "{name}.abc".format(**instance.data) path = os.path.join(parent_dir, filename) - abc_root = None + root = None if not instance.data.get("includeParentHierarchy", True): # Set the root nodes if we don't want to include parents # The roots are to be considered the ones that are the actual # direct members of the set - abc_root = roots + root = roots - abc_writeUVSets = False - - if int(cmds.about(version=True)) >= 2017: - # Since Maya 2017 alembic supports multiple uv sets - write them. - if "writeUVSets" in abc_flags: - abc_writeUVSets = True - - extract_abc_args = { + args = { "file": path, - "attr": abc_attrs, - "attrPrefix": abc_attr_prefixes, - "dataFormat": creator_attributes.get("dataFormat", "ogawa"), + "attr": attrs, + "attrPrefix": attr_prefixes, + "dataFormat": attribute_values.get("dataFormat", "ogawa"), "endFrame": end, - "eulerFilter": True if "eulerFilter" in abc_flags else False, - "noNormals": True if "noNormals" in abc_flags else False, - "preRoll": True if "preRoll" in abc_flags else False, - "preRollStartFrame": creator_attributes.get( + "eulerFilter": False, + "noNormals": False, + "preRoll": False, + "preRollStartFrame": attribute_values.get( "preRollStartFrame", 0 ), - "renderableOnly": True if "renderableOnly" in abc_flags else False, - "root": abc_root, - "selection": True, # Should this stay like so? + "renderableOnly": False, + "root": root, + "selection": True, "startFrame": start, - "step": creator_attributes.get("step", 1.0), - "stripNamespaces": True, - "uvWrite": True if "uvWrite" in abc_flags else False, - "verbose": True if "verbose" in abc_flags else False, - "wholeFrameGeo": True if "wholeFrameGeo" in abc_flags else False, - "worldSpace": True if "worldSpace" in abc_flags else False, - "writeColorSets": True if "writeColorSets" in abc_flags else False, - "writeCreases": True if "writeCreases" in abc_flags else False, - "writeFaceSets": True if "writeFaceSets" in abc_flags else False, - "writeUVSets": abc_writeUVSets, - "writeVisibility": True - if "writeVisibility" in abc_flags - else False, + "step": instance.data.get( + "creator_attributes", {} + ).get("step", 1.0), + "stripNamespaces": False, + "uvWrite": False, + "verbose": False, + "wholeFrameGeo": False, + "worldSpace": False, + "writeColorSets": False, + "writeCreases": False, + "writeFaceSets": False, + "writeUVSets": False, + "writeVisibility": False, } + # Export flags are defined as default enabled flags excluding flags + # that are exposed to the user, plus the flags the user has enabled + # when publishing. + flags = list(set(self.flags) - set(self.export_overrides)) + flags += attribute_values["flag_overrides"] + for flag in flags: + args[flag] = True + if instance.data.get("visibleOnly", False): # If we only want to include nodes that are visible in the frame # range then we need to do our own check. Alembic's `visibleOnly` @@ -121,10 +146,10 @@ class ExtractAlembic(publish.Extractor): cmds.select(nodes, noExpand=True) self.log.debug( "Running `extract_alembic` with the arguments: {}".format( - extract_abc_args + args ) ) - extract_alembic(**extract_abc_args) + extract_alembic(**args) if "representations" not in instance.data: instance.data["representations"] = [] @@ -148,17 +173,17 @@ class ExtractAlembic(publish.Extractor): return path = path.replace(".abc", "_proxy.abc") - extract_abc_args["file"] = path + args["file"] = path if not instance.data.get("includeParentHierarchy", True): # Set the root nodes if we don't want to include parents # The roots are to be considered the ones that are the actual # direct members of the set - extract_abc_args["root"] = instance.data["proxyRoots"] + args["root"] = instance.data["proxyRoots"] with suspended_refresh(suspend=suspend): with maintained_selection(): cmds.select(instance.data["proxy"]) - extract_alembic(**extract_abc_args) + extract_alembic(**args) representation = { "name": "proxy", @@ -172,9 +197,146 @@ class ExtractAlembic(publish.Extractor): def get_members_and_roots(self, instance): return instance[:], instance.data.get("setMembers") + @classmethod + def get_attribute_defs(cls): + override_defs = { + "attr": { + "def": TextDef, + "kwargs": { + "label": "Custom Attributes", + "placeholder": "attr1; attr2; ...", + } + }, + "attrPrefix": { + "def": TextDef, + "kwargs": { + "label": "Custom Attributes Prefix", + "placeholder": "prefix1; prefix2; ...", + } + }, + "dataFormat": { + "def": EnumDef, + "kwargs": { + "label": "Data Format", + "items": ["ogawa", "HDF"], + } + }, + "melPerFrameCallback": { + "def": TextDef, + "kwargs": { + "label": "melPerFrameCallback", + } + }, + "melPostJobCallback": { + "def": TextDef, + "kwargs": { + "label": "melPostJobCallback", + } + }, + "preRollStartFrame": { + "def": NumberDef, + "kwargs": { + "label": "Start frame for preroll", + "tooltip": ( + "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." + ), + } + }, + "pythonPerFrameCallback": { + "def": TextDef, + "kwargs": { + "label": "pythonPerFrameCallback", + } + }, + "pythonPostJobCallback": { + "def": TextDef, + "kwargs": { + "label": "pythonPostJobCallback", + } + }, + "stripNamespaces": { + "def": NumberDef, + "kwargs": { + "label": "stripNamespaces", + "tooltip": ( + "If this flag is present namespaces will be stripped " + "off of the node before being written to Alembic. The " + "int after the flag specifies how many namespaces will" + " be stripped off of the node name. Be careful that " + "the new stripped name does not collide with other " + "sibling node names.\n\nExamples:\n taco:foo:bar would" + " be written as just bar with -sn 0\ntaco:foo:bar " + "would be written as foo:bar with -sn 1" + ), + } + }, + "userAttr": { + "def": TextDef, + "kwargs": { + "label": "userAttr", + } + }, + "userAttrPrefix": { + "def": TextDef, + "kwargs": { + "label": "userAttrPrefix", + } + }, + "visibleOnly": { + "def": BoolDef, + "kwargs": { + "label": "Visible Only", + } + } + } + + defs = super(ExtractAlembic, cls).get_attribute_defs() + + defs.extend([ + UISeparatorDef("sep_alembic_options"), + UILabelDef("Alembic Options"), + ]) + + # The Arguments that can be modified by the Publisher + export_overrides = set(getattr(cls, "export_overrides", set())) + + # What we have set in the Settings as defaults. + flags = set(getattr(cls, "flags", set())) + + enabled_flags = [x for x in flags if x in export_overrides] + flag_overrides = export_overrides - set(override_defs.keys()) + defs.append( + EnumDef( + "flag_overrides", + flag_overrides, + default=enabled_flags, + multiselection=True, + label="Export Flags", + ) + ) + + for key, value in override_defs.items(): + if key not in export_overrides: + continue + + kwargs = value["kwargs"] + kwargs["default"] = getattr(cls, key, None) + defs.append( + value["def"](key, **value["kwargs"]) + ) + + defs.append( + UISeparatorDef("sep_alembic_options") + ) + + return defs + class ExtractAnimation(ExtractAlembic): - label = "Extract Animation" + label = "Extract Animation (Alembic)" families = ["animation"] def get_members_and_roots(self, instance): diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 214a4f737a..1319a41f51 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -1150,6 +1150,32 @@ "pointcache", "model", "vrayproxy.alembic" + ], + "flags": [ + "stripNamespaces", + "writeColorSets", + "writeNormals", + "worldSpace" + ], + "attr": "", + "attrPrefix": "", + "dataFormat": "ogawa", + "melPerFrameCallback": "", + "melPostJobCallback": "", + "preRollStartFrame": 0, + "pythonPerFrameCallback": "", + "pythonPostJobCallback": "", + "userAttr": "", + "userAttrPrefix": "", + "visibleOnly": false, + "export_overrides": [ + "attr", + "attrPrefix", + "worldSpace", + "writeNormals", + "writeFaceSets", + "renderableOnly", + "visibleOnly" ] }, "ExtractObj": { diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json index 6f9ead7fec..7539d82436 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json @@ -158,114 +158,10 @@ "key": "refresh", "label": "Refresh" }, - { - "type": "enum", - "key": "abc_export_flags", - "multiselection": true, - "label": "Export Flags (.abc)", - "enum_items": [ - {"autoSubd": "autoSubd"}, - {"dontSkipUnwrittenFrames": "dontSkipUnwrittenFrames"}, - {"eulerFilter": "eulerFilter"}, - {"noNormals": "noNormals"}, - {"preRoll": "preRoll"}, - {"renderableOnly": "renderableOnly"}, - {"selection": "selection"}, - {"stripNamespaces": "stripNamespaces"}, - {"uvWrite": "uvWrite"}, - {"uvsOnly": "uvsOnly"}, - {"verbose": "verbose"}, - {"wholeFrameGeo": "wholeFrameGeo"}, - {"worldSpace": "worldSpace"}, - {"writeColorSets": "writeColorSets"}, - {"writeCreases": "writeCreases"}, - {"writeFaceSets": "writeFaceSets"}, - {"writeUVSets": "writeUVSets"}, - {"writeVisibility": "writeVisibility"} - ] - }, - { - "type": "enum", - "key": "abc_export_overrides", - "multiselection": true, - "label": "Export Overrides (.abc)", - "enum_items": [ - {"attr": "attr"}, - {"attrPrefix": "attrPrefix"}, - {"autoSubd": "autoSubd"}, - {"dataFormat": "dataFormat"}, - {"dontSkipUnwrittenFrames": "dontSkipUnwrittenFrames"}, - {"endFrame": "endFrame"}, - {"eulerFilter": "eulerFilter"}, - {"frameRange": "frameRange"}, - {"frameRelativeSample": "frameRelativeSample"}, - {"melPerFrameCallback": "melPerFrameCallback"}, - {"melPostJobCallback": "melPostJobCallback"}, - {"noNormals": "noNormals"}, - {"preRoll": "preRoll"}, - {"preRollStartFrame": "preRollStartFrame"}, - {"pythonPerFrameCallback": "pythonPerFrameCallback"}, - {"pythonPostJobCallback": "pythonPostJobCallback"}, - {"renderableOnly": "renderableOnly"}, - {"root": "root"}, - {"selection": "selection"}, - {"startFrame": "startFrame"}, - {"step": "step"}, - {"stripNamespaces": "stripNamespaces"}, - {"userAttr": "userAttr"}, - {"userAttrPrefix": "userAttrPrefix"}, - {"uvWrite": "uvWrite"}, - {"uvsOnly": "uvsOnly"}, - {"verbose": "verbose"}, - {"wholeFrameGeo": "wholeFrameGeo"}, - {"worldSpace": "worldSpace"}, - {"writeColorSets": "writeColorSets"}, - {"writeCreases": "writeCreases"}, - {"writeFaceSets": "writeFaceSets"}, - {"writeUVSets": "writeUVSets"}, - {"writeVisibility": "writeVisibility"} - ] - }, - { - "type": "number", - "key": "step", - "label": "Step", - "minimum": 0.0, - "decimal": 4 - }, { "type": "boolean", "key": "visibleOnly", "label": "Visible Only default" - }, - { - "type": "text", - "key": "attr", - "label": "Attributes" - }, - { - "type": "text", - "key": "attrPrefix", - "label": "Attr Prefix" - }, - { - "type": "enum", - "key": "dataFormat", - "label": "Data Format", - "enum_items": [ - { - "ogawa": "ogawa" - }, - { - "HDF": "HDF" - } - ] - }, - { - "type": "number", - "key": "preRollStartFrame", - "label": "Pre Roll Start Frame", - "minimum": 0 } ] }, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json index d2e7c51e24..9af9dbb32b 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json @@ -750,26 +750,6 @@ } ] }, - { - "type": "dict", - "collapsible": true, - "key": "ExtractAlembic", - "label": "Extract Alembic", - "checkbox_key": "enabled", - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "key": "families", - "label": "Families", - "type": "list", - "object_type": "text" - } - ] - }, { "type": "dict", "collapsible": true, @@ -1008,6 +988,165 @@ } ] }, + { + "type": "dict", + "collapsible": true, + "key": "ExtractAlembic", + "label": "Extract Pointcache/Animation", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "key": "families", + "label": "Families", + "type": "list", + "object_type": "text" + }, + { + "type": "splitter" + }, + { + "type": "label", + "label": "Export Defaults" + }, + { + "type": "enum", + "key": "flags", + "multiselection": true, + "label": "Flags", + "enum_items": [ + {"autoSubd": "autoSubd"}, + {"dontSkipUnwrittenFrames": "dontSkipUnwrittenFrames"}, + {"eulerFilter": "eulerFilter"}, + {"noNormals": "noNormals"}, + {"preRoll": "preRoll"}, + {"renderableOnly": "renderableOnly"}, + {"stripNamespaces": "stripNamespaces"}, + {"uvWrite": "uvWrite"}, + {"uvsOnly": "uvsOnly"}, + {"verbose": "verbose"}, + {"wholeFrameGeo": "wholeFrameGeo"}, + {"worldSpace": "worldSpace"}, + {"writeColorSets": "writeColorSets"}, + {"writeFaceSets": "writeFaceSets"}, + {"writeUVSets": "writeUVSets"}, + {"writeVisibility": "writeVisibility"} + ] + }, + { + "type": "text", + "key": "attr", + "label": "Attributes" + }, + { + "type": "text", + "key": "attrPrefix", + "label": "Attr Prefix" + }, + { + "type": "enum", + "key": "dataFormat", + "label": "Data Format", + "enum_items": [ + { + "ogawa": "ogawa" + }, + { + "HDF": "HDF" + } + ] + }, + { + "type": "text", + "key": "melPerFrameCallback", + "label": "melPerFrameCallback" + }, + { + "type": "text", + "key": "melPostJobCallback", + "label": "melPostJobCallback" + }, + { + "type": "number", + "key": "preRollStartFrame", + "label": "Pre Roll Start Frame", + "minimum": 0 + }, + { + "type": "text", + "key": "pythonPerFrameCallback", + "label": "pythonPerFrameCallback" + }, + { + "type": "text", + "key": "pythonPostJobCallback", + "label": "pythonPostJobCallback" + }, + { + "type": "text", + "key": "userAttr", + "label": "userAttr" + }, + { + "type": "text", + "key": "userAttrPrefix", + "label": "userAttrPrefix" + }, + { + "type": "boolean", + "key": "visibleOnly", + "label": "visibleOnly" + }, + { + "type": "splitter" + }, + { + "type": "label", + "label": "These attributes are exposed to the user when publishing with default values from above." + }, + { + "type": "enum", + "key": "export_overrides", + "multiselection": true, + "label": "Export Overrides", + "enum_items": [ + {"attr": "attr"}, + {"attrPrefix": "attrPrefix"}, + {"autoSubd": "autoSubd"}, + {"dataFormat": "dataFormat"}, + {"dontSkipUnwrittenFrames": "dontSkipUnwrittenFrames"}, + {"eulerFilter": "eulerFilter"}, + {"melPerFrameCallback": "melPerFrameCallback"}, + {"melPostJobCallback": "melPostJobCallback"}, + {"noNormals": "noNormals"}, + {"preRoll": "preRoll"}, + {"preRollStartFrame": "preRollStartFrame"}, + {"pythonPerFrameCallback": "pythonPerFrameCallback"}, + {"pythonPostJobCallback": "pythonPostJobCallback"}, + {"renderableOnly": "renderableOnly"}, + {"stripNamespaces": "stripNamespaces"}, + {"userAttr": "userAttr"}, + {"userAttrPrefix": "userAttrPrefix"}, + {"uvWrite": "uvWrite"}, + {"uvsOnly": "uvsOnly"}, + {"verbose": "verbose"}, + {"visibleOnly": "visibleOnly"}, + {"wholeFrameGeo": "wholeFrameGeo"}, + {"worldSpace": "worldSpace"}, + {"writeColorSets": "writeColorSets"}, + {"writeCreases": "writeCreases"}, + {"writeFaceSets": "writeFaceSets"}, + {"writeNormals": "writeNormals"}, + {"writeUVSets": "writeUVSets"}, + {"writeVisibility": "writeVisibility"} + ] + } + ] + }, { "type": "dict", "collapsible": true, diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index ecccc4e0c8..2b497707fa 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1485,7 +1485,7 @@ class CreatorAttrsWidget(QtWidgets.QWidget): class PublishPluginAttrsWidget(QtWidgets.QWidget): """Widget showing publsish plugin attributes for selected instances. - Attributes are defined on publish plugins. Publihs plugin may define + Attributes are defined on publish plugins. Publish plugin may define attribute definitions but must inherit `OpenPypePyblishPluginMixin` (~/openpype/pipeline/publish). At the moment requires to implement `get_attribute_defs` and `convert_attribute_values` class methods.