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

Commit

Permalink
Merge branch 'develop' into feature/AY-742_copy-to-breakdown-project
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubjezek001 authored Apr 26, 2024
2 parents 0b36fa3 + 41e72ff commit 7901009
Show file tree
Hide file tree
Showing 76 changed files with 996 additions and 246 deletions.
12 changes: 6 additions & 6 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ body:
label: Version
description: What version are you running? Look to OpenPype Tray
options:
- 3.18.9-nightly.9
- 3.18.9-nightly.8
- 3.18.9-nightly.7
- 3.18.9-nightly.6
- 3.18.9-nightly.5
- 3.18.9-nightly.4
- 3.18.9-nightly.3
- 3.18.9-nightly.2
- 3.18.9-nightly.1
Expand Down Expand Up @@ -129,12 +135,6 @@ body:
- 3.16.0
- 3.16.0-nightly.2
- 3.16.0-nightly.1
- 3.15.12
- 3.15.12-nightly.4
- 3.15.12-nightly.3
- 3.15.12-nightly.2
- 3.15.12-nightly.1
- 3.15.11
validations:
required: true
- type: dropdown
Expand Down
4 changes: 3 additions & 1 deletion openpype/hosts/hiero/api/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from .lib import (
sync_avalon_data_to_workfile,
launch_workfiles_app,
selection_changed_timeline,
before_project_save,
apply_colorspace_project
)
from .tags import add_tags_to_workfile
from .menu import update_menu_task_label
Expand Down Expand Up @@ -42,6 +42,8 @@ def afterNewProjectCreated(event):
# reset workfiles startup not to open any more in session
os.environ["WORKFILES_STARTUP"] = "0"

apply_colorspace_project()


def beforeProjectLoad(event):
log.info("before project load event...")
Expand Down
89 changes: 75 additions & 14 deletions openpype/hosts/hiero/api/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ def flatten(list_):


def get_current_project(remove_untitled=False):
projects = flatten(hiero.core.projects())
projects = hiero.core.projects()
if not remove_untitled:
return next(iter(projects))
return projects[0]

# if remove_untitled
for proj in projects:
Expand Down Expand Up @@ -243,8 +243,13 @@ def get_track_items(
# collect all available active sequence track items
if not return_list:
sequence = get_current_sequence(name=sequence_name)
# get all available tracks from sequence
tracks = list(sequence.audioTracks()) + list(sequence.videoTracks())

tracks = []
if sequence is not None:
# get all available tracks from sequence
tracks = list(sequence.audioTracks())
tracks += list(sequence.videoTracks())

# loop all tracks
for track in tracks:
if check_locked and track.isLocked():
Expand Down Expand Up @@ -1039,18 +1044,68 @@ def _set_hrox_project_knobs(doc, **knobs):


def apply_colorspace_project():
project_name = get_current_project_name()
# get path the the active projects
project = get_current_project(remove_untitled=True)
current_file = project.path()

# close the active project
project.close()

"""Apply colorspaces from settings.
Due to not being able to set the project settings through the Python API,
we need to do use some dubious code to find the widgets and set them. It is
possible to set the project settings without traversing through the widgets
but it involves reading the hrox files from disk with XML, so no in-memory
support. See https://community.foundry.com/discuss/topic/137771/change-a-project-s-default-color-transform-with-python # noqa
for more details.
"""
# get presets for hiero
project_name = get_current_project_name()
imageio = get_project_settings(project_name)["hiero"]["imageio"]
presets = imageio.get("workfile")

# Open Project Settings UI.
for act in hiero.ui.registeredActions():
if act.objectName() == "foundry.project.settings":
act.trigger()

# Find widgets from their sibling label.
labels = {
"Working Space:": "workingSpace",
"Viewer:": "viewerLut",
"Thumbnails:": "thumbnailLut",
"Monitor Out:": "monitorOutLut",
"8 Bit Files:": "eightBitLut",
"16 Bit Files:": "sixteenBitLut",
"Log Files:": "logLut",
"Floating Point Files:": "floatLut"
}
widgets = {x: None for x in labels.values()}

def _recursive_children(widget, labels, widgets):
children = widget.children()
for count, child in enumerate(children):
if isinstance(child, QtWidgets.QLabel):
if child.text() in labels.keys():
widgets[labels[child.text()]] = children[count + 1]
_recursive_children(child, labels, widgets)

app = QtWidgets.QApplication.instance()
title = "Project Settings"
for widget in app.topLevelWidgets():
if isinstance(widget, QtWidgets.QMainWindow):
if widget.windowTitle() != title:
continue
_recursive_children(widget, labels, widgets)
widget.close()

msg = "Setting value \"{}\" is not a valid option for \"{}\""
for key, widget in widgets.items():
options = [widget.itemText(i) for i in range(widget.count())]
setting_value = presets[key]
assert setting_value in options, msg.format(setting_value, key)
widget.setCurrentText(presets[key])

# This code block is for setting up project colorspaces for files on disk.
# Due to not having Python API access to set the project settings, the
# Foundry recommended way is to modify the hrox files on disk with XML. See
# this forum thread for more details;
# https://community.foundry.com/discuss/topic/137771/change-a-project-s-default-color-transform-with-python # noqa
'''
# backward compatibility layer
# TODO: remove this after some time
config_data = get_imageio_config(
Expand All @@ -1063,6 +1118,13 @@ def apply_colorspace_project():
"ocioConfigName": "custom"
})
# get path the the active projects
project = get_current_project()
current_file = project.path()
msg = "The project needs to be saved to disk to apply colorspace settings."
assert current_file, msg
# save the workfile as subversion "comment:_colorspaceChange"
split_current_file = os.path.splitext(current_file)
copy_current_file = current_file
Expand Down Expand Up @@ -1105,6 +1167,7 @@ def apply_colorspace_project():
# open the file as current project
hiero.core.openProject(copy_current_file)
'''


def apply_colorspace_clips():
Expand All @@ -1114,10 +1177,8 @@ def apply_colorspace_clips():

# get presets for hiero
imageio = get_project_settings(project_name)["hiero"]["imageio"]
from pprint import pprint

presets = imageio.get("regexInputs", {}).get("inputs", {})
pprint(presets)
for clip in clips:
clip_media_source_path = clip.mediaSource().firstpath()
clip_name = clip.name()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
import openpype.hosts.maya.api.action
from openpype.pipeline.publish import (
PublishValidationError,
ValidateContentsOrder
ValidateContentsOrder,
OptionalPyblishPluginMixin
)
from maya import cmds


class ValidateAnimatedReferenceRig(pyblish.api.InstancePlugin):
class ValidateAnimatedReferenceRig(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
"""Validate all nodes in skeletonAnim_SET are referenced"""

order = ValidateContentsOrder
Expand All @@ -16,8 +18,11 @@ class ValidateAnimatedReferenceRig(pyblish.api.InstancePlugin):
label = "Animated Reference Rig"
accepted_controllers = ["transform", "locator"]
actions = [openpype.hosts.maya.api.action.SelectInvalidAction]
optional = False

def process(self, instance):
if not self.is_active(instance.data):
return
animated_sets = instance.data.get("animated_skeleton", [])
if not animated_sets:
self.log.debug(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
import openpype.hosts.maya.api.action
from openpype.pipeline.publish import (
PublishValidationError,
ValidateContentsOrder
ValidateContentsOrder,
OptionalPyblishPluginMixin
)


class ValidateAnimationContent(pyblish.api.InstancePlugin):
"""Adheres to the content of 'animation' family
class ValidateAnimationContent(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
"""Adheres to the content of 'animation' product type
- Must have collected `out_hierarchy` data.
- All nodes in `out_hierarchy` must be in the instance.
Expand All @@ -19,6 +21,7 @@ class ValidateAnimationContent(pyblish.api.InstancePlugin):
families = ["animation"]
label = "Animation Content"
actions = [openpype.hosts.maya.api.action.SelectInvalidAction]
optional = False

@classmethod
def get_invalid(cls, instance):
Expand Down Expand Up @@ -48,6 +51,8 @@ def get_invalid(cls, instance):
return invalid

def process(self, instance):
if not self.is_active(instance.data):
return
invalid = self.get_invalid(instance)
if invalid:
raise PublishValidationError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
from openpype.pipeline.publish import (
RepairAction,
ValidateContentsOrder,
PublishValidationError
PublishValidationError,
OptionalPyblishPluginMixin
)


class ValidateOutRelatedNodeIds(pyblish.api.InstancePlugin):
class ValidateOutRelatedNodeIds(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
"""Validate if deformed shapes have related IDs to the original shapes
When a deformer is applied in the scene on a referenced mesh that already
Expand All @@ -28,10 +30,12 @@ class ValidateOutRelatedNodeIds(pyblish.api.InstancePlugin):
openpype.hosts.maya.api.action.SelectInvalidAction,
RepairAction
]
optional = False

def process(self, instance):
"""Process all meshes"""

if not self.is_active(instance.data):
return
# Ensure all nodes have a cbId and a related ID to the original shapes
# if a deformer has been created on the shape
invalid = self.get_invalid(instance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,25 @@
from openpype.pipeline.publish import (
RepairAction,
ValidateContentsOrder,
PublishValidationError
PublishValidationError,
OptionalPyblishPluginMixin
)


class ValidateAssRelativePaths(pyblish.api.InstancePlugin):
class ValidateAssRelativePaths(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
"""Ensure exporting ass file has set relative texture paths"""

order = ValidateContentsOrder
hosts = ['maya']
families = ['ass']
label = "ASS has relative texture paths"
actions = [RepairAction]
optional = False

def process(self, instance):
if not self.is_active(instance.data):
return
# we cannot ask this until user open render settings as
# `defaultArnoldRenderOptions` doesn't exist
errors = []
Expand Down
10 changes: 7 additions & 3 deletions openpype/hosts/maya/plugins/publish/validate_assembly_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
import maya.cmds as cmds
import openpype.hosts.maya.api.action
from openpype.pipeline.publish import (
PublishValidationError
PublishValidationError,
OptionalPyblishPluginMixin
)


class ValidateAssemblyName(pyblish.api.InstancePlugin):
class ValidateAssemblyName(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
""" Ensure Assembly name ends with `GRP`
Check if assembly name ends with `_GRP` string.
Expand All @@ -17,6 +19,7 @@ class ValidateAssemblyName(pyblish.api.InstancePlugin):
families = ["assembly"]
actions = [openpype.hosts.maya.api.action.SelectInvalidAction]
active = False
optional = True

@classmethod
def get_invalid(cls, instance):
Expand Down Expand Up @@ -47,7 +50,8 @@ def get_invalid(cls, instance):
return invalid

def process(self, instance):

if not self.is_active(instance.data):
return
invalid = self.get_invalid(instance)
if invalid:
raise PublishValidationError("Found {} invalid named assembly "
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import pyblish.api
import openpype.hosts.maya.api.action
from openpype.pipeline.publish import (
PublishValidationError
PublishValidationError,
OptionalPyblishPluginMixin
)

class ValidateAssemblyNamespaces(pyblish.api.InstancePlugin):

class ValidateAssemblyNamespaces(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
"""Ensure namespaces are not nested
In the outliner an item in a normal namespace looks as following:
Expand All @@ -20,9 +23,11 @@ class ValidateAssemblyNamespaces(pyblish.api.InstancePlugin):
order = pyblish.api.ValidatorOrder
families = ["assembly"]
actions = [openpype.hosts.maya.api.action.SelectInvalidAction]
optional = False

def process(self, instance):

if not self.is_active(instance.data):
return
self.log.debug("Checking namespace for %s" % instance.name)
if self.get_invalid(instance):
raise PublishValidationError("Nested namespaces found")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
from maya import cmds

import openpype.hosts.maya.api.action
from openpype.pipeline.publish import PublishValidationError, RepairAction
from openpype.pipeline.publish import (
PublishValidationError,
RepairAction,
OptionalPyblishPluginMixin
)


class ValidateAssemblyModelTransforms(pyblish.api.InstancePlugin):
class ValidateAssemblyModelTransforms(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
"""Verify only root nodes of the loaded asset have transformations.
Note: This check is temporary and is subject to change.
Expand Down Expand Up @@ -34,7 +39,11 @@ class ValidateAssemblyModelTransforms(pyblish.api.InstancePlugin):
" This can alter the look of your scene. "
"Are you sure you want to continue?")

optional = False

def process(self, instance):
if not self.is_active(instance.data):
return
invalid = self.get_invalid(instance)
if invalid:
raise PublishValidationError(
Expand Down
Loading

0 comments on commit 7901009

Please sign in to comment.