diff --git a/pype/hosts/maya/api/attributes.py b/pype/hosts/maya/api/attributes.py new file mode 100644 index 0000000000..a98548301a --- /dev/null +++ b/pype/hosts/maya/api/attributes.py @@ -0,0 +1,334 @@ +# -*- coding: utf-8 -*- +"""Code to get attributes from render layer without switching to it. + +https://github.com/Colorbleed/colorbleed-config/blob/acre/colorbleed/maya/lib_rendersetup.py +Credits: Roy Nieterau (BigRoy) / Colorbleed +Modified for use in Pype + +""" + +from maya import cmds +import maya.api.OpenMaya as om +import pymel.core as pm + +import maya.app.renderSetup.model.utils as utils +from maya.app.renderSetup.model import renderSetup +from maya.app.renderSetup.model.override import ( + AbsOverride, + RelOverride, + UniqueOverride +) + +EXACT_MATCH = 0 +PARENT_MATCH = 1 +CLIENT_MATCH = 2 + +DEFAULT_RENDER_LAYER = "defaultRenderLayer" + + +def get_rendersetup_layer(layer): + """Return render setup layer name. + + This also converts names from legacy renderLayer node name to render setup + name. + + Note: `DEFAULT_RENDER_LAYER` is not a renderSetupLayer node but it is + however the valid layer name for Render Setup - so we return that as + is. + + Example: + >>> for legacy_layer in cmds.ls(type="renderLayer"): + >>> layer = get_rendersetup_layer(legacy_layer) + + Returns: + str or None: Returns renderSetupLayer node name if `layer` is a valid + layer name in legacy renderlayers or render setup layers. + Returns None if the layer can't be found or Render Setup is + currently disabled. + """ + if layer == DEFAULT_RENDER_LAYER: + # DEFAULT_RENDER_LAYER doesn't have a `renderSetupLayer` + return layer + + if not cmds.mayaHasRenderSetup(): + return None + + if not cmds.objExists(layer): + return None + + if cmds.nodeType(layer) == "renderSetupLayer": + return layer + + # By default Render Setup renames the legacy renderlayer + # to `rs_` but lets not rely on that as the + # layer node can be renamed manually + connections = cmds.listConnections(layer + ".message", + type="renderSetupLayer", + exactType=True, + source=False, + destination=True, + plugs=True) or [] + return next((conn.split(".", 1)[0] for conn in connections + if conn.endswith(".legacyRenderLayer")), None) + + +def get_attr_in_layer(node_attr, layer): + """Return attribute value in Render Setup layer. + + This will only work for attributes which can be + retrieved with `maya.cmds.getAttr` and for which + Relative and Absolute overrides are applicable. + + Examples: + >>> get_attr_in_layer("defaultResolution.width", layer="layer1") + >>> get_attr_in_layer("defaultRenderGlobals.startFrame", layer="layer") + >>> get_attr_in_layer("transform.translate", layer="layer3") + + Args: + attr (str): attribute name as 'node.attribute' + layer (str): layer name + + Returns: + object: attribute value in layer + + """ + def _layer_needs_update(layer): + """Return whether layer needs updating.""" + # Use `getattr` as e.g. DEFAULT_RENDER_LAYER does not have + # the attribute + return getattr(layer, "needsMembershipUpdate", False) or \ + getattr(layer, "needsApplyUpdate", False) + + def get_default_layer_value(node_attr_): + """Return attribute value in `DEFAULT_RENDER_LAYER`.""" + inputs = cmds.listConnections(node_attr_, + source=True, + destination=False, + type="applyOverride") or [] + if inputs: + override = inputs[0] + history_overrides = cmds.ls(cmds.listHistory(override, + pruneDagObjects=True), + type="applyOverride") + node = history_overrides[-1] if history_overrides else override + node_attr_ = node + ".original" + + return pm.getAttr(node_attr_, asString=True) + + layer = get_rendersetup_layer(layer) + rs = renderSetup.instance() + current_layer = rs.getVisibleRenderLayer() + if current_layer.name() == layer: + + # Ensure layer is up-to-date + if _layer_needs_update(current_layer): + try: + rs.switchToLayer(current_layer) + except RuntimeError: + # Some cases can cause errors on switching + # the first time with Render Setup layers + # e.g. different overrides to compounds + # and its children plugs. So we just force + # it another time. If it then still fails + # we will let it error out. + rs.switchToLayer(current_layer) + + return pm.getAttr(node_attr, asString=True) + + overrides = get_attr_overrides(node_attr, layer) + default_layer_value = get_default_layer_value(node_attr) + if not overrides: + return default_layer_value + + value = default_layer_value + for match, layer_override, index in overrides: + if isinstance(layer_override, AbsOverride): + # Absolute override + value = pm.getAttr(layer_override.name() + ".attrValue") + if match == EXACT_MATCH: + # value = value + pass + if match == PARENT_MATCH: + value = value[index] + if match == CLIENT_MATCH: + value[index] = value + + elif isinstance(layer_override, RelOverride): + # Relative override + # Value = Original * Multiply + Offset + multiply = pm.getAttr(layer_override.name() + ".multiply") + offset = pm.getAttr(layer_override.name() + ".offset") + + if match == EXACT_MATCH: + value = value * multiply + offset + if match == PARENT_MATCH: + value = value * multiply[index] + offset[index] + if match == CLIENT_MATCH: + value[index] = value[index] * multiply + offset + + else: + raise TypeError("Unsupported override: %s" % layer_override) + + return value + + +def get_attr_overrides(node_attr, layer, + skip_disabled=True, + skip_local_render=True, + stop_at_absolute_override=True): + """Return all Overrides applicable to the attribute. + + Overrides are returned as a 3-tuple: + (Match, Override, Index) + Match: + This is any of EXACT_MATCH, PARENT_MATCH, CLIENT_MATCH + and defines whether the override is exactly on the + plug, on the parent or on a child plug. + Override: + This is the RenderSetup Override instance. + Index: + This is the Plug index under the parent or for + the child that matches. The EXACT_MATCH index will + always be None. For PARENT_MATCH the index is which + index the plug is under the parent plug. For CLIENT_MATCH + the index is which child index matches the plug. + + Args: + node_attr (str): attribute name as 'node.attribute' + layer (str): layer name + skip_disabled (bool): exclude disabled overrides + skip_local_render (bool): exclude overrides marked + as local render. + stop_at_absolute_override: exclude overrides prior + to the last absolute override as they have + no influence on the resulting value. + + Returns: + list: Ordered Overrides in order of strength + + """ + def get_mplug_children(plug): + """Return children MPlugs of compound `MPlug`.""" + children = [] + if plug.isCompound: + for i in range(plug.numChildren()): + children.append(plug.child(i)) + return children + + def get_mplug_names(mplug): + """Return long and short name of `MPlug`.""" + long_name = mplug.partialName(useLongNames=True) + short_name = mplug.partialName(useLongNames=False) + return {long_name, short_name} + + def iter_override_targets(override): + try: + for target in override._targets(): + yield target + except AssertionError: + # Workaround: There is a bug where the private `_targets()` method + # fails on some attribute plugs. For example overrides + # to the defaultRenderGlobals.endFrame + # (Tested in Maya 2020.2) + print("Workaround for %s" % override) + from maya.app.renderSetup.common.utils import findPlug + + attr = override.attributeName() + if isinstance(override, UniqueOverride): + node = override.targetNodeName() + yield findPlug(node, attr) + else: + nodes = override.parent().selector().nodes() + for node in nodes: + if cmds.attributeQuery(attr, node=node, exists=True): + yield findPlug(node, attr) + + # Get the MPlug for the node.attr + sel = om.MSelectionList() + sel.add(node_attr) + plug = sel.getPlug(0) + + layer = get_rendersetup_layer(layer) + if layer == DEFAULT_RENDER_LAYER: + # DEFAULT_RENDER_LAYER will never have overrides + # since it's the default layer + return [] + + rs_layer = renderSetup.instance().getRenderLayer(layer) + if rs_layer is None: + # Renderlayer does not exist + return + + # Get any parent or children plugs as we also + # want to include them in the attribute match + # for overrides + parent = plug.parent() if plug.isChild else None + parent_index = None + if parent: + parent_index = get_mplug_children(parent).index(plug) + + children = get_mplug_children(plug) + + # Create lookup for the attribute by both long + # and short names + attr_names = get_mplug_names(plug) + for child in children: + attr_names.update(get_mplug_names(child)) + if parent: + attr_names.update(get_mplug_names(parent)) + + # Get all overrides of the layer + # And find those that are relevant to the attribute + plug_overrides = [] + + # Iterate over the overrides in reverse so we get the last + # overrides first and can "break" whenever an absolute + # override is reached + layer_overrides = list(utils.getOverridesRecursive(rs_layer)) + for layer_override in reversed(layer_overrides): + + if skip_disabled and not layer_override.isEnabled(): + # Ignore disabled overrides + continue + + if skip_local_render and layer_override.isLocalRender(): + continue + + # The targets list can be very large so we'll do + # a quick filter by attribute name to detect whether + # it matches the attribute name, or its parent or child + if layer_override.attributeName() not in attr_names: + continue + + override_match = None + for override_plug in iter_override_targets(layer_override): + + override_match = None + if plug == override_plug: + override_match = (EXACT_MATCH, layer_override, None) + + elif parent and override_plug == parent: + override_match = (PARENT_MATCH, layer_override, parent_index) + + elif children and override_plug in children: + child_index = children.index(override_plug) + override_match = (CLIENT_MATCH, layer_override, child_index) + + if override_match: + plug_overrides.append(override_match) + break + + if ( + override_match and + stop_at_absolute_override and + isinstance(layer_override, AbsOverride) and + # When the override is only on a child plug then it doesn't + # override the entire value so we not stop at this override + not override_match[0] == CLIENT_MATCH + ): + # If override is absolute override, then BREAK out + # of parent loop we don't need to look any further as + # this is the absolute override + break + + return reversed(plug_overrides) diff --git a/pype/hosts/maya/plugins/publish/collect_renderable_camera.py b/pype/hosts/maya/plugins/publish/collect_renderable_camera.py index b90b85e7ec..5b3468424a 100644 --- a/pype/hosts/maya/plugins/publish/collect_renderable_camera.py +++ b/pype/hosts/maya/plugins/publish/collect_renderable_camera.py @@ -2,7 +2,7 @@ import pyblish.api from maya import cmds -from pype.hosts.maya.api import lib +from pype.hosts.maya.api.attributes import get_attr_in_layer class CollectRenderableCamera(pyblish.api.InstancePlugin): @@ -24,7 +24,7 @@ class CollectRenderableCamera(pyblish.api.InstancePlugin): self.log.info("layer: {}".format(layer)) cameras = cmds.ls(type="camera", long=True) renderable = [c for c in cameras if - lib.get_attr_in_layer("%s.renderable" % c, layer=layer)] + get_attr_in_layer("%s.renderable" % c, layer)] self.log.info("Found cameras %s: %s" % (len(renderable), renderable)) diff --git a/pype/hosts/maya/plugins/publish/validate_model_name.py b/pype/hosts/maya/plugins/publish/validate_model_name.py index f0004dc81e..2f1586538e 100644 --- a/pype/hosts/maya/plugins/publish/validate_model_name.py +++ b/pype/hosts/maya/plugins/publish/validate_model_name.py @@ -22,7 +22,6 @@ class ValidateModelName(pyblish.api.InstancePlugin): # path to shader names definitions # TODO: move it to preset file material_file = None - active = False regex = '(.*)_(\\d)*_(.*)_(GEO)' @classmethod diff --git a/pype/hosts/maya/plugins/publish/validate_joints_hidden.py b/pype/hosts/maya/plugins/publish/validate_rig_joints_hidden.py similarity index 93% rename from pype/hosts/maya/plugins/publish/validate_joints_hidden.py rename to pype/hosts/maya/plugins/publish/validate_rig_joints_hidden.py index 61dfcd563d..a102df50de 100644 --- a/pype/hosts/maya/plugins/publish/validate_joints_hidden.py +++ b/pype/hosts/maya/plugins/publish/validate_rig_joints_hidden.py @@ -6,7 +6,7 @@ import pype.hosts.maya.api.action from pype.hosts.maya.api import lib -class ValidateJointsHidden(pyblish.api.InstancePlugin): +class ValidateRigJointsHidden(pyblish.api.InstancePlugin): """Validate all joints are hidden visually. This includes being hidden: @@ -20,7 +20,6 @@ class ValidateJointsHidden(pyblish.api.InstancePlugin): order = pype.api.ValidateContentsOrder hosts = ['maya'] families = ['rig'] - category = 'rig' version = (0, 1, 0) label = "Joints Hidden" actions = [pype.hosts.maya.api.action.SelectInvalidAction, diff --git a/pype/hosts/maya/plugins/publish/validate_shader_name.py b/pype/hosts/maya/plugins/publish/validate_shader_name.py index 4a42ec6e35..a2951d5551 100644 --- a/pype/hosts/maya/plugins/publish/validate_shader_name.py +++ b/pype/hosts/maya/plugins/publish/validate_shader_name.py @@ -13,7 +13,6 @@ class ValidateShaderName(pyblish.api.InstancePlugin): """ optional = True - active = False order = pype.api.ValidateContentsOrder families = ["look"] hosts = ['maya'] diff --git a/pype/hosts/maya/plugins/publish/validate_transform_naming_suffix.py b/pype/hosts/maya/plugins/publish/validate_transform_naming_suffix.py index 14d4e7d5c8..bd290c73c7 100644 --- a/pype/hosts/maya/plugins/publish/validate_transform_naming_suffix.py +++ b/pype/hosts/maya/plugins/publish/validate_transform_naming_suffix.py @@ -35,11 +35,11 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin): version = (0, 1, 0) label = 'Suffix Naming Conventions' actions = [pype.hosts.maya.api.action.SelectInvalidAction] - SUFFIX_NAMING_TABLE = {'mesh': ["_GEO", "_GES", "_GEP", "_OSD"], - 'nurbsCurve': ["_CRV"], - 'nurbsSurface': ["_NRB"], - 'locator': ["_LOC"], - None: ['_GRP']} + SUFFIX_NAMING_TABLE = {"mesh": ["_GEO", "_GES", "_GEP", "_OSD"], + "nurbsCurve": ["_CRV"], + "nurbsSurface": ["_NRB"], + "locator": ["_LOC"], + "group": ["_GRP"]} ALLOW_IF_NOT_IN_SUFFIX_TABLE = True @@ -88,7 +88,7 @@ class ValidateTransformNamingSuffix(pyblish.api.InstancePlugin): fullPath=True, noIntermediate=True) - shape_type = cmds.nodeType(shapes[0]) if shapes else None + shape_type = cmds.nodeType(shapes[0]) if shapes else "group" if not cls.is_valid_name(transform, shape_type, cls.SUFFIX_NAMING_TABLE, cls.ALLOW_IF_NOT_IN_SUFFIX_TABLE): diff --git a/pype/hosts/nuke/plugins/publish/validate_knobs.py b/pype/hosts/nuke/plugins/publish/validate_knobs.py index ce15831c9c..cbc02690cb 100644 --- a/pype/hosts/nuke/plugins/publish/validate_knobs.py +++ b/pype/hosts/nuke/plugins/publish/validate_knobs.py @@ -9,7 +9,7 @@ class ValidateKnobs(pyblish.api.ContextPlugin): Knobs to validate and their values comes from the - Controled by plugin settings that require json in following structure: + Controlled by plugin settings that require json in following structure: "ValidateKnobs": { "enabled": true, "knobs": { diff --git a/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py index b36e1fdbba..af8694dd22 100644 --- a/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/pype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -23,12 +23,12 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): optional = True # presets - deadline_priority = 50 - deadline_chunk_size = 1 - deadline_pool = "" - deadline_pool_secondary = "" - deadline_group = "" - deadline_department = "" + priority = 50 + chunk_size = 1 + primary_pool = "" + secondary_pool = "" + group = "" + department = "" def process(self, instance): instance.data["toBeRenderedOn"] = "deadline" @@ -142,12 +142,12 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): # define chunk and priority chunk_size = instance.data.get("deadlineChunkSize") - if chunk_size == 0 and self.deadline_chunk_size: - chunk_size = self.deadline_chunk_size + if chunk_size == 0 and self.chunk_size: + chunk_size = self.chunk_size priority = instance.data.get("deadlinePriority") if not priority: - priority = self.deadline_priority + priority = self.priority payload = { "JobInfo": { @@ -165,11 +165,11 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin): "Priority": priority, "ChunkSize": chunk_size, - "Department": self.deadline_department, + "Department": self.department, - "Pool": self.deadline_pool, - "SecondaryPool": self.deadline_pool_secondary, - "Group": self.deadline_group, + "Pool": self.primary_pool, + "SecondaryPool": self.secondary_pool, + "Group": self.group, "Plugin": "Nuke", "Frames": "{start}-{end}".format( diff --git a/pype/settings/defaults/project_settings/deadline.json b/pype/settings/defaults/project_settings/deadline.json new file mode 100644 index 0000000000..6844979ddb --- /dev/null +++ b/pype/settings/defaults/project_settings/deadline.json @@ -0,0 +1,44 @@ +{ + "publish": { + "MayaSubmitDeadline": { + "enabled": true, + "optional": false, + "tile_assembler_plugin": "oiio", + "use_published": true, + "asset_dependencies": true + }, + "NukeSubmitDeadline": { + "enabled": true, + "optional": false, + "use_published": true, + "priority": 50, + "Chunk Size": 10, + "primary_pool": "", + "secondary_pool": "", + "group": "", + "department": "" + }, + "HarmonySubmitDeadline": { + "enabled": true, + "optional": false, + "use_published": true, + "priority": 50, + "Chunk Size": 10000, + "primary_pool": "", + "secondary_pool": "", + "group": "", + "department": "" + }, + "AfterEffectsSubmitDeadline": { + "enabled": true, + "optional": false, + "use_published": true, + "priority": 50, + "Chunk Size": 10000, + "primary_pool": "", + "secondary_pool": "", + "group": "", + "department": "" + } + } +} \ No newline at end of file diff --git a/pype/settings/defaults/project_settings/harmony.json b/pype/settings/defaults/project_settings/harmony.json index 83d63d3392..e1de4485a4 100644 --- a/pype/settings/defaults/project_settings/harmony.json +++ b/pype/settings/defaults/project_settings/harmony.json @@ -1,7 +1,20 @@ { - "publish": {}, "general": { "skip_resolution_check": [], "skip_timelines_check": [] + }, + "publish": { + "CollectPalettes": { + "allowed_tasks": [ + "." + ] + }, + "HarmonySubmitDeadline": { + "use_published": false, + "priority": 50, + "primary_pool": "", + "secondary_pool": "", + "chunk_size": 0 + } } } \ No newline at end of file diff --git a/pype/settings/defaults/project_settings/maya.json b/pype/settings/defaults/project_settings/maya.json index 2307fd8b82..03955732d2 100644 --- a/pype/settings/defaults/project_settings/maya.json +++ b/pype/settings/defaults/project_settings/maya.json @@ -107,37 +107,249 @@ "overscan": 1.0 } }, - "ext_mapping": {}, + "create": { + "CreateAnimation": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateAss": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateAssembly": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateCamera": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateLayout": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateLook": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateMayaScene": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateModel": { + "enabled": true, + "defaults": [ + "Main", + "Proxy", + "Sculpt" + ] + }, + "CreatePointCache": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateRender": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateRenderSetup": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateReview": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateRig": { + "enabled": true, + "defaults": [ + "Main", + "Sim", + "Cloth" + ] + }, + "CreateSetDress": { + "enabled": true, + "defaults": [ + "Main", + "Anim" + ] + }, + "CreateUnrealStaticMesh": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateVrayProxy": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateVRayScene": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateYetiRig": { + "enabled": true, + "defaults": [ + "Main" + ] + } + }, "publish": { "CollectMayaRender": { "sync_workfile_version": false }, - "ValidateCameraAttributes": { + "ValidateShaderName": { "enabled": false, - "optional": true + "regex": "(?P.*)_(.*)_SHD" + }, + "ValidateAttributes": { + "enabled": false, + "attributes": {} }, "ValidateModelName": { - "enabled": true, + "enabled": false, "material_file": { "windows": "", "darwin": "", "linux": "" }, - "regex": "" + "regex": "(.*)_(\\\\d)*_(.*)_(GEO)" }, - "ValidateAssemblyName": { - "enabled": true - }, - "ValidateShaderName": { + "ValidateTransformNamingSuffix": { "enabled": true, - "regex": "" + "SUFFIX_NAMING_TABLE": { + "mesh": [ + "_GEO", + "_GES", + "_GEP", + "_OSD" + ], + "nurbsCurve": [ + "_CRV" + ], + "nurbsSurface": [ + "_NRB" + ], + "locator": [ + "_LOC" + ], + "group": [ + "_GRP" + ] + }, + "ALLOW_IF_NOT_IN_SUFFIX_TABLE": true + }, + "ValidateColorSets": { + "enabled": false, + "optional": true }, "ValidateMeshHasOverlappingUVs": { - "enabled": false - }, - "ValidateAttributes": { "enabled": false, - "attributes": {} + "optional": true + }, + "ValidateMeshArnoldAttributes": { + "enabled": false, + "optional": true + }, + "ValidateMeshShaderConnections": { + "enabled": true, + "optional": true + }, + "ValidateMeshSingleUVSet": { + "enabled": false, + "optional": true + }, + "ValidateMeshHasUVs": { + "enabled": true, + "optional": true + }, + "ValidateMeshLaminaFaces": { + "enabled": false, + "optional": true + }, + "ValidateMeshNonManifold": { + "enabled": false, + "optional": true + }, + "ValidateMeshUVSetMap1": { + "enabled": false, + "optional": true + }, + "ValidateMeshVerticesHaveEdges": { + "enabled": true, + "optional": true + }, + "ValidateNoAnimation": { + "enabled": false, + "optional": true + }, + "ValidateNoNamespace": { + "enabled": true, + "optional": true + }, + "ValidateNoNullTransforms": { + "enabled": true, + "optional": true + }, + "ValidateNoUnknownNodes": { + "enabled": true, + "optional": true + }, + "ValidateNodeNoGhosting": { + "enabled": false, + "optional": true + }, + "ValidateShapeDefaultNames": { + "enabled": false, + "optional": true + }, + "ValidateShapeRenderStats": { + "enabled": false, + "optional": true + }, + "ValidateTransformZero": { + "enabled": true, + "optional": true + }, + "ValidateCameraAttributes": { + "enabled": false, + "optional": true + }, + "ValidateAssemblyName": { + "enabled": true, + "optional": true + }, + "ValidateAssRelativePaths": { + "enabled": true, + "optional": true }, "ExtractCameraAlembic": { "enabled": true, @@ -221,6 +433,39 @@ 0.8, 0.5 ] + }, + "ReferenceLoader": { + "enabled": true, + "representations": [ + "ma", + "mb", + "abc", + "fbx" + ] + }, + "AudioLoader": { + "enabled": true, + "representations": [ + "wav" + ] + }, + "GpuCacheLoader": { + "enabled": true, + "representations": [ + "abc" + ] + }, + "ImagePlaneLoader": { + "enabled": true, + "representations": [ + "jpg", + "png", + "mov" + ] + }, + "MatchmoveLoader": { + "enabled": true, + "representations": [] } }, "workfile_build": { diff --git a/pype/settings/defaults/project_settings/nuke.json b/pype/settings/defaults/project_settings/nuke.json index 94cd712639..517065f79a 100644 --- a/pype/settings/defaults/project_settings/nuke.json +++ b/pype/settings/defaults/project_settings/nuke.json @@ -61,6 +61,22 @@ "deadline_pool": "", "deadline_pool_secondary": "", "deadline_chunk_size": 1 + }, + "ValidateOutputResolution": { + "enabled": true, + "optional": true + }, + "ValidateGizmo": { + "enabled": true, + "optional": true + }, + "ValidateScript": { + "enabled": true, + "optional": true + }, + "ValidateNukeWriteBoundingBox": { + "enabled": true, + "optional": true } }, "workfile_build": { diff --git a/pype/settings/entities/dict_immutable_keys_entity.py b/pype/settings/entities/dict_immutable_keys_entity.py index f6cd629d10..af0ddcb758 100644 --- a/pype/settings/entities/dict_immutable_keys_entity.py +++ b/pype/settings/entities/dict_immutable_keys_entity.py @@ -135,7 +135,7 @@ class DictImmutableKeysEntity(ItemEntity): continue if child_obj.key in self.non_gui_children: - raise SchemaDuplicatedKeys(self.path, child_obj.key) + raise SchemaDuplicatedKeys("", child_obj.key) self.non_gui_children[child_obj.key] = child_obj if not first: diff --git a/pype/settings/entities/schemas/projects_schema/schema_main.json b/pype/settings/entities/schemas/projects_schema/schema_main.json index 8ad059f1c7..31d7373873 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_main.json +++ b/pype/settings/entities/schemas/projects_schema/schema_main.json @@ -45,6 +45,10 @@ "type": "schema", "name": "schema_project_ftrack" }, + { + "type": "schema", + "name": "schema_project_deadline" + }, { "type": "schema", "name": "schema_project_maya" diff --git a/pype/settings/entities/schemas/projects_schema/schema_plugins.json b/pype/settings/entities/schemas/projects_schema/schema_plugins.json deleted file mode 100644 index a7ed64be17..0000000000 --- a/pype/settings/entities/schemas/projects_schema/schema_plugins.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "type": "dict", - "collapsible": true, - "key": "plugins", - "label": "Plugins", - "children": [ - { - "type": "dict", - "collapsible": true, - "key": "standalonepublisher", - "label": "Standalone Publisher", - "children": [ - { - "type": "dict", - "collapsible": true, - "key": "publish", - "label": "Publish plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsible": true, - "key": "ExtractThumbnailSP", - "label": "ExtractThumbnailSP", - "is_group": true, - "children": [ - { - "type": "dict", - "collapsible": false, - "key": "ffmpeg_args", - "label": "ffmpeg_args", - "children": [ - { - "type": "list", - "object_type": "text", - "key": "input", - "label": "input" - }, - { - "type": "list", - "object_type": "text", - "key": "output", - "label": "output" - } - ] - } - ] - } - ] - } - ] - } - ] -} diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json b/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json new file mode 100644 index 0000000000..ea76f4e62e --- /dev/null +++ b/pype/settings/entities/schemas/projects_schema/schema_project_deadline.json @@ -0,0 +1,223 @@ +{ + "type": "dict", + "key": "deadline", + "label": "Deadline", + "collapsible": true, + "is_file": true, + "children": [ + { + "type": "dict", + "collapsible": true, + "key": "publish", + "label": "Publish plugins", + "is_file": true, + "children": [ + { + "type": "dict", + "collapsible": true, + "key": "MayaSubmitDeadline", + "label": "Submit maya job to deadline", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "optional", + "label": "Optional" + }, + { + "type": "enum", + "key": "tile_assembler_plugin", + "label": "Tile Assembler Plugin", + "multiselection": false, + "enum_items": [ + { + "DraftTileAssembler": "Draft Tile Assembler" + }, + { + "oiio": "Open Image IO" + } + ] + }, + { + "type": "boolean", + "key": "use_published", + "label": "Use Published scene" + }, + { + "type": "boolean", + "key": "asset_dependencies", + "label": "Use Asset dependencies" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "key": "NukeSubmitDeadline", + "label": "Nuke Submit to Deadline", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "optional", + "label": "Optional" + }, + { + "type": "boolean", + "key": "use_published", + "label": "Use Published scene" + }, + { + "type": "number", + "key": "priority", + "label": "Priority" + }, + { + "type": "number", + "key": "Chunk Size", + "label": "Chunk Size" + }, + { + "type": "text", + "key": "primary_pool", + "label": "Primary Pool" + }, + { + "type": "text", + "key": "secondary_pool", + "label": "Secondary Pool" + }, + { + "type": "text", + "key": "group", + "label": "Group" + }, + { + "type": "text", + "key": "department", + "label": "Department" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "key": "HarmonySubmitDeadline", + "label": "Harmony Submit to Deadline", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "optional", + "label": "Optional" + }, + { + "type": "boolean", + "key": "use_published", + "label": "Use Published scene" + }, + { + "type": "number", + "key": "priority", + "label": "Priority" + }, + { + "type": "number", + "key": "Chunk Size", + "label": "Chunk Size" + }, + { + "type": "text", + "key": "primary_pool", + "label": "Primary Pool" + }, + { + "type": "text", + "key": "secondary_pool", + "label": "Secondary Pool" + }, + { + "type": "text", + "key": "group", + "label": "Group" + }, + { + "type": "text", + "key": "department", + "label": "Department" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "key": "AfterEffectsSubmitDeadline", + "label": "After Effects Submit to Deadline", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "optional", + "label": "Optional" + }, + { + "type": "boolean", + "key": "use_published", + "label": "Use Published scene" + }, + { + "type": "number", + "key": "priority", + "label": "Priority" + }, + { + "type": "number", + "key": "Chunk Size", + "label": "Chunk Size" + }, + { + "type": "text", + "key": "primary_pool", + "label": "Primary Pool" + }, + { + "type": "text", + "key": "secondary_pool", + "label": "Secondary Pool" + }, + { + "type": "text", + "key": "group", + "label": "Group" + }, + { + "type": "text", + "key": "department", + "label": "Department" + } + ] + } + ] + } + ] +} diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_global.json b/pype/settings/entities/schemas/projects_schema/schema_project_global.json index 1733e04f67..221cf0b588 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_global.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_global.json @@ -14,7 +14,7 @@ "name": "schema_global_tools" }, { - "type": "raw-json", + "type": "collapsible-wrap", "label": "Project Folder Structure", "key": "project_folder_structure", "use_label_wrap": true diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_harmony.json b/pype/settings/entities/schemas/projects_schema/schema_project_harmony.json index 5d1cbff1b8..c4cdccff42 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_harmony.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_harmony.json @@ -5,13 +5,6 @@ "label": "Harmony", "is_file": true, "children": [ - { - "type": "dict", - "collapsible": true, - "key": "publish", - "label": "Publish plugins", - "children": [] - }, { "type": "dict", "collapsible": true, @@ -31,6 +24,61 @@ "label": "Skip Timeliene Check for Tasks" } ] + }, + { + "type": "dict", + "collapsible": true, + "key": "publish", + "label": "Publish plugins", + "children": [ + { + "type": "dict", + "collapsible": true, + "key": "CollectPalettes", + "label": "Collect Palettes", + "children": [ + { + "type": "list", + "key": "allowed_tasks", + "label": "Allowed tasks", + "object_type": "text" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "key": "HarmonySubmitDeadline", + "label": "Harmony Submit to Deadline", + "children": [ + { + "type": "boolean", + "key": "use_published", + "label": "Use Published scene" + }, + { + "type": "number", + "key": "priority", + "label": "priority" + }, + { + "type": "text", + "key": "primary_pool", + "label": "Primary Pool" + }, + { + "type": "text", + "key": "secondary_pool", + "label": "Secondary Pool" + }, + { + "type": "number", + "key": "chunk_size", + "label": "Chunk Size" + } + ] + } + ] } ] } diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_maya.json b/pype/settings/entities/schemas/projects_schema/schema_project_maya.json index 5ba5de1557..7a270b0046 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_maya.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_maya.json @@ -9,6 +9,10 @@ "type": "schema", "name": "schema_maya_capture" }, + { + "type": "schema", + "name": "schema_maya_create" + }, { "type": "schema", "name": "schema_maya_publish" diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json b/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json index b60b548cb0..0548bd3544 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_nuke.json @@ -9,7 +9,7 @@ "type": "dict", "collapsible": true, "key": "create", - "label": "Create plugins", + "label": "Creator plugins", "children": [ { "type": "dict", @@ -42,144 +42,9 @@ ] }, { - "type": "dict", - "collapsible": true, - "key": "publish", - "label": "Publish plugins", - "children": [ - { - "type": "dict", - "collapsible": true, - "key": "PreCollectNukeInstances", - "label": "PreCollectNukeInstances", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "sync_workfile_version", - "label": "Sync Version from workfile" - } - ] - }, - { - "type": "dict", - "collapsible": true, - "checkbox_key": "enabled", - "key": "ExtractThumbnail", - "label": "ExtractThumbnail", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "raw-json", - "key": "nodes", - "label": "Nodes" - } - ] - }, - { - "type": "dict", - "collapsible": true, - "checkbox_key": "enabled", - "key": "ValidateKnobs", - "label": "ValidateKnobs", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "raw-json", - "key": "knobs", - "label": "Knobs" - } - ] - }, - { - "type": "dict", - "collapsible": true, - "checkbox_key": "enabled", - "key": "ExtractReviewDataLut", - "label": "ExtractReviewDataLut", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - } - ] - }, - { - "type": "dict", - "collapsible": true, - "checkbox_key": "enabled", - "key": "ExtractReviewDataMov", - "label": "ExtractReviewDataMov", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "viewer_lut_raw", - "label": "Viewer LUT raw" - } - ] - }, - { - "type": "dict", - "collapsible": true, - "key": "ExtractSlateFrame", - "label": "ExtractSlateFrame", - "is_group": true, - "children": [ - { - "type": "boolean", - "key": "viewer_lut_raw", - "label": "Viewer LUT raw" - } - ] - }, - { - "type": "dict", - "collapsible": true, - "key": "NukeSubmitDeadline", - "label": "NukeSubmitDeadline", - "is_group": true, - "children": [ - { - "type": "number", - "key": "deadline_priority", - "label": "deadline_priority" - }, - { - "type": "text", - "key": "deadline_pool", - "label": "deadline_pool" - }, - { - "type": "text", - "key": "deadline_pool_secondary", - "label": "deadline_pool_secondary" - }, - { - "type": "number", - "key": "deadline_chunk_size", - "label": "deadline_chunk_size" - } - ] - } - ] + "type": "schema", + "name": "schema_nuke_publish", + "template_data": [] }, { "type": "schema", diff --git a/pype/settings/entities/schemas/projects_schema/schema_project_standalonepublisher.json b/pype/settings/entities/schemas/projects_schema/schema_project_standalonepublisher.json index 735b9611d2..47eea3441c 100644 --- a/pype/settings/entities/schemas/projects_schema/schema_project_standalonepublisher.json +++ b/pype/settings/entities/schemas/projects_schema/schema_project_standalonepublisher.json @@ -5,44 +5,6 @@ "label": "Standalone Publisher", "is_file": true, "children": [ - { - "type": "dict", - "collapsible": true, - "key": "publish", - "label": "Publish plugins", - "is_file": true, - "children": [ - { - "type": "dict", - "collapsible": true, - "key": "ExtractThumbnailSP", - "label": "ExtractThumbnailSP", - "is_group": true, - "children": [ - { - "type": "dict", - "collapsible": false, - "key": "ffmpeg_args", - "label": "ffmpeg_args", - "children": [ - { - "type": "list", - "object_type": "text", - "key": "input", - "label": "input" - }, - { - "type": "list", - "object_type": "text", - "key": "output", - "label": "output" - } - ] - } - ] - } - ] - }, { "type": "dict-modifiable", "collapsible": true, @@ -88,6 +50,44 @@ } ] } + }, + { + "type": "dict", + "collapsible": true, + "key": "publish", + "label": "Publish plugins", + "is_file": true, + "children": [ + { + "type": "dict", + "collapsible": true, + "key": "ExtractThumbnailSP", + "label": "ExtractThumbnailSP", + "is_group": true, + "children": [ + { + "type": "dict", + "collapsible": false, + "key": "ffmpeg_args", + "label": "ffmpeg_args", + "children": [ + { + "type": "list", + "object_type": "text", + "key": "input", + "label": "input" + }, + { + "type": "list", + "object_type": "text", + "key": "output", + "label": "output" + } + ] + } + ] + } + ] } ] } diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_capture.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_capture.json index 648fca28e6..4745a19075 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_capture.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_capture.json @@ -1,595 +1,581 @@ { - "type": "collapsible-wrap", - "label": "Collapsible Wrapper without key", + "type": "dict", + "collapsible": true, + "key": "capture", + "label": "Maya Playblast settings", + "is_file": true, "children": [ { "type": "dict", - "collapsible": true, - "key": "capture", - "label": "Maya Playblast settings", - "is_file": true, + "key": "Codec", "children": [ { - "type": "dict", - "key": "Codec", - "children": [ - { - "type": "label", - "label": "Codec" - }, - { - "type": "text", - "key": "compression", - "label": "Compression type" - }, - { - "type": "text", - "key": "format", - "label": "Data format" - }, - { - "type": "number", - "key": "quality", - "label": "Quality", - "decimal": 0, - "minimum": 0, - "maximum": 100 - }, + "type": "label", + "label": "Codec" + }, + { + "type": "text", + "key": "compression", + "label": "Compression type" + }, + { + "type": "text", + "key": "format", + "label": "Data format" + }, + { + "type": "number", + "key": "quality", + "label": "Quality", + "decimal": 0, + "minimum": 0, + "maximum": 100 + }, - { - "type": "splitter" - } - ] - }, - { - "type": "dict", - "key": "Display Options", - "children": [ - { - "type": "label", - "label": "Display Options" - }, - { - "type": "list-strict", - "key": "background", - "label": "Background Color: ", - "object_types": [ - { - "label": "Red", - "type": "number", - "minimum": 0, - "maximum": 1, - "decimal": 3 - }, - { - "label": "Green", - "type": "number", - "minimum": 0, - "maximum": 1, - "decimal": 3 - }, - { - "label": "Blue", - "type": "number", - "minimum": 0, - "maximum": 1, - "decimal": 3 - } - ] - }, - { - "type": "list-strict", - "key": "backgroundBottom", - "label": "Background Bottom: ", - "object_types": [ - { - "label": "Red", - "type": "number", - "minimum": 0, - "maximum": 1, - "decimal": 3 - }, - { - "label": "Green", - "type": "number", - "minimum": 0, - "maximum": 1, - "decimal": 3 - }, - { - "label": "Blue", - "type": "number", - "minimum": 0, - "maximum": 1, - "decimal": 3 - } - ] - }, - { - "type": "list-strict", - "key": "backgroundTop", - "label": "Background Top: ", - "object_types": [ - { - "label": "Red", - "type": "number", - "minimum": 0, - "maximum": 1, - "decimal": 3 - }, - { - "label": "Green", - "type": "number", - "minimum": 0, - "maximum": 1, - "decimal": 3 - }, - { - "label": "Blue", - "type": "number", - "minimum": 0, - "maximum": 1, - "decimal": 3 - } - ] - }, - { - "type": "boolean", - "key": "override_display", - "label": "Override display options" - } - ] - }, { "type": "splitter" - }, - { - "type": "dict", - "key": "Generic", - "children": [ - { - "type": "label", - "label": "Generic" - }, - { - "type": "boolean", - "key": "isolate_view", - "label": " Isolate view" - }, - { - "type": "boolean", - "key": "off_screen", - "label": " Off Screen" - } - ] - }, - { - "type": "dict", - "key": "IO", - "children": [ - { - "type": "label", - "label": "IO" - }, - { - "type": "text", - "key": "name", - "label": "Name" - }, - { - "type": "boolean", - "key": "open_finished", - "label": "Open finished" - }, - { - "type": "boolean", - "key": "raw_frame_numbers", - "label": "Raw frame numbers" - }, - { - "type": "list", - "key": "recent_playblasts", - "label": "Recent Playblasts", - "object_type": "text" - }, - { - "type": "boolean", - "key": "save_file", - "label": "Save file" - } - ] - }, - { - "type": "dict", - "key": "PanZoom", - "children": [ - { - "type": "boolean", - "key": "pan_zoom", - "label": " Pan Zoom" - } - ] - }, - { - "type": "splitter" - }, - { - "type": "dict", - "key": "Renderer", - "children": [ - { - "type": "label", - "label": "Renderer" - }, - { - "type": "text", - "key": "rendererName", - "label": " Renderer name" - } - ] - }, - { - "type": "dict", - "key": "Resolution", - "children": [ - { - "type": "splitter" - }, - { - "type": "label", - "label": "Resolution" - }, - { - "type": "number", - "key": "width", - "label": " Width", - "decimal": 0, - "minimum": 0, - "maximum": 99999 - }, - { - "type": "number", - "key": "height", - "label": "Height", - "decimal": 0, - "minimum": 0, - "maximum": 99999 - }, - { - "type": "number", - "key": "percent", - "label": "percent", - "decimal": 1, - "minimum": 0, - "maximum": 200 - }, - { - "type": "text", - "key": "mode", - "label": "Mode" - } - ] - }, - { - "type": "splitter" - }, - { - "type": "dict", - "key": "Time Range", - "children": [ - { - "type": "label", - "label": "Time Range" - }, - { - "type": "number", - "key": "start_frame", - "label": " Start frame", - "decimal": 0, - "minimum": 0, - "maximum": 999999 - }, - { - "type": "number", - "key": "end_frame", - "label": "End frame", - "decimal": 0, - "minimum": 0, - "maximum": 999999 - }, - { - "type": "text", - "key": "frame", - "label": "Frame" - }, - { - "type": "text", - "key": "time", - "label": "Time" - } - ] - }, - { - "type": "dict", - "collapsible": true, - "key": "Viewport Options", - "label": "Viewport Options", - "children": [ - { - "type": "boolean", - "key": "cameras", - "label": "cameras" - }, - { - "type": "boolean", - "key": "clipGhosts", - "label": "clipGhosts" - }, - { - "type": "boolean", - "key": "controlVertices", - "label": "controlVertices" - }, - { - "type": "boolean", - "key": "deformers", - "label": "deformers" - }, - { - "type": "boolean", - "key": "dimensions", - "label": "dimensions" - }, - { - "type": "number", - "key": "displayLights", - "label": "displayLights", - "decimal": 0, - "minimum": 0, - "maximum": 10 - }, - { - "type": "boolean", - "key": "dynamicConstraints", - "label": "dynamicConstraints" - }, - { - "type": "boolean", - "key": "dynamics", - "label": "dynamics" - }, - { - "type": "boolean", - "key": "fluids", - "label": "fluids" - }, - { - "type": "boolean", - "key": "follicles", - "label": "follicles" - }, - { - "type": "boolean", - "key": "gpuCacheDisplayFilter", - "label": "gpuCacheDisplayFilter" - }, - { - "type": "boolean", - "key": "greasePencils", - "label": "greasePencils" - }, - { - "type": "boolean", - "key": "grid", - "label": "grid" - }, - { - "type": "boolean", - "key": "hairSystems", - "label": "hairSystems" - }, - { - "type": "boolean", - "key": "handles", - "label": "handles" - }, - { - "type": "boolean", - "key": "high_quality", - "label": "high_quality" - }, - { - "type": "boolean", - "key": "hud", - "label": "hud" - }, - { - "type": "boolean", - "key": "hulls", - "label": "hulls" - }, - { - "type": "boolean", - "key": "ikHandles", - "label": "ikHandles" - }, - { - "type": "boolean", - "key": "imagePlane", - "label": "imagePlane" - }, - { - "type": "boolean", - "key": "joints", - "label": "joints" - }, - { - "type": "boolean", - "key": "lights", - "label": "lights" - }, - { - "type": "boolean", - "key": "locators", - "label": "locators" - }, - { - "type": "boolean", - "key": "manipulators", - "label": "manipulators" - }, - { - "type": "boolean", - "key": "motionTrails", - "label": "motionTrails" - }, - { - "type": "boolean", - "key": "nCloths", - "label": "nCloths" - }, - { - "type": "boolean", - "key": "nParticles", - "label": "nParticles" - }, - { - "type": "boolean", - "key": "nRigids", - "label": "nRigids" - }, - { - "type": "boolean", - "key": "nurbsCurves", - "label": "nurbsCurves" - }, - { - "type": "boolean", - "key": "nurbsSurfaces", - "label": "nurbsSurfaces" - }, - { - "type": "boolean", - "key": "override_viewport_options", - "label": "override_viewport_options" - }, - { - "type": "boolean", - "key": "particleInstancers", - "label": "particleInstancers" - }, - { - "type": "boolean", - "key": "pivots", - "label": "pivots" - }, - { - "type": "boolean", - "key": "planes", - "label": "planes" - }, - { - "type": "boolean", - "key": "pluginShapes", - "label": "pluginShapes" - }, - { - "type": "boolean", - "key": "polymeshes", - "label": "polymeshes" - }, - { - "type": "boolean", - "key": "shadows", - "label": "shadows" - }, - { - "type": "boolean", - "key": "strokes", - "label": "strokes" - }, - { - "type": "boolean", - "key": "subdivSurfaces", - "label": "subdivSurfaces" - }, - { - "type": "boolean", - "key": "textures", - "label": "textures" - }, - { - "type": "boolean", - "key": "twoSidedLighting", - "label": "twoSidedLighting" - } - ] - }, - { - "type": "dict", - "collapsible": true, - "key": "Camera Options", - "label": "Camera Options", - "children": [ - { - "type": "boolean", - "key": "displayGateMask", - "label": "displayGateMask" - }, - { - "type": "boolean", - "key": "displayResolution", - "label": "displayResolution" - }, - { - "type": "boolean", - "key": "displayFilmGate", - "label": "displayFilmGate" - }, - { - "type": "boolean", - "key": "displayFieldChart", - "label": "displayFieldChart" - }, - { - "type": "boolean", - "key": "displaySafeAction", - "label": "displaySafeAction" - }, - { - "type": "boolean", - "key": "displaySafeTitle", - "label": "displaySafeTitle" - }, - { - "type": "boolean", - "key": "displayFilmPivot", - "label": "displayFilmPivot" - }, - { - "type": "boolean", - "key": "displayFilmOrigin", - "label": "displayFilmOrigin" - }, - { - "type": "number", - "key": "overscan", - "label": "overscan", - "decimal": 1, - "minimum": 0, - "maximum": 10 - } - ] } ] }, { - "type": "dict-modifiable", - "key": "ext_mapping", - "label": "Extension Mapping", - "object_type": { - "type": "text" - } + "type": "dict", + "key": "Display Options", + "children": [ + { + "type": "label", + "label": "Display Options" + }, + { + "type": "list-strict", + "key": "background", + "label": "Background Color: ", + "object_types": [ + { + "label": "Red", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, + { + "label": "Green", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, + { + "label": "Blue", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + } + ] + }, + { + "type": "list-strict", + "key": "backgroundBottom", + "label": "Background Bottom: ", + "object_types": [ + { + "label": "Red", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, + { + "label": "Green", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, + { + "label": "Blue", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + } + ] + }, + { + "type": "list-strict", + "key": "backgroundTop", + "label": "Background Top: ", + "object_types": [ + { + "label": "Red", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, + { + "label": "Green", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + }, + { + "label": "Blue", + "type": "number", + "minimum": 0, + "maximum": 1, + "decimal": 3 + } + ] + }, + { + "type": "boolean", + "key": "override_display", + "label": "Override display options" + } + ] + }, + { + "type": "splitter" + }, + { + "type": "dict", + "key": "Generic", + "children": [ + { + "type": "label", + "label": "Generic" + }, + { + "type": "boolean", + "key": "isolate_view", + "label": " Isolate view" + }, + { + "type": "boolean", + "key": "off_screen", + "label": " Off Screen" + } + ] + }, + { + "type": "dict", + "key": "IO", + "children": [ + { + "type": "label", + "label": "IO" + }, + { + "type": "text", + "key": "name", + "label": "Name" + }, + { + "type": "boolean", + "key": "open_finished", + "label": "Open finished" + }, + { + "type": "boolean", + "key": "raw_frame_numbers", + "label": "Raw frame numbers" + }, + { + "type": "list", + "key": "recent_playblasts", + "label": "Recent Playblasts", + "object_type": "text" + }, + { + "type": "boolean", + "key": "save_file", + "label": "Save file" + } + ] + }, + { + "type": "dict", + "key": "PanZoom", + "children": [ + { + "type": "boolean", + "key": "pan_zoom", + "label": " Pan Zoom" + } + ] + }, + { + "type": "splitter" + }, + { + "type": "dict", + "key": "Renderer", + "children": [ + { + "type": "label", + "label": "Renderer" + }, + { + "type": "text", + "key": "rendererName", + "label": " Renderer name" + } + ] + }, + { + "type": "dict", + "key": "Resolution", + "children": [ + { + "type": "splitter" + }, + { + "type": "label", + "label": "Resolution" + }, + { + "type": "number", + "key": "width", + "label": " Width", + "decimal": 0, + "minimum": 0, + "maximum": 99999 + }, + { + "type": "number", + "key": "height", + "label": "Height", + "decimal": 0, + "minimum": 0, + "maximum": 99999 + }, + { + "type": "number", + "key": "percent", + "label": "percent", + "decimal": 1, + "minimum": 0, + "maximum": 200 + }, + { + "type": "text", + "key": "mode", + "label": "Mode" + } + ] + }, + { + "type": "splitter" + }, + { + "type": "dict", + "key": "Time Range", + "children": [ + { + "type": "label", + "label": "Time Range" + }, + { + "type": "number", + "key": "start_frame", + "label": " Start frame", + "decimal": 0, + "minimum": 0, + "maximum": 999999 + }, + { + "type": "number", + "key": "end_frame", + "label": "End frame", + "decimal": 0, + "minimum": 0, + "maximum": 999999 + }, + { + "type": "text", + "key": "frame", + "label": "Frame" + }, + { + "type": "text", + "key": "time", + "label": "Time" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "key": "Viewport Options", + "label": "Viewport Options", + "children": [ + { + "type": "boolean", + "key": "cameras", + "label": "cameras" + }, + { + "type": "boolean", + "key": "clipGhosts", + "label": "clipGhosts" + }, + { + "type": "boolean", + "key": "controlVertices", + "label": "controlVertices" + }, + { + "type": "boolean", + "key": "deformers", + "label": "deformers" + }, + { + "type": "boolean", + "key": "dimensions", + "label": "dimensions" + }, + { + "type": "number", + "key": "displayLights", + "label": "displayLights", + "decimal": 0, + "minimum": 0, + "maximum": 10 + }, + { + "type": "boolean", + "key": "dynamicConstraints", + "label": "dynamicConstraints" + }, + { + "type": "boolean", + "key": "dynamics", + "label": "dynamics" + }, + { + "type": "boolean", + "key": "fluids", + "label": "fluids" + }, + { + "type": "boolean", + "key": "follicles", + "label": "follicles" + }, + { + "type": "boolean", + "key": "gpuCacheDisplayFilter", + "label": "gpuCacheDisplayFilter" + }, + { + "type": "boolean", + "key": "greasePencils", + "label": "greasePencils" + }, + { + "type": "boolean", + "key": "grid", + "label": "grid" + }, + { + "type": "boolean", + "key": "hairSystems", + "label": "hairSystems" + }, + { + "type": "boolean", + "key": "handles", + "label": "handles" + }, + { + "type": "boolean", + "key": "high_quality", + "label": "high_quality" + }, + { + "type": "boolean", + "key": "hud", + "label": "hud" + }, + { + "type": "boolean", + "key": "hulls", + "label": "hulls" + }, + { + "type": "boolean", + "key": "ikHandles", + "label": "ikHandles" + }, + { + "type": "boolean", + "key": "imagePlane", + "label": "imagePlane" + }, + { + "type": "boolean", + "key": "joints", + "label": "joints" + }, + { + "type": "boolean", + "key": "lights", + "label": "lights" + }, + { + "type": "boolean", + "key": "locators", + "label": "locators" + }, + { + "type": "boolean", + "key": "manipulators", + "label": "manipulators" + }, + { + "type": "boolean", + "key": "motionTrails", + "label": "motionTrails" + }, + { + "type": "boolean", + "key": "nCloths", + "label": "nCloths" + }, + { + "type": "boolean", + "key": "nParticles", + "label": "nParticles" + }, + { + "type": "boolean", + "key": "nRigids", + "label": "nRigids" + }, + { + "type": "boolean", + "key": "nurbsCurves", + "label": "nurbsCurves" + }, + { + "type": "boolean", + "key": "nurbsSurfaces", + "label": "nurbsSurfaces" + }, + { + "type": "boolean", + "key": "override_viewport_options", + "label": "override_viewport_options" + }, + { + "type": "boolean", + "key": "particleInstancers", + "label": "particleInstancers" + }, + { + "type": "boolean", + "key": "pivots", + "label": "pivots" + }, + { + "type": "boolean", + "key": "planes", + "label": "planes" + }, + { + "type": "boolean", + "key": "pluginShapes", + "label": "pluginShapes" + }, + { + "type": "boolean", + "key": "polymeshes", + "label": "polymeshes" + }, + { + "type": "boolean", + "key": "shadows", + "label": "shadows" + }, + { + "type": "boolean", + "key": "strokes", + "label": "strokes" + }, + { + "type": "boolean", + "key": "subdivSurfaces", + "label": "subdivSurfaces" + }, + { + "type": "boolean", + "key": "textures", + "label": "textures" + }, + { + "type": "boolean", + "key": "twoSidedLighting", + "label": "twoSidedLighting" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "key": "Camera Options", + "label": "Camera Options", + "children": [ + { + "type": "boolean", + "key": "displayGateMask", + "label": "displayGateMask" + }, + { + "type": "boolean", + "key": "displayResolution", + "label": "displayResolution" + }, + { + "type": "boolean", + "key": "displayFilmGate", + "label": "displayFilmGate" + }, + { + "type": "boolean", + "key": "displayFieldChart", + "label": "displayFieldChart" + }, + { + "type": "boolean", + "key": "displaySafeAction", + "label": "displaySafeAction" + }, + { + "type": "boolean", + "key": "displaySafeTitle", + "label": "displaySafeTitle" + }, + { + "type": "boolean", + "key": "displayFilmPivot", + "label": "displayFilmPivot" + }, + { + "type": "boolean", + "key": "displayFilmOrigin", + "label": "displayFilmOrigin" + }, + { + "type": "number", + "key": "overscan", + "label": "overscan", + "decimal": 1, + "minimum": 0, + "maximum": 10 + } + ] } ] } diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json new file mode 100644 index 0000000000..575e04c85d --- /dev/null +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_create.json @@ -0,0 +1,86 @@ +{ + "type": "dict", + "collapsible": true, + "key": "create", + "label": "Creator plugins", + "children": [ + { + "type": "schema_template", + "name": "template_create_plugin", + "template_data": [ + { + "key": "CreateAnimation", + "label": "Create Animation" + }, + { + "key": "CreateAss", + "label": "Create Ass" + }, + { + "key": "CreateAssembly", + "label": "Create Assembly" + }, + { + "key": "CreateCamera", + "label": "Create Camera" + }, + { + "key": "CreateLayout", + "label": "Create Layout" + }, + { + "key": "CreateLook", + "label": "Create Look" + }, + { + "key": "CreateMayaScene", + "label": "Create Maya Scene" + }, + { + "key": "CreateModel", + "label": "Create Model" + }, + { + "key": "CreatePointCache", + "label": "Create Cache" + }, + { + "key": "CreateRender", + "label": "Create Render" + }, + { + "key": "CreateRenderSetup", + "label": "Create Render Setup" + }, + { + "key": "CreateReview", + "label": "Create Review" + }, + { + "key": "CreateRig", + "label": "Create Rig" + }, + { + "key": "CreateSetDress", + "label": "Create Set Dress" + }, + { + "key": "CreateUnrealStaticMesh", + "label": "Create Unreal - Static Mesh" + }, + { + "key": "CreateVrayProxy", + "label": "Create VRay Proxy" + }, + { + "key": "CreateVRayScene", + "label": "Create VRay Scene" + }, + { + "key": "CreateYetiRig", + "label": "Create Yeti Rig" + } + ] + } + ] +} diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_load.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_load.json index dd9d0508b4..3615c1477c 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_load.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_load.json @@ -151,6 +151,32 @@ ] } ] + }, + { + "type": "schema_template", + "name": "template_loader_plugin", + "template_data": [ + { + "key": "ReferenceLoader", + "label": "Reference Loader" + }, + { + "key": "AudioLoader", + "label": "Audio Loader" + }, + { + "key": "GpuCacheLoader", + "label": "GpuCache Loader" + }, + { + "key": "ImagePlaneLoader", + "label": "Imageplane Loader" + }, + { + "key": "MatchmoveLoader", + "label": "Matchmove Loader" + } + ] } ] } diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json index 0d705d3d02..58a21c185a 100644 --- a/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json @@ -26,71 +26,9 @@ }, { "type": "label", - "label": "Collectors" - }, - { - "type": "dict", - "collapsible": true, - "key": "ValidateCameraAttributes", - "label": "Validate Camera Attributes", - "checkbox_key": "enabled", - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "optional", - "label": "Optional" - } - ] - }, - { - "type": "dict", - "collapsible": true, - "key": "ValidateModelName", - "label": "Validate Model Name", - "checkbox_key": "enabled", - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "label", - "label": "Path to material file defining list of material names to check. This is material name per line simple text file.
It will be checked against named group shader in your Validation regex.

For example:
^.*(?P=<shader>.+)_GEO

" - }, - { - "type": "path-widget", - "key": "material_file", - "label": "Material File", - "multiplatform": true, - "multipath": false - }, - { - "type": "text", - "key": "regex", - "label": "Validation regex" - } - ] - }, - { - "type": "dict", - "collapsible": true, - "key": "ValidateAssemblyName", - "label": "Validate Assembly Name", - "checkbox_key": "enabled", - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - } - ] + "label": "Validators" }, + { "type": "dict", "collapsible": true, @@ -114,20 +52,7 @@ } ] }, - { - "type": "dict", - "collapsible": true, - "key": "ValidateMeshHasOverlappingUVs", - "label": "ValidateMeshHasOverlappingUVs", - "checkbox_key": "enabled", - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - } - ] - }, + { "type": "dict", "collapsible": true, @@ -147,6 +72,169 @@ } ] }, + { + "type": "collapsible-wrap", + "label": "Model", + "children": [ + { + "type": "dict", + "collapsible": true, + "key": "ValidateModelName", + "label": "Validate Model Name", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "label", + "label": "Path to material file defining list of material names to check. This is material name per line simple text file.
It will be checked against named group shader in your Validation regex.

For example:
^.*(?P=<shader>.+)_GEO

" + }, + { + "type": "path-widget", + "key": "material_file", + "label": "Material File", + "multiplatform": true, + "multipath": false + }, + { + "type": "text", + "key": "regex", + "label": "Validation regex" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "key": "ValidateTransformNamingSuffix", + "label": "ValidateTransformNamingSuffix", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "label", + "label": "Validates transform suffix based on the type of its children shapes." + }, + { + "type": "raw-json", + "key": "SUFFIX_NAMING_TABLE", + "label": "Suffix Naming Table" + }, + { + "type": "boolean", + "key": "ALLOW_IF_NOT_IN_SUFFIX_TABLE", + "label": "Allow if suffix not in table" + } + ] + }, + { + "type": "schema_template", + "name": "template_publish_plugin", + "template_data": [ + { + "key": "ValidateColorSets", + "label": "ValidateColorSets" + }, + { + "key": "ValidateMeshHasOverlappingUVs", + "label": "ValidateMeshHasOverlappingUVs" + }, + { + "key": "ValidateMeshArnoldAttributes", + "label": "ValidateMeshArnoldAttributes" + }, + { + "key": "ValidateMeshShaderConnections", + "label": "ValidateMeshShaderConnections" + }, + { + "key": "ValidateMeshSingleUVSet", + "label": "ValidateMeshSingleUVSet" + }, + { + "key": "ValidateMeshHasUVs", + "label": "ValidateMeshHasUVs" + }, + { + "key": "ValidateMeshLaminaFaces", + "label": "ValidateMeshLaminaFaces" + }, + { + "key": "ValidateMeshNonManifold", + "label": "ValidateMeshNonManifold" + }, + { + "key": "ValidateMeshUVSetMap1", + "label": "ValidateMeshUVSetMap1", + "docstring": "Validate model's default uv set exists and is named 'map1'.

In Maya meshes by default have a uv set named 'map1' that cannot be deleted. It can be renamed, however,
introducing some issues with some renderers. As such we ensure the first (default) UV set index is named 'map1'." + }, + { + "key": "ValidateMeshVerticesHaveEdges", + "label": "ValidateMeshVerticesHaveEdges" + }, + { + "key": "ValidateNoAnimation", + "label": "ValidateNoAnimation", + "docstring": "Ensure no keyframes on nodes in the Instance.
Even though a Model would extract without animCurves correctly this avoids getting different
output from a model when extracted from a different frame than the first frame. (Might be overly restrictive though)." + }, + { + "key": "ValidateNoNamespace", + "label": "ValidateNoNamespace" + }, + { + "key": "ValidateNoNullTransforms", + "label": "ValidateNoNullTransforms" + }, + { + "key": "ValidateNoUnknownNodes", + "label": "ValidateNoUnknownNodes" + }, + { + "key": "ValidateNodeNoGhosting", + "label": "ValidateNodeNoGhosting" + }, + { + "key": "ValidateShapeDefaultNames", + "label": "ValidateShapeDefaultNames" + }, + { + "key": "ValidateShapeRenderStats", + "label": "ValidateShapeRenderStats" + }, + { + "key": "ValidateTransformZero", + "label": "ValidateTransformZero" + } + ] + } + ] + }, + { + "type": "schema_template", + "name": "template_publish_plugin", + "template_data": [ + { + "key": "ValidateCameraAttributes", + "label": "Validate Camera Attributes", + "docstring": "" + }, + { + "key": "ValidateAssemblyName", + "label": "Validate Assembly Name" + }, + { + "key": "ValidateAssRelativePaths", + "label": "ValidateAssRelativePaths" + } + ] + }, { "type": "splitter" }, diff --git a/pype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json b/pype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json new file mode 100644 index 0000000000..0e3770ac78 --- /dev/null +++ b/pype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json @@ -0,0 +1,180 @@ +{ + "type": "dict", + "collapsible": true, + "key": "publish", + "label": "Publish plugins", + "children": [ + { + "type": "label", + "label": "Collectors" + }, + { + "type": "dict", + "collapsible": true, + "key": "PreCollectNukeInstances", + "label": "PreCollectNukeInstances", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "sync_workfile_version", + "label": "Sync Version from workfile" + } + ] + }, + { + "type": "splitter" + }, + { + "type": "label", + "label": "Validators" + }, + { + "type": "dict", + "collapsible": true, + "checkbox_key": "enabled", + "key": "ValidateKnobs", + "label": "ValidateKnobs", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "raw-json", + "key": "knobs", + "label": "Knobs" + } + ] + }, + { + "type": "schema_template", + "name": "template_publish_plugin", + "template_data": [ + { + "key": "ValidateOutputResolution", + "label": "Validate Output Resolution" + }, + { + "key": "ValidateGizmo", + "label": "Validate Gizmo (Group)" + }, + { + "key": "ValidateScript", + "label": "Validate script settings" + }, + { + "key": "ValidateNukeWriteBoundingBox", + "label": "Validate and Write Bounding Box" + } + ] + }, + { + "type": "splitter" + }, + { + "type": "label", + "label": "Extractors" + }, + { + "type": "dict", + "collapsible": true, + "checkbox_key": "enabled", + "key": "ExtractThumbnail", + "label": "ExtractThumbnail", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "raw-json", + "key": "nodes", + "label": "Nodes" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "checkbox_key": "enabled", + "key": "ExtractReviewDataLut", + "label": "ExtractReviewDataLut", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "checkbox_key": "enabled", + "key": "ExtractReviewDataMov", + "label": "ExtractReviewDataMov", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "viewer_lut_raw", + "label": "Viewer LUT raw" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "key": "ExtractSlateFrame", + "label": "ExtractSlateFrame", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "viewer_lut_raw", + "label": "Viewer LUT raw" + } + ] + }, + { + "type": "dict", + "collapsible": true, + "key": "NukeSubmitDeadline", + "label": "NukeSubmitDeadline", + "is_group": true, + "children": [ + { + "type": "number", + "key": "deadline_priority", + "label": "deadline_priority" + }, + { + "type": "text", + "key": "deadline_pool", + "label": "deadline_pool" + }, + { + "type": "text", + "key": "deadline_pool_secondary", + "label": "deadline_pool_secondary" + }, + { + "type": "number", + "key": "deadline_chunk_size", + "label": "deadline_chunk_size" + } + ] + } + ] +} diff --git a/pype/settings/entities/schemas/projects_schema/schemas/template_create_plugin.json b/pype/settings/entities/schemas/projects_schema/schemas/template_create_plugin.json new file mode 100644 index 0000000000..14d15e7840 --- /dev/null +++ b/pype/settings/entities/schemas/projects_schema/schemas/template_create_plugin.json @@ -0,0 +1,22 @@ +[ + { + "type": "dict", + "collapsible": true, + "key": "{key}", + "label": "{label}", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "list", + "key": "defaults", + "label": "Default Subsets", + "object_type": "text" + } + ] + } +] diff --git a/pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin.json b/pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin.json new file mode 100644 index 0000000000..20dca6df17 --- /dev/null +++ b/pype/settings/entities/schemas/projects_schema/schemas/template_loader_plugin.json @@ -0,0 +1,22 @@ +[ + { + "type": "dict", + "collapsible": true, + "key": "{key}", + "label": "{label}", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "list", + "key": "representations", + "label": "Representations", + "object_type": "text" + } + ] + } +] diff --git a/pype/settings/entities/schemas/projects_schema/schemas/template_publish_plugin.json b/pype/settings/entities/schemas/projects_schema/schemas/template_publish_plugin.json new file mode 100644 index 0000000000..88151f7534 --- /dev/null +++ b/pype/settings/entities/schemas/projects_schema/schemas/template_publish_plugin.json @@ -0,0 +1,30 @@ +[ + { + "__default_values__": { + "docstring": "" + } + }, + { + "type": "dict", + "collapsible": true, + "key": "{key}", + "label": "{label}", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "optional", + "label": "Optional" + }, + { + "type": "label", + "label": "{docstring}" + } + ] + } +] \ No newline at end of file diff --git a/pype/tools/settings/settings/widgets/item_widgets.py b/pype/tools/settings/settings/widgets/item_widgets.py index 4299d3dee7..cf290eb417 100644 --- a/pype/tools/settings/settings/widgets/item_widgets.py +++ b/pype/tools/settings/settings/widgets/item_widgets.py @@ -46,8 +46,8 @@ class DictImmutableKeysWidget(BaseWidget): self._ui_item_base() label = self.entity.label - self.widget_mapping = {} - self.wrapper_widgets_by_id = {} + self._parent_widget_by_entity_id = {} + self._added_wrapper_ids = set() self._prepare_entity_layouts( self.entity.gui_layout, self.content_widget ) @@ -65,7 +65,7 @@ class DictImmutableKeysWidget(BaseWidget): for child in children: if not isinstance(child, dict): if child is not self.checkbox_child: - self.widget_mapping[child.id] = widget + self._parent_widget_by_entity_id[child.id] = widget continue if child["type"] == "collapsible-wrap": @@ -79,9 +79,8 @@ class DictImmutableKeysWidget(BaseWidget): "Unknown Wrapper type \"{}\"".format(child["type"]) ) - self.widget_mapping[wrapper.id] = widget - self.wrapper_widgets_by_id[wrapper.id] = wrapper - self.add_widget_to_layout(wrapper) + self._parent_widget_by_entity_id[wrapper.id] = widget + self._prepare_entity_layouts(child["children"], wrapper) def _ui_item_base(self): @@ -162,9 +161,12 @@ class DictImmutableKeysWidget(BaseWidget): else: map_id = widget.entity.id - wrapper = self.widget_mapping[map_id] + wrapper = self._parent_widget_by_entity_id[map_id] if wrapper is not self.content_widget: wrapper.add_widget_to_layout(widget, label) + if wrapper.id not in self._added_wrapper_ids: + self.add_widget_to_layout(wrapper) + self._added_wrapper_ids.add(wrapper.id) return row = self.content_layout.rowCount()