mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
Merge branch 'develop' into release/3.15.x
This commit is contained in:
commit
ee16161f89
23 changed files with 495 additions and 68 deletions
69
CHANGELOG.md
69
CHANGELOG.md
|
|
@ -1,5 +1,73 @@
|
|||
# Changelog
|
||||
|
||||
## [3.14.9](https://github.com/pypeclub/OpenPype/tree/3.14.9)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.8...3.14.9)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Documentation: Testing on Deadline [\#4185](https://github.com/pypeclub/OpenPype/pull/4185)
|
||||
- Consistent Python version [\#4160](https://github.com/pypeclub/OpenPype/pull/4160)
|
||||
|
||||
**🆕 New features**
|
||||
|
||||
- Feature/op 4397 gl tf extractor for maya [\#4192](https://github.com/pypeclub/OpenPype/pull/4192)
|
||||
- Maya: Extractor for Unreal SkeletalMesh [\#4174](https://github.com/pypeclub/OpenPype/pull/4174)
|
||||
- 3dsmax: integration [\#4168](https://github.com/pypeclub/OpenPype/pull/4168)
|
||||
- Blender: Extract Alembic Animations [\#4128](https://github.com/pypeclub/OpenPype/pull/4128)
|
||||
- Unreal: Load Alembic Animations [\#4127](https://github.com/pypeclub/OpenPype/pull/4127)
|
||||
|
||||
**🚀 Enhancements**
|
||||
|
||||
- Houdini: Use new interface class name for publish host [\#4220](https://github.com/pypeclub/OpenPype/pull/4220)
|
||||
- General: Default command for headless mode is interactive [\#4203](https://github.com/pypeclub/OpenPype/pull/4203)
|
||||
- Maya: Enhanced ASS publishing [\#4196](https://github.com/pypeclub/OpenPype/pull/4196)
|
||||
- Feature/op 3924 implement ass extractor [\#4188](https://github.com/pypeclub/OpenPype/pull/4188)
|
||||
- File transactions: Source path is destination path [\#4184](https://github.com/pypeclub/OpenPype/pull/4184)
|
||||
- Deadline: improve environment processing [\#4182](https://github.com/pypeclub/OpenPype/pull/4182)
|
||||
- General: Comment per instance in Publisher [\#4178](https://github.com/pypeclub/OpenPype/pull/4178)
|
||||
- Ensure Mongo database directory exists in Windows. [\#4166](https://github.com/pypeclub/OpenPype/pull/4166)
|
||||
- Note about unrestricted execution on Windows. [\#4161](https://github.com/pypeclub/OpenPype/pull/4161)
|
||||
- Maya: Enable thumbnail transparency on extraction. [\#4147](https://github.com/pypeclub/OpenPype/pull/4147)
|
||||
- Maya: Disable viewport Pan/Zoom on playblast extraction. [\#4146](https://github.com/pypeclub/OpenPype/pull/4146)
|
||||
- Maya: Optional viewport refresh on pointcache extraction [\#4144](https://github.com/pypeclub/OpenPype/pull/4144)
|
||||
- CelAction: refactory integration to current openpype [\#4140](https://github.com/pypeclub/OpenPype/pull/4140)
|
||||
- Maya: create and publish bounding box geometry [\#4131](https://github.com/pypeclub/OpenPype/pull/4131)
|
||||
- Changed the UOpenPypePublishInstance to use the UDataAsset class [\#4124](https://github.com/pypeclub/OpenPype/pull/4124)
|
||||
- General: Collection Audio speed up [\#4110](https://github.com/pypeclub/OpenPype/pull/4110)
|
||||
- Maya: keep existing AOVs when creating render instance [\#4087](https://github.com/pypeclub/OpenPype/pull/4087)
|
||||
- General: Oiio conversion multipart fix [\#4060](https://github.com/pypeclub/OpenPype/pull/4060)
|
||||
|
||||
**🐛 Bug fixes**
|
||||
|
||||
- Publisher: Signal type issues in Python 2 DCCs [\#4230](https://github.com/pypeclub/OpenPype/pull/4230)
|
||||
- Blender: Fix Layout Family Versioning [\#4228](https://github.com/pypeclub/OpenPype/pull/4228)
|
||||
- Blender: Fix Create Camera "Use selection" [\#4226](https://github.com/pypeclub/OpenPype/pull/4226)
|
||||
- TrayPublisher - join needs list [\#4224](https://github.com/pypeclub/OpenPype/pull/4224)
|
||||
- General: Event callbacks pass event to callbacks as expected [\#4210](https://github.com/pypeclub/OpenPype/pull/4210)
|
||||
- Build:Revert .toml update of Gazu [\#4207](https://github.com/pypeclub/OpenPype/pull/4207)
|
||||
- Nuke: fixed imageio node overrides subset filter [\#4202](https://github.com/pypeclub/OpenPype/pull/4202)
|
||||
- Maya: pointcache [\#4201](https://github.com/pypeclub/OpenPype/pull/4201)
|
||||
- Unreal: Support for Unreal Engine 5.1 [\#4199](https://github.com/pypeclub/OpenPype/pull/4199)
|
||||
- General: Integrate thumbnail looks for thumbnail to multiple places [\#4181](https://github.com/pypeclub/OpenPype/pull/4181)
|
||||
- Various minor bugfixes [\#4172](https://github.com/pypeclub/OpenPype/pull/4172)
|
||||
- Nuke/Hiero: Remove tkinter library paths before launch [\#4171](https://github.com/pypeclub/OpenPype/pull/4171)
|
||||
- Flame: vertical alignment of layers [\#4169](https://github.com/pypeclub/OpenPype/pull/4169)
|
||||
- Nuke: correct detection of viewer and display [\#4165](https://github.com/pypeclub/OpenPype/pull/4165)
|
||||
- Settings UI: Don't create QApplication if already exists [\#4156](https://github.com/pypeclub/OpenPype/pull/4156)
|
||||
- General: Extract review handle start offset of sequences [\#4152](https://github.com/pypeclub/OpenPype/pull/4152)
|
||||
- Maya: Maintain time connections on Alembic update. [\#4143](https://github.com/pypeclub/OpenPype/pull/4143)
|
||||
|
||||
**🔀 Refactored code**
|
||||
|
||||
- General: Use qtpy in modules and hosts UIs which are running in OpenPype process [\#4225](https://github.com/pypeclub/OpenPype/pull/4225)
|
||||
- Tools: Use qtpy instead of Qt in standalone tools [\#4223](https://github.com/pypeclub/OpenPype/pull/4223)
|
||||
- General: Use qtpy in settings UI [\#4215](https://github.com/pypeclub/OpenPype/pull/4215)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- layout publish more than one container issue [\#4098](https://github.com/pypeclub/OpenPype/pull/4098)
|
||||
|
||||
## [3.14.8](https://github.com/pypeclub/OpenPype/tree/3.14.8)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.7...3.14.8)
|
||||
|
|
@ -21,7 +89,6 @@
|
|||
- Maya: Looks - add all connections [\#4135](https://github.com/pypeclub/OpenPype/pull/4135)
|
||||
- General: Fix variable check in collect anatomy instance data [\#4117](https://github.com/pypeclub/OpenPype/pull/4117)
|
||||
|
||||
|
||||
## [3.14.7](https://github.com/pypeclub/OpenPype/tree/3.14.7)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.6...3.14.7)
|
||||
|
|
|
|||
69
HISTORY.md
69
HISTORY.md
|
|
@ -1,5 +1,74 @@
|
|||
# Changelog
|
||||
|
||||
|
||||
## [3.14.9](https://github.com/pypeclub/OpenPype/tree/3.14.9)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.8...3.14.9)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Documentation: Testing on Deadline [\#4185](https://github.com/pypeclub/OpenPype/pull/4185)
|
||||
- Consistent Python version [\#4160](https://github.com/pypeclub/OpenPype/pull/4160)
|
||||
|
||||
**🆕 New features**
|
||||
|
||||
- Feature/op 4397 gl tf extractor for maya [\#4192](https://github.com/pypeclub/OpenPype/pull/4192)
|
||||
- Maya: Extractor for Unreal SkeletalMesh [\#4174](https://github.com/pypeclub/OpenPype/pull/4174)
|
||||
- 3dsmax: integration [\#4168](https://github.com/pypeclub/OpenPype/pull/4168)
|
||||
- Blender: Extract Alembic Animations [\#4128](https://github.com/pypeclub/OpenPype/pull/4128)
|
||||
- Unreal: Load Alembic Animations [\#4127](https://github.com/pypeclub/OpenPype/pull/4127)
|
||||
|
||||
**🚀 Enhancements**
|
||||
|
||||
- Houdini: Use new interface class name for publish host [\#4220](https://github.com/pypeclub/OpenPype/pull/4220)
|
||||
- General: Default command for headless mode is interactive [\#4203](https://github.com/pypeclub/OpenPype/pull/4203)
|
||||
- Maya: Enhanced ASS publishing [\#4196](https://github.com/pypeclub/OpenPype/pull/4196)
|
||||
- Feature/op 3924 implement ass extractor [\#4188](https://github.com/pypeclub/OpenPype/pull/4188)
|
||||
- File transactions: Source path is destination path [\#4184](https://github.com/pypeclub/OpenPype/pull/4184)
|
||||
- Deadline: improve environment processing [\#4182](https://github.com/pypeclub/OpenPype/pull/4182)
|
||||
- General: Comment per instance in Publisher [\#4178](https://github.com/pypeclub/OpenPype/pull/4178)
|
||||
- Ensure Mongo database directory exists in Windows. [\#4166](https://github.com/pypeclub/OpenPype/pull/4166)
|
||||
- Note about unrestricted execution on Windows. [\#4161](https://github.com/pypeclub/OpenPype/pull/4161)
|
||||
- Maya: Enable thumbnail transparency on extraction. [\#4147](https://github.com/pypeclub/OpenPype/pull/4147)
|
||||
- Maya: Disable viewport Pan/Zoom on playblast extraction. [\#4146](https://github.com/pypeclub/OpenPype/pull/4146)
|
||||
- Maya: Optional viewport refresh on pointcache extraction [\#4144](https://github.com/pypeclub/OpenPype/pull/4144)
|
||||
- CelAction: refactory integration to current openpype [\#4140](https://github.com/pypeclub/OpenPype/pull/4140)
|
||||
- Maya: create and publish bounding box geometry [\#4131](https://github.com/pypeclub/OpenPype/pull/4131)
|
||||
- Changed the UOpenPypePublishInstance to use the UDataAsset class [\#4124](https://github.com/pypeclub/OpenPype/pull/4124)
|
||||
- General: Collection Audio speed up [\#4110](https://github.com/pypeclub/OpenPype/pull/4110)
|
||||
- Maya: keep existing AOVs when creating render instance [\#4087](https://github.com/pypeclub/OpenPype/pull/4087)
|
||||
- General: Oiio conversion multipart fix [\#4060](https://github.com/pypeclub/OpenPype/pull/4060)
|
||||
|
||||
**🐛 Bug fixes**
|
||||
|
||||
- Publisher: Signal type issues in Python 2 DCCs [\#4230](https://github.com/pypeclub/OpenPype/pull/4230)
|
||||
- Blender: Fix Layout Family Versioning [\#4228](https://github.com/pypeclub/OpenPype/pull/4228)
|
||||
- Blender: Fix Create Camera "Use selection" [\#4226](https://github.com/pypeclub/OpenPype/pull/4226)
|
||||
- TrayPublisher - join needs list [\#4224](https://github.com/pypeclub/OpenPype/pull/4224)
|
||||
- General: Event callbacks pass event to callbacks as expected [\#4210](https://github.com/pypeclub/OpenPype/pull/4210)
|
||||
- Build:Revert .toml update of Gazu [\#4207](https://github.com/pypeclub/OpenPype/pull/4207)
|
||||
- Nuke: fixed imageio node overrides subset filter [\#4202](https://github.com/pypeclub/OpenPype/pull/4202)
|
||||
- Maya: pointcache [\#4201](https://github.com/pypeclub/OpenPype/pull/4201)
|
||||
- Unreal: Support for Unreal Engine 5.1 [\#4199](https://github.com/pypeclub/OpenPype/pull/4199)
|
||||
- General: Integrate thumbnail looks for thumbnail to multiple places [\#4181](https://github.com/pypeclub/OpenPype/pull/4181)
|
||||
- Various minor bugfixes [\#4172](https://github.com/pypeclub/OpenPype/pull/4172)
|
||||
- Nuke/Hiero: Remove tkinter library paths before launch [\#4171](https://github.com/pypeclub/OpenPype/pull/4171)
|
||||
- Flame: vertical alignment of layers [\#4169](https://github.com/pypeclub/OpenPype/pull/4169)
|
||||
- Nuke: correct detection of viewer and display [\#4165](https://github.com/pypeclub/OpenPype/pull/4165)
|
||||
- Settings UI: Don't create QApplication if already exists [\#4156](https://github.com/pypeclub/OpenPype/pull/4156)
|
||||
- General: Extract review handle start offset of sequences [\#4152](https://github.com/pypeclub/OpenPype/pull/4152)
|
||||
- Maya: Maintain time connections on Alembic update. [\#4143](https://github.com/pypeclub/OpenPype/pull/4143)
|
||||
|
||||
**🔀 Refactored code**
|
||||
|
||||
- General: Use qtpy in modules and hosts UIs which are running in OpenPype process [\#4225](https://github.com/pypeclub/OpenPype/pull/4225)
|
||||
- Tools: Use qtpy instead of Qt in standalone tools [\#4223](https://github.com/pypeclub/OpenPype/pull/4223)
|
||||
- General: Use qtpy in settings UI [\#4215](https://github.com/pypeclub/OpenPype/pull/4215)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- layout publish more than one container issue [\#4098](https://github.com/pypeclub/OpenPype/pull/4098)
|
||||
|
||||
## [3.14.8](https://github.com/pypeclub/OpenPype/tree/3.14.8)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.14.7...3.14.8)
|
||||
|
|
|
|||
82
openpype/hosts/blender/plugins/load/import_workfile.py
Normal file
82
openpype/hosts/blender/plugins/load/import_workfile.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import bpy
|
||||
|
||||
from openpype.hosts.blender.api import plugin
|
||||
|
||||
|
||||
def append_workfile(context, fname, do_import):
|
||||
asset = context['asset']['name']
|
||||
subset = context['subset']['name']
|
||||
|
||||
group_name = plugin.asset_name(asset, subset)
|
||||
|
||||
# We need to preserve the original names of the scenes, otherwise,
|
||||
# if there are duplicate names in the current workfile, the imported
|
||||
# scenes will be renamed by Blender to avoid conflicts.
|
||||
original_scene_names = []
|
||||
|
||||
with bpy.data.libraries.load(fname) as (data_from, data_to):
|
||||
for attr in dir(data_to):
|
||||
if attr == "scenes":
|
||||
for scene in data_from.scenes:
|
||||
original_scene_names.append(scene)
|
||||
setattr(data_to, attr, getattr(data_from, attr))
|
||||
|
||||
current_scene = bpy.context.scene
|
||||
|
||||
for scene, s_name in zip(data_to.scenes, original_scene_names):
|
||||
scene.name = f"{group_name}_{s_name}"
|
||||
if do_import:
|
||||
collection = bpy.data.collections.new(f"{group_name}_{s_name}")
|
||||
for obj in scene.objects:
|
||||
collection.objects.link(obj)
|
||||
current_scene.collection.children.link(collection)
|
||||
for coll in scene.collection.children:
|
||||
collection.children.link(coll)
|
||||
|
||||
|
||||
class AppendBlendLoader(plugin.AssetLoader):
|
||||
"""Append workfile in Blender (unmanaged)
|
||||
|
||||
Warning:
|
||||
The loaded content will be unmanaged and is *not* visible in the
|
||||
scene inventory. It's purely intended to merge content into your scene
|
||||
so you could also use it as a new base.
|
||||
"""
|
||||
|
||||
representations = ["blend"]
|
||||
families = ["*"]
|
||||
|
||||
label = "Append Workfile"
|
||||
order = 9
|
||||
icon = "arrow-circle-down"
|
||||
color = "#775555"
|
||||
|
||||
def load(self, context, name=None, namespace=None, data=None):
|
||||
append_workfile(context, self.fname, False)
|
||||
|
||||
# We do not containerize imported content, it remains unmanaged
|
||||
return
|
||||
|
||||
|
||||
class ImportBlendLoader(plugin.AssetLoader):
|
||||
"""Import workfile in the current Blender scene (unmanaged)
|
||||
|
||||
Warning:
|
||||
The loaded content will be unmanaged and is *not* visible in the
|
||||
scene inventory. It's purely intended to merge content into your scene
|
||||
so you could also use it as a new base.
|
||||
"""
|
||||
|
||||
representations = ["blend"]
|
||||
families = ["*"]
|
||||
|
||||
label = "Import Workfile"
|
||||
order = 9
|
||||
icon = "arrow-circle-down"
|
||||
color = "#775555"
|
||||
|
||||
def load(self, context, name=None, namespace=None, data=None):
|
||||
append_workfile(context, self.fname, True)
|
||||
|
||||
# We do not containerize imported content, it remains unmanaged
|
||||
return
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import os
|
||||
from Qt import QtWidgets
|
||||
from qtpy import QtWidgets
|
||||
from copy import deepcopy
|
||||
from pprint import pformat
|
||||
from openpype.tools.utils.host_tools import HostToolsHelper
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ from copy import deepcopy
|
|||
from xml.etree import ElementTree as ET
|
||||
|
||||
import qargparse
|
||||
from Qt import QtCore, QtWidgets
|
||||
from qtpy import QtCore, QtWidgets
|
||||
|
||||
from openpype import style
|
||||
from openpype.lib import Logger
|
||||
from openpype.lib import Logger, StringTemplate
|
||||
from openpype.pipeline import LegacyCreator, LoaderPlugin
|
||||
from openpype.settings import get_current_project_settings
|
||||
|
||||
|
|
@ -775,6 +775,11 @@ class OpenClipSolver(flib.MediaInfoFile):
|
|||
self.feed_colorspace = feed_data.get("colorspace")
|
||||
self.log.debug("feed_version_name: {}".format(self.feed_version_name))
|
||||
|
||||
# layer rename variables
|
||||
self.layer_rename_template = feed_data["layer_rename_template"]
|
||||
self.layer_rename_patterns = feed_data["layer_rename_patterns"]
|
||||
self.context_data = feed_data["context_data"]
|
||||
|
||||
# derivate other feed variables
|
||||
self.feed_basename = os.path.basename(feed_path)
|
||||
self.feed_dir = os.path.dirname(feed_path)
|
||||
|
|
@ -813,9 +818,11 @@ class OpenClipSolver(flib.MediaInfoFile):
|
|||
|
||||
def _create_new_open_clip(self):
|
||||
self.log.info("Building new openClip")
|
||||
self.log.debug(">> self.clip_data: {}".format(self.clip_data))
|
||||
|
||||
for tmp_xml_track in self.clip_data.iter("track"):
|
||||
# solve track (layer) name
|
||||
self._rename_track_name(tmp_xml_track)
|
||||
|
||||
tmp_xml_feeds = tmp_xml_track.find('feeds')
|
||||
tmp_xml_feeds.set('currentVersion', self.feed_version_name)
|
||||
|
||||
|
|
@ -850,6 +857,48 @@ class OpenClipSolver(flib.MediaInfoFile):
|
|||
if uid == track_uid:
|
||||
return xml_track
|
||||
|
||||
def _rename_track_name(self, xml_track_data):
|
||||
layer_uid = xml_track_data.get("uid")
|
||||
name_obj = xml_track_data.find("name")
|
||||
layer_name = name_obj.text
|
||||
|
||||
if (
|
||||
self.layer_rename_patterns
|
||||
and not any(
|
||||
re.search(lp_.lower(), layer_name.lower())
|
||||
for lp_ in self.layer_rename_patterns
|
||||
)
|
||||
):
|
||||
return
|
||||
|
||||
formating_data = self._update_formating_data(
|
||||
layerName=layer_name,
|
||||
layerUID=layer_uid
|
||||
)
|
||||
name_obj.text = StringTemplate(
|
||||
self.layer_rename_template
|
||||
).format(formating_data)
|
||||
|
||||
def _update_formating_data(self, **kwargs):
|
||||
""" Updating formating data for layer rename
|
||||
|
||||
Attributes:
|
||||
key=value (optional): will be included to formating data
|
||||
as {key: value}
|
||||
Returns:
|
||||
dict: anatomy context data for formating
|
||||
"""
|
||||
self.log.debug(">> self.clip_data: {}".format(self.clip_data))
|
||||
clip_name_obj = self.clip_data.find("name")
|
||||
data = {
|
||||
"originalBasename": clip_name_obj.text
|
||||
}
|
||||
# include version context data
|
||||
data.update(self.context_data)
|
||||
# include input kwargs data
|
||||
data.update(kwargs)
|
||||
return data
|
||||
|
||||
def _update_open_clip(self):
|
||||
self.log.info("Updating openClip ..")
|
||||
|
||||
|
|
@ -857,11 +906,12 @@ class OpenClipSolver(flib.MediaInfoFile):
|
|||
out_xml = out_xml.getroot()
|
||||
|
||||
self.log.debug(">> out_xml: {}".format(out_xml))
|
||||
self.log.debug(">> self.clip_data: {}".format(self.clip_data))
|
||||
|
||||
# loop tmp tracks
|
||||
updated_any = False
|
||||
for tmp_xml_track in self.clip_data.iter("track"):
|
||||
# solve track (layer) name
|
||||
self._rename_track_name(tmp_xml_track)
|
||||
|
||||
# get tmp track uid
|
||||
tmp_track_uid = tmp_xml_track.get("uid")
|
||||
self.log.debug(">> tmp_track_uid: {}".format(tmp_track_uid))
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from copy import deepcopy
|
||||
import os
|
||||
import flame
|
||||
from pprint import pformat
|
||||
|
|
@ -25,6 +26,14 @@ class LoadClip(opfapi.ClipLoader):
|
|||
reel_name = "Loaded"
|
||||
clip_name_template = "{asset}_{subset}<_{output}>"
|
||||
|
||||
""" Anatomy keys from version context data and dynamically added:
|
||||
- {layerName} - original layer name token
|
||||
- {layerUID} - original layer UID token
|
||||
- {originalBasename} - original clip name taken from file
|
||||
"""
|
||||
layer_rename_template = "{asset}_{subset}<_{output}>"
|
||||
layer_rename_patterns = []
|
||||
|
||||
def load(self, context, name, namespace, options):
|
||||
|
||||
# get flame objects
|
||||
|
|
@ -38,8 +47,16 @@ class LoadClip(opfapi.ClipLoader):
|
|||
version_name = version.get("name", None)
|
||||
colorspace = self.get_colorspace(context)
|
||||
|
||||
# in case output is not in context replace key to representation
|
||||
if not context["representation"]["context"].get("output"):
|
||||
self.clip_name_template = self.clip_name_template.replace(
|
||||
"output", "representation")
|
||||
self.layer_rename_template = self.layer_rename_template.replace(
|
||||
"output", "representation")
|
||||
|
||||
formating_data = deepcopy(context["representation"]["context"])
|
||||
clip_name = StringTemplate(self.clip_name_template).format(
|
||||
context["representation"]["context"])
|
||||
formating_data)
|
||||
|
||||
# convert colorspace with ocio to flame mapping
|
||||
# in imageio flame section
|
||||
|
|
@ -62,6 +79,9 @@ class LoadClip(opfapi.ClipLoader):
|
|||
"path": self.fname.replace("\\", "/"),
|
||||
"colorspace": colorspace,
|
||||
"version": "v{:0>3}".format(version_name),
|
||||
"layer_rename_template": self.layer_rename_template,
|
||||
"layer_rename_patterns": self.layer_rename_patterns,
|
||||
"context_data": formating_data
|
||||
}
|
||||
self.log.debug(pformat(
|
||||
loading_context
|
||||
|
|
|
|||
|
|
@ -25,6 +25,14 @@ class LoadClipBatch(opfapi.ClipLoader):
|
|||
reel_name = "OP_LoadedReel"
|
||||
clip_name_template = "{batch}_{asset}_{subset}<_{output}>"
|
||||
|
||||
""" Anatomy keys from version context data and dynamically added:
|
||||
- {layerName} - original layer name token
|
||||
- {layerUID} - original layer UID token
|
||||
- {originalBasename} - original clip name taken from file
|
||||
"""
|
||||
layer_rename_template = "{asset}_{subset}<_{output}>"
|
||||
layer_rename_patterns = []
|
||||
|
||||
def load(self, context, name, namespace, options):
|
||||
|
||||
# get flame objects
|
||||
|
|
@ -39,7 +47,10 @@ class LoadClipBatch(opfapi.ClipLoader):
|
|||
|
||||
# in case output is not in context replace key to representation
|
||||
if not context["representation"]["context"].get("output"):
|
||||
self.clip_name_template.replace("output", "representation")
|
||||
self.clip_name_template = self.clip_name_template.replace(
|
||||
"output", "representation")
|
||||
self.layer_rename_template = self.layer_rename_template.replace(
|
||||
"output", "representation")
|
||||
|
||||
formating_data = deepcopy(context["representation"]["context"])
|
||||
formating_data["batch"] = self.batch.name.get_value()
|
||||
|
|
@ -69,6 +80,9 @@ class LoadClipBatch(opfapi.ClipLoader):
|
|||
"path": self.fname.replace("\\", "/"),
|
||||
"colorspace": colorspace,
|
||||
"version": "v{:0>3}".format(version_name),
|
||||
"layer_rename_template": self.layer_rename_template,
|
||||
"layer_rename_patterns": self.layer_rename_patterns,
|
||||
"context_data": formating_data
|
||||
}
|
||||
self.log.debug(pformat(
|
||||
loading_context
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtCore
|
||||
from qtpy import QtWidgets, QtCore
|
||||
|
||||
import uiwidgets
|
||||
import app_utils
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from Qt import QtWidgets, QtCore
|
||||
from qtpy import QtWidgets, QtCore
|
||||
|
||||
|
||||
class FlameLabel(QtWidgets.QLabel):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from __future__ import print_function
|
||||
import sys
|
||||
from Qt import QtWidgets
|
||||
from qtpy import QtWidgets
|
||||
from pprint import pformat
|
||||
import atexit
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import logging
|
||||
|
||||
from scriptsmenu import scriptsmenu
|
||||
from Qt import QtWidgets
|
||||
from qtpy import QtWidgets
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,11 @@ import secrets
|
|||
import shutil
|
||||
import hiero
|
||||
|
||||
from Qt import QtWidgets, QtCore, QtXml
|
||||
from qtpy import QtWidgets, QtCore
|
||||
try:
|
||||
from PySide import QtXml
|
||||
except ImportError:
|
||||
from PySide2 import QtXml
|
||||
|
||||
from openpype.client import get_project
|
||||
from openpype.settings import get_project_settings
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ def menu_install():
|
|||
|
||||
"""
|
||||
|
||||
from Qt import QtGui
|
||||
from qtpy import QtGui
|
||||
from . import (
|
||||
publish, launch_workfiles_app, reload_config,
|
||||
apply_colorspace_project, apply_colorspace_clips
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from copy import deepcopy
|
|||
|
||||
import hiero
|
||||
|
||||
from Qt import QtWidgets, QtCore
|
||||
from qtpy import QtWidgets, QtCore
|
||||
import qargparse
|
||||
|
||||
from openpype.settings import get_current_project_settings
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import tempfile
|
|||
from pprint import pformat
|
||||
|
||||
import pyblish.api
|
||||
from Qt.QtGui import QPixmap
|
||||
from qtpy.QtGui import QPixmap
|
||||
|
||||
import hiero.ui
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from collections import OrderedDict
|
|||
import clique
|
||||
|
||||
import nuke
|
||||
from Qt import QtCore, QtWidgets
|
||||
from qtpy import QtCore, QtWidgets
|
||||
|
||||
from openpype.client import (
|
||||
get_project,
|
||||
|
|
@ -81,7 +81,6 @@ class Context:
|
|||
def get_main_window():
|
||||
"""Acquire Nuke's main window"""
|
||||
if Context.main_window is None:
|
||||
from Qt import QtWidgets
|
||||
|
||||
top_widgets = QtWidgets.QApplication.topLevelWidgets()
|
||||
name = "Foundry::UI::DockMainWindow"
|
||||
|
|
@ -611,7 +610,10 @@ def get_created_node_imageio_setting_legacy(nodeclass, creator, subset):
|
|||
|
||||
if (
|
||||
onode["subsets"]
|
||||
and not any(re.search(s, subset) for s in onode["subsets"])
|
||||
and not any(
|
||||
re.search(s.lower(), subset.lower())
|
||||
for s in onode["subsets"]
|
||||
)
|
||||
):
|
||||
continue
|
||||
|
||||
|
|
@ -694,7 +696,8 @@ def get_imageio_node_override_setting(
|
|||
# find matching override node
|
||||
override_imageio_node = None
|
||||
for onode in override_nodes:
|
||||
log.info(onode)
|
||||
log.debug("__ onode: {}".format(onode))
|
||||
log.debug("__ subset: {}".format(subset))
|
||||
if node_class not in onode["nukeNodeClass"]:
|
||||
continue
|
||||
|
||||
|
|
@ -703,7 +706,10 @@ def get_imageio_node_override_setting(
|
|||
|
||||
if (
|
||||
onode["subsets"]
|
||||
and not any(re.search(s, subset) for s in onode["subsets"])
|
||||
and not any(
|
||||
re.search(s.lower(), subset.lower())
|
||||
for s in onode["subsets"]
|
||||
)
|
||||
):
|
||||
continue
|
||||
|
||||
|
|
|
|||
|
|
@ -786,23 +786,15 @@ class ModulesManager:
|
|||
).format(expected_keys, " | ".join(msg_items)))
|
||||
return output
|
||||
|
||||
def collect_creator_plugin_paths(self, host_name):
|
||||
"""Helper to collect creator plugin paths from modules.
|
||||
|
||||
Args:
|
||||
host_name (str): For which host are creators meants.
|
||||
|
||||
Returns:
|
||||
list: List of creator plugin paths.
|
||||
"""
|
||||
# Output structure
|
||||
def _collect_plugin_paths(self, method_name, *args, **kwargs):
|
||||
output = []
|
||||
for module in self.get_enabled_modules():
|
||||
# Skip module that do not inherit from `IPluginPaths`
|
||||
if not isinstance(module, IPluginPaths):
|
||||
continue
|
||||
|
||||
paths = module.get_creator_plugin_paths(host_name)
|
||||
method = getattr(module, method_name)
|
||||
paths = method(*args, **kwargs)
|
||||
if paths:
|
||||
# Convert to list if value is not list
|
||||
if not isinstance(paths, (list, tuple, set)):
|
||||
|
|
@ -810,6 +802,53 @@ class ModulesManager:
|
|||
output.extend(paths)
|
||||
return output
|
||||
|
||||
def collect_create_plugin_paths(self, host_name):
|
||||
"""Helper to collect creator plugin paths from modules.
|
||||
|
||||
Args:
|
||||
host_name (str): For which host are creators meant.
|
||||
|
||||
Returns:
|
||||
list: List of creator plugin paths.
|
||||
"""
|
||||
|
||||
return self._collect_plugin_paths(
|
||||
"get_create_plugin_paths",
|
||||
host_name
|
||||
)
|
||||
|
||||
collect_creator_plugin_paths = collect_create_plugin_paths
|
||||
|
||||
def collect_load_plugin_paths(self, host_name):
|
||||
"""Helper to collect load plugin paths from modules.
|
||||
|
||||
Args:
|
||||
host_name (str): For which host are load plugins meant.
|
||||
|
||||
Returns:
|
||||
list: List of load plugin paths.
|
||||
"""
|
||||
|
||||
return self._collect_plugin_paths(
|
||||
"get_load_plugin_paths",
|
||||
host_name
|
||||
)
|
||||
|
||||
def collect_publish_plugin_paths(self, host_name):
|
||||
"""Helper to collect load plugin paths from modules.
|
||||
|
||||
Args:
|
||||
host_name (str): For which host are load plugins meant.
|
||||
|
||||
Returns:
|
||||
list: List of pyblish plugin paths.
|
||||
"""
|
||||
|
||||
return self._collect_plugin_paths(
|
||||
"get_publish_plugin_paths",
|
||||
host_name
|
||||
)
|
||||
|
||||
def get_host_module(self, host_name):
|
||||
"""Find host module by host name.
|
||||
|
||||
|
|
|
|||
|
|
@ -188,7 +188,6 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline):
|
|||
# Adding file dependencies.
|
||||
if self.asset_dependencies:
|
||||
dependencies = instance.context.data["fileDependencies"]
|
||||
dependencies.append(context.data["currentFile"])
|
||||
for dependency in dependencies:
|
||||
job_info.AssetDependency += dependency
|
||||
|
||||
|
|
@ -299,7 +298,7 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline):
|
|||
# Add export job as dependency --------------------------------------
|
||||
if export_job:
|
||||
job_info, _ = payload
|
||||
job_info.JobDependency = export_job
|
||||
job_info.JobDependencies = export_job
|
||||
|
||||
if instance.data.get("tileRendering"):
|
||||
# Prepare tiles data
|
||||
|
|
@ -436,7 +435,7 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline):
|
|||
|
||||
frame_assembly_job_info.ExtraInfo[0] = file_hash
|
||||
frame_assembly_job_info.ExtraInfo[1] = file
|
||||
frame_assembly_job_info.JobDependency = tile_job_id
|
||||
frame_assembly_job_info.JobDependencies = tile_job_id
|
||||
|
||||
# write assembly job config files
|
||||
now = datetime.now()
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class OpenPypeInterface:
|
|||
|
||||
Child classes of OpenPypeInterface may be used as mixin in different
|
||||
OpenPype modules which means they have to have implemented methods defined
|
||||
in the interface. By default interface does not have any abstract parts.
|
||||
in the interface. By default, interface does not have any abstract parts.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
|
@ -44,40 +44,78 @@ class IPluginPaths(OpenPypeInterface):
|
|||
def get_plugin_paths(self):
|
||||
pass
|
||||
|
||||
def get_creator_plugin_paths(self, host_name):
|
||||
"""Retreive creator plugin paths.
|
||||
def _get_plugin_paths_by_type(self, plugin_type):
|
||||
paths = self.get_plugin_paths()
|
||||
if not paths or plugin_type not in paths:
|
||||
return []
|
||||
|
||||
Give addons ability to add creator plugin paths based on host name.
|
||||
paths = paths[plugin_type]
|
||||
if not paths:
|
||||
return []
|
||||
|
||||
NOTES:
|
||||
- Default implementation uses 'get_plugin_paths' and always return
|
||||
all creator plugins.
|
||||
- Host name may help to organize plugins by host, but each creator
|
||||
alsomay have host filtering.
|
||||
if not isinstance(paths, (list, tuple, set)):
|
||||
paths = [paths]
|
||||
return paths
|
||||
|
||||
def get_create_plugin_paths(self, host_name):
|
||||
"""Receive create plugin paths.
|
||||
|
||||
Give addons ability to add create plugin paths based on host name.
|
||||
|
||||
Notes:
|
||||
Default implementation uses 'get_plugin_paths' and always return
|
||||
all create plugin paths.
|
||||
|
||||
Args:
|
||||
host_name (str): For which host are the plugins meant.
|
||||
"""
|
||||
|
||||
paths = self.get_plugin_paths()
|
||||
if not paths or "create" not in paths:
|
||||
return []
|
||||
if hasattr(self, "get_creator_plugin_paths"):
|
||||
# TODO remove in 3.16
|
||||
self.log.warning((
|
||||
"DEPRECATION WARNING: Using method 'get_creator_plugin_paths'"
|
||||
" which was renamed to 'get_create_plugin_paths'."
|
||||
))
|
||||
return self.get_creator_plugin_paths(host_name)
|
||||
return self._get_plugin_paths_by_type("create")
|
||||
|
||||
create_paths = paths["create"]
|
||||
if not create_paths:
|
||||
return []
|
||||
def get_load_plugin_paths(self, host_name):
|
||||
"""Receive load plugin paths.
|
||||
|
||||
if not isinstance(create_paths, (list, tuple, set)):
|
||||
create_paths = [create_paths]
|
||||
return create_paths
|
||||
Give addons ability to add load plugin paths based on host name.
|
||||
|
||||
Notes:
|
||||
Default implementation uses 'get_plugin_paths' and always return
|
||||
all load plugin paths.
|
||||
|
||||
Args:
|
||||
host_name (str): For which host are the plugins meant.
|
||||
"""
|
||||
|
||||
return self._get_plugin_paths_by_type("load")
|
||||
|
||||
def get_publish_plugin_paths(self, host_name):
|
||||
"""Receive publish plugin paths.
|
||||
|
||||
Give addons ability to add publish plugin paths based on host name.
|
||||
|
||||
Notes:
|
||||
Default implementation uses 'get_plugin_paths' and always return
|
||||
all publish plugin paths.
|
||||
|
||||
Args:
|
||||
host_name (str): For which host are the plugins meant.
|
||||
"""
|
||||
|
||||
return self._get_plugin_paths_by_type("publish")
|
||||
|
||||
|
||||
class ILaunchHookPaths(OpenPypeInterface):
|
||||
"""Module has launch hook paths to return.
|
||||
|
||||
Modules does not have to inherit from this interface (changed 8.11.2022).
|
||||
Module just have to have implemented 'get_launch_hook_paths' to be able use
|
||||
the advantage.
|
||||
Modules don't have to inherit from this interface (changed 8.11.2022).
|
||||
Module just have to have implemented 'get_launch_hook_paths' to be able to
|
||||
use the advantage.
|
||||
|
||||
Expected result is list of paths.
|
||||
["path/to/launch_hooks_dir"]
|
||||
|
|
|
|||
|
|
@ -158,17 +158,24 @@ def install_openpype_plugins(project_name=None, host_name=None):
|
|||
pyblish.api.register_discovery_filter(filter_pyblish_plugins)
|
||||
register_loader_plugin_path(LOAD_PATH)
|
||||
|
||||
modules_manager = _get_modules_manager()
|
||||
publish_plugin_dirs = modules_manager.collect_plugin_paths()["publish"]
|
||||
for path in publish_plugin_dirs:
|
||||
pyblish.api.register_plugin_path(path)
|
||||
|
||||
if host_name is None:
|
||||
host_name = os.environ.get("AVALON_APP")
|
||||
|
||||
creator_paths = modules_manager.collect_creator_plugin_paths(host_name)
|
||||
for creator_path in creator_paths:
|
||||
register_creator_plugin_path(creator_path)
|
||||
modules_manager = _get_modules_manager()
|
||||
publish_plugin_dirs = modules_manager.collect_publish_plugin_paths(
|
||||
host_name)
|
||||
for path in publish_plugin_dirs:
|
||||
pyblish.api.register_plugin_path(path)
|
||||
|
||||
create_plugin_paths = modules_manager.collect_create_plugin_paths(
|
||||
host_name)
|
||||
for path in create_plugin_paths:
|
||||
register_creator_plugin_path(path)
|
||||
|
||||
load_plugin_paths = modules_manager.collect_load_plugin_paths(
|
||||
host_name)
|
||||
for path in load_plugin_paths:
|
||||
register_loader_plugin_path(path)
|
||||
|
||||
if project_name is None:
|
||||
project_name = os.environ.get("AVALON_PROJECT")
|
||||
|
|
|
|||
|
|
@ -119,7 +119,12 @@
|
|||
],
|
||||
"reel_group_name": "OpenPype_Reels",
|
||||
"reel_name": "Loaded",
|
||||
"clip_name_template": "{asset}_{subset}<_{output}>"
|
||||
"clip_name_template": "{asset}_{subset}<_{output}>",
|
||||
"layer_rename_template": "{asset}_{subset}<_{output}>",
|
||||
"layer_rename_patterns": [
|
||||
"rgb",
|
||||
"rgba"
|
||||
]
|
||||
},
|
||||
"LoadClipBatch": {
|
||||
"enabled": true,
|
||||
|
|
@ -142,7 +147,12 @@
|
|||
"exr16fpdwaa"
|
||||
],
|
||||
"reel_name": "OP_LoadedReel",
|
||||
"clip_name_template": "{batch}_{asset}_{subset}<_{output}>"
|
||||
"clip_name_template": "{batch}_{asset}_{subset}<_{output}>",
|
||||
"layer_rename_template": "{asset}_{subset}<_{output}>",
|
||||
"layer_rename_patterns": [
|
||||
"rgb",
|
||||
"rgba"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -512,6 +512,17 @@
|
|||
"type": "text",
|
||||
"key": "clip_name_template",
|
||||
"label": "Clip name template"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "layer_rename_template",
|
||||
"label": "Layer name template"
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "layer_rename_patterns",
|
||||
"label": "Layer rename patters",
|
||||
"object_type": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -554,6 +565,17 @@
|
|||
"type": "text",
|
||||
"key": "clip_name_template",
|
||||
"label": "Clip name template"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "layer_rename_template",
|
||||
"label": "Layer name template"
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "layer_rename_patterns",
|
||||
"label": "Layer rename patters",
|
||||
"object_type": "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring Pype version."""
|
||||
__version__ = "3.14.9-nightly.4"
|
||||
__version__ = "3.14.10-nightly.1"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue