[Automated] Merged develop into main

This commit is contained in:
pypebot 2022-10-12 06:05:26 +02:00 committed by GitHub
commit 0d1aea447f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
52 changed files with 499 additions and 144 deletions

View file

@ -2,6 +2,7 @@ from .mongo import get_project_connection
from .entities import (
get_assets,
get_asset_by_id,
get_version_by_id,
get_representation_by_id,
convert_id,
)
@ -127,12 +128,20 @@ def get_linked_representation_id(
if not version_id:
return []
version_doc = get_version_by_id(
project_name, version_id, fields=["type", "version_id"]
)
if version_doc["type"] == "hero_version":
version_id = version_doc["version_id"]
if max_depth is None:
max_depth = 0
match = {
"_id": version_id,
"type": {"$in": ["version", "hero_version"]}
# Links are not stored to hero versions at this moment so filter
# is limited to just versions
"type": "version"
}
graph_lookup = {
@ -187,7 +196,7 @@ def _process_referenced_pipeline_result(result, link_type):
referenced_version_ids = set()
correctly_linked_ids = set()
for item in result:
input_links = item["data"].get("inputLinks")
input_links = item.get("data", {}).get("inputLinks")
if not input_links:
continue
@ -203,7 +212,7 @@ def _process_referenced_pipeline_result(result, link_type):
continue
for output in sorted(outputs_recursive, key=lambda o: o["depth"]):
output_links = output["data"].get("inputLinks")
output_links = output.get("data", {}).get("inputLinks")
if not output_links:
continue

View file

@ -23,6 +23,7 @@ CURRENT_PROJECT_CONFIG_SCHEMA = "openpype:config-2.0"
CURRENT_ASSET_DOC_SCHEMA = "openpype:asset-3.0"
CURRENT_SUBSET_SCHEMA = "openpype:subset-3.0"
CURRENT_VERSION_SCHEMA = "openpype:version-3.0"
CURRENT_HERO_VERSION_SCHEMA = "openpype:hero_version-1.0"
CURRENT_REPRESENTATION_SCHEMA = "openpype:representation-2.0"
CURRENT_WORKFILE_INFO_SCHEMA = "openpype:workfile-1.0"
CURRENT_THUMBNAIL_SCHEMA = "openpype:thumbnail-1.0"
@ -162,6 +163,34 @@ def new_version_doc(version, subset_id, data=None, entity_id=None):
}
def new_hero_version_doc(version_id, subset_id, data=None, entity_id=None):
"""Create skeleton data of hero version document.
Args:
version_id (ObjectId): Is considered as unique identifier of version
under subset.
subset_id (Union[str, ObjectId]): Id of parent subset.
data (Dict[str, Any]): Version document data.
entity_id (Union[str, ObjectId]): Predefined id of document. New id is
created if not passed.
Returns:
Dict[str, Any]: Skeleton of version document.
"""
if data is None:
data = {}
return {
"_id": _create_or_convert_to_mongo_id(entity_id),
"schema": CURRENT_HERO_VERSION_SCHEMA,
"type": "hero_version",
"version_id": version_id,
"parent": subset_id,
"data": data
}
def new_representation_doc(
name, version_id, context, data=None, entity_id=None
):
@ -293,6 +322,20 @@ def prepare_version_update_data(old_doc, new_doc, replace=True):
return _prepare_update_data(old_doc, new_doc, replace)
def prepare_hero_version_update_data(old_doc, new_doc, replace=True):
"""Compare two hero version documents and prepare update data.
Based on compared values will create update data for 'UpdateOperation'.
Empty output means that documents are identical.
Returns:
Dict[str, Any]: Changes between old and new document.
"""
return _prepare_update_data(old_doc, new_doc, replace)
def prepare_representation_update_data(old_doc, new_doc, replace=True):
"""Compare two representation documents and prepare update data.

View file

@ -6,9 +6,9 @@ from xml.etree import ElementTree as ET
from Qt import QtCore, QtWidgets
import openpype.api as openpype
import qargparse
from openpype import style
from openpype.settings import get_current_project_settings
from openpype.lib import Logger
from openpype.pipeline import LegacyCreator, LoaderPlugin
@ -306,7 +306,7 @@ class Creator(LegacyCreator):
def __init__(self, *args, **kwargs):
super(Creator, self).__init__(*args, **kwargs)
self.presets = openpype.get_current_project_settings()[
self.presets = get_current_project_settings()[
"flame"]["create"].get(self.__class__.__name__, {})
# adding basic current context flame objects

View file

@ -3,8 +3,6 @@ import sys
import re
import contextlib
from Qt import QtGui
from openpype.lib import Logger
from openpype.client import (
get_asset_by_name,
@ -92,7 +90,7 @@ def set_asset_resolution():
})
def validate_comp_prefs(comp=None):
def validate_comp_prefs(comp=None, force_repair=False):
"""Validate current comp defaults with asset settings.
Validates fps, resolutionWidth, resolutionHeight, aspectRatio.
@ -135,21 +133,22 @@ def validate_comp_prefs(comp=None):
asset_value = asset_data[key]
comp_value = comp_frame_format_prefs.get(comp_key)
if asset_value != comp_value:
# todo: Actually show dialog to user instead of just logging
log.warning(
"Comp {pref} {value} does not match asset "
"'{asset_name}' {pref} {asset_value}".format(
pref=label,
value=comp_value,
asset_name=asset_doc["name"],
asset_value=asset_value)
)
invalid_msg = "{} {} should be {}".format(label,
comp_value,
asset_value)
invalid.append(invalid_msg)
if not force_repair:
# Do not log warning if we force repair anyway
log.warning(
"Comp {pref} {value} does not match asset "
"'{asset_name}' {pref} {asset_value}".format(
pref=label,
value=comp_value,
asset_name=asset_doc["name"],
asset_value=asset_value)
)
if invalid:
def _on_repair():
@ -160,6 +159,11 @@ def validate_comp_prefs(comp=None):
attributes[comp_key_full] = value
comp.SetPrefs(attributes)
if force_repair:
log.info("Applying default Comp preferences..")
_on_repair()
return
from . import menu
from openpype.widgets import popup
from openpype.style import load_stylesheet

View file

@ -16,6 +16,7 @@ from openpype.hosts.fusion.api.lib import (
from openpype.pipeline import legacy_io
from openpype.resources import get_openpype_icon_filepath
from .pipeline import FusionEventHandler
from .pulse import FusionPulse
self = sys.modules[__name__]
@ -119,6 +120,10 @@ class OpenPypeMenu(QtWidgets.QWidget):
self._pulse = FusionPulse(parent=self)
self._pulse.start()
# Detect Fusion events as OpenPype events
self._event_handler = FusionEventHandler(parent=self)
self._event_handler.start()
def on_task_changed(self):
# Update current context label
label = legacy_io.Session["AVALON_ASSET"]

View file

@ -2,13 +2,16 @@
Basic avalon integration
"""
import os
import sys
import logging
import pyblish.api
from Qt import QtCore
from openpype.lib import (
Logger,
register_event_callback
register_event_callback,
emit_event
)
from openpype.pipeline import (
register_loader_plugin_path,
@ -39,12 +42,13 @@ CREATE_PATH = os.path.join(PLUGINS_DIR, "create")
INVENTORY_PATH = os.path.join(PLUGINS_DIR, "inventory")
class CompLogHandler(logging.Handler):
class FusionLogHandler(logging.Handler):
# Keep a reference to fusion's Print function (Remote Object)
_print = getattr(sys.modules["__main__"], "fusion").Print
def emit(self, record):
entry = self.format(record)
comp = get_current_comp()
if comp:
comp.Print(entry)
self._print(entry)
def install():
@ -67,7 +71,7 @@ def install():
# Attach default logging handler that prints to active comp
logger = logging.getLogger()
formatter = logging.Formatter(fmt="%(message)s\n")
handler = CompLogHandler()
handler = FusionLogHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
@ -84,10 +88,10 @@ def install():
"instanceToggled", on_pyblish_instance_toggled
)
# Fusion integration currently does not attach to direct callbacks of
# the application. So we use workfile callbacks to allow similar behavior
# on save and open
register_event_callback("workfile.open.after", on_after_open)
# Register events
register_event_callback("open", on_after_open)
register_event_callback("save", on_save)
register_event_callback("new", on_new)
def uninstall():
@ -137,8 +141,18 @@ def on_pyblish_instance_toggled(instance, old_value, new_value):
tool.SetAttrs({"TOOLB_PassThrough": passthrough})
def on_after_open(_event):
comp = get_current_comp()
def on_new(event):
comp = event["Rets"]["comp"]
validate_comp_prefs(comp, force_repair=True)
def on_save(event):
comp = event["sender"]
validate_comp_prefs(comp)
def on_after_open(event):
comp = event["sender"]
validate_comp_prefs(comp)
if any_outdated_containers():
@ -182,7 +196,7 @@ def ls():
"""
comp = get_current_comp()
tools = comp.GetToolList(False, "Loader").values()
tools = comp.GetToolList(False).values()
for tool in tools:
container = parse_container(tool)
@ -254,3 +268,114 @@ def parse_container(tool):
return container
class FusionEventThread(QtCore.QThread):
"""QThread which will periodically ping Fusion app for any events.
The fusion.UIManager must be set up to be notified of events before they'll
be reported by this thread, for example:
fusion.UIManager.AddNotify("Comp_Save", None)
"""
on_event = QtCore.Signal(dict)
def run(self):
app = getattr(sys.modules["__main__"], "app", None)
if app is None:
# No Fusion app found
return
# As optimization store the GetEvent method directly because every
# getattr of UIManager.GetEvent tries to resolve the Remote Function
# through the PyRemoteObject
get_event = app.UIManager.GetEvent
delay = int(os.environ.get("OPENPYPE_FUSION_CALLBACK_INTERVAL", 1000))
while True:
if self.isInterruptionRequested():
return
# Process all events that have been queued up until now
while True:
event = get_event(False)
if not event:
break
self.on_event.emit(event)
# Wait some time before processing events again
# to not keep blocking the UI
self.msleep(delay)
class FusionEventHandler(QtCore.QObject):
"""Emits OpenPype events based on Fusion events captured in a QThread.
This will emit the following OpenPype events based on Fusion actions:
save: Comp_Save, Comp_SaveAs
open: Comp_Opened
new: Comp_New
To use this you can attach it to you Qt UI so it runs in the background.
E.g.
>>> handler = FusionEventHandler(parent=window)
>>> handler.start()
"""
ACTION_IDS = [
"Comp_Save",
"Comp_SaveAs",
"Comp_New",
"Comp_Opened"
]
def __init__(self, parent=None):
super(FusionEventHandler, self).__init__(parent=parent)
# Set up Fusion event callbacks
fusion = getattr(sys.modules["__main__"], "fusion", None)
ui = fusion.UIManager
# Add notifications for the ones we want to listen to
notifiers = []
for action_id in self.ACTION_IDS:
notifier = ui.AddNotify(action_id, None)
notifiers.append(notifier)
# TODO: Not entirely sure whether these must be kept to avoid
# garbage collection
self._notifiers = notifiers
self._event_thread = FusionEventThread(parent=self)
self._event_thread.on_event.connect(self._on_event)
def start(self):
self._event_thread.start()
def stop(self):
self._event_thread.stop()
def _on_event(self, event):
"""Handle Fusion events to emit OpenPype events"""
if not event:
return
what = event["what"]
# Comp Save
if what in {"Comp_Save", "Comp_SaveAs"}:
if not event["Rets"].get("success"):
# If the Save action is cancelled it will still emit an
# event but with "success": False so we ignore those cases
return
# Comp was saved
emit_event("save", data=event)
return
# Comp New
elif what in {"Comp_New"}:
emit_event("new", data=event)
# Comp Opened
elif what in {"Comp_Opened"}:
emit_event("open", data=event)

View file

@ -19,9 +19,12 @@ class PulseThread(QtCore.QThread):
while True:
if self.isInterruptionRequested():
return
try:
app.Test()
except Exception:
# We don't need to call Test because PyRemoteObject of the app
# will actually fail to even resolve the Test function if it has
# gone down. So we can actually already just check by confirming
# the method is still getting resolved. (Optimization)
if app.Test is None:
self.no_response.emit()
self.msleep(interval)

View file

@ -0,0 +1,70 @@
from openpype.pipeline import (
load,
get_representation_path,
)
from openpype.hosts.fusion.api import (
imprint_container,
get_current_comp,
comp_lock_and_undo_chunk
)
class FusionLoadAlembicMesh(load.LoaderPlugin):
"""Load Alembic mesh into Fusion"""
families = ["pointcache", "model"]
representations = ["abc"]
label = "Load alembic mesh"
order = -10
icon = "code-fork"
color = "orange"
tool_type = "SurfaceAlembicMesh"
def load(self, context, name, namespace, data):
# Fallback to asset name when namespace is None
if namespace is None:
namespace = context['asset']['name']
# Create the Loader with the filename path set
comp = get_current_comp()
with comp_lock_and_undo_chunk(comp, "Create tool"):
path = self.fname
args = (-32768, -32768)
tool = comp.AddTool(self.tool_type, *args)
tool["Filename"] = path
imprint_container(tool,
name=name,
namespace=namespace,
context=context,
loader=self.__class__.__name__)
def switch(self, container, representation):
self.update(container, representation)
def update(self, container, representation):
"""Update Alembic path"""
tool = container["_tool"]
assert tool.ID == self.tool_type, f"Must be {self.tool_type}"
comp = tool.Comp()
path = get_representation_path(representation)
with comp_lock_and_undo_chunk(comp, "Update tool"):
tool["Filename"] = path
# Update the imprinted representation
tool.SetData("avalon.representation", str(representation["_id"]))
def remove(self, container):
tool = container["_tool"]
assert tool.ID == self.tool_type, f"Must be {self.tool_type}"
comp = tool.Comp()
with comp_lock_and_undo_chunk(comp, "Remove tool"):
tool.Delete()

View file

@ -0,0 +1,71 @@
from openpype.pipeline import (
load,
get_representation_path,
)
from openpype.hosts.fusion.api import (
imprint_container,
get_current_comp,
comp_lock_and_undo_chunk
)
class FusionLoadFBXMesh(load.LoaderPlugin):
"""Load FBX mesh into Fusion"""
families = ["*"]
representations = ["fbx"]
label = "Load FBX mesh"
order = -10
icon = "code-fork"
color = "orange"
tool_type = "SurfaceFBXMesh"
def load(self, context, name, namespace, data):
# Fallback to asset name when namespace is None
if namespace is None:
namespace = context['asset']['name']
# Create the Loader with the filename path set
comp = get_current_comp()
with comp_lock_and_undo_chunk(comp, "Create tool"):
path = self.fname
args = (-32768, -32768)
tool = comp.AddTool(self.tool_type, *args)
tool["ImportFile"] = path
imprint_container(tool,
name=name,
namespace=namespace,
context=context,
loader=self.__class__.__name__)
def switch(self, container, representation):
self.update(container, representation)
def update(self, container, representation):
"""Update path"""
tool = container["_tool"]
assert tool.ID == self.tool_type, f"Must be {self.tool_type}"
comp = tool.Comp()
path = get_representation_path(representation)
with comp_lock_and_undo_chunk(comp, "Update tool"):
tool["ImportFile"] = path
# Update the imprinted representation
tool.SetData("avalon.representation", str(representation["_id"]))
def remove(self, container):
tool = container["_tool"]
assert tool.ID == self.tool_type, f"Must be {self.tool_type}"
comp = tool.Comp()
with comp_lock_and_undo_chunk(comp, "Remove tool"):
tool.Delete()

View file

@ -8,7 +8,7 @@ import hiero
from Qt import QtWidgets, QtCore
import qargparse
import openpype.api as openpype
from openpype.settings import get_current_project_settings
from openpype.lib import Logger
from openpype.pipeline import LoaderPlugin, LegacyCreator
from openpype.pipeline.context_tools import get_current_project_asset
@ -606,7 +606,7 @@ class Creator(LegacyCreator):
def __init__(self, *args, **kwargs):
super(Creator, self).__init__(*args, **kwargs)
import openpype.hosts.hiero.api as phiero
self.presets = openpype.get_current_project_settings()[
self.presets = get_current_project_settings()[
"hiero"]["create"].get(self.__class__.__name__, {})
# adding basic current context resolve objects

View file

@ -35,6 +35,9 @@ class ValidateWorkfilePaths(pyblish.api.InstancePlugin):
def get_invalid(cls):
invalid = []
for param, _ in hou.fileReferences():
if param is None:
continue
# skip nodes we are not interested in
if param.node().type().name() not in cls.node_types:
continue

View file

@ -23,7 +23,7 @@ from openpype.client import (
get_last_versions,
get_representation_by_name
)
from openpype.api import get_anatomy_settings
from openpype.settings import get_anatomy_settings
from openpype.pipeline import (
legacy_io,
discover_loader_plugins,

View file

@ -6,7 +6,7 @@ import six
import sys
from openpype.lib import Logger
from openpype.api import (
from openpype.settings import (
get_project_settings,
get_current_project_settings
)

View file

@ -9,7 +9,7 @@ import requests
from maya import cmds
from maya.app.renderSetup.model import renderSetup
from openpype.api import (
from openpype.settings import (
get_system_settings,
get_project_settings,
)

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Creator for Unreal Static Meshes."""
from openpype.hosts.maya.api import plugin, lib
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import legacy_io
from maya import cmds # noqa

View file

@ -12,7 +12,7 @@ from openpype.hosts.maya.api import (
lib,
plugin
)
from openpype.api import (
from openpype.settings import (
get_system_settings,
get_project_settings
)

View file

@ -1,7 +1,7 @@
import os
import clique
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path

View file

@ -4,7 +4,7 @@ from openpype.pipeline import (
load,
get_representation_path
)
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
class GpuCacheLoader(load.LoaderPlugin):

View file

@ -5,7 +5,7 @@ import clique
import maya.cmds as cmds
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path

View file

@ -1,7 +1,7 @@
import os
from maya import cmds
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import legacy_io
from openpype.pipeline.create import (
legacy_create,

View file

@ -1,6 +1,6 @@
import os
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path

View file

@ -1,6 +1,6 @@
import os
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path

View file

@ -1,6 +1,6 @@
import os
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path

View file

@ -10,7 +10,7 @@ import os
import maya.cmds as cmds
from openpype.client import get_representation_by_name
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import (
legacy_io,
load,

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import os
import maya.cmds as cmds # noqa
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path

View file

@ -6,7 +6,7 @@ from collections import defaultdict
import clique
from maya import cmds
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import (
load,
get_representation_path
@ -250,7 +250,7 @@ class YetiCacheLoader(load.LoaderPlugin):
"""
name = node_name.replace(":", "_")
pattern = r"^({name})(\.[0-4]+)?(\.fur)$".format(name=re.escape(name))
pattern = r"^({name})(\.[0-9]+)?(\.fur)$".format(name=re.escape(name))
files = [fname for fname in os.listdir(root) if re.match(pattern,
fname)]

View file

@ -1,7 +1,7 @@
import os
from collections import defaultdict
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
import openpype.hosts.maya.api.plugin
from openpype.hosts.maya.api import lib

View file

@ -136,8 +136,10 @@ class ExtractPlayblast(publish.Extractor):
self.log.debug("playblast path {}".format(path))
collected_files = os.listdir(stagingdir)
patterns = [clique.PATTERNS["frames"]]
collections, remainder = clique.assemble(collected_files,
minimum_items=1)
minimum_items=1,
patterns=patterns)
self.log.debug("filename {}".format(filename))
frame_collection = None

View file

@ -11,7 +11,7 @@ import pyblish.api
from openpype.lib import requests_post
from openpype.hosts.maya.api import lib
from openpype.pipeline import legacy_io
from openpype.api import get_system_settings
from openpype.settings import get_system_settings
# mapping between Maya renderer names and Muster template ids

View file

@ -1,5 +1,5 @@
import os
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import install_host
from openpype.hosts.maya.api import MayaHost
from maya import cmds

View file

@ -7,9 +7,7 @@ import nuke
import pyblish.api
import openpype
from openpype.api import (
get_current_project_settings
)
from openpype.settings import get_current_project_settings
from openpype.lib import register_event_callback, Logger
from openpype.pipeline import (
register_loader_plugin_path,

View file

@ -6,7 +6,7 @@ from abc import abstractmethod
import nuke
from openpype.api import get_current_project_settings
from openpype.settings import get_current_project_settings
from openpype.pipeline import (
LegacyCreator,
LoaderPlugin,

View file

@ -504,7 +504,7 @@ class Creator(LegacyCreator):
def __init__(self, *args, **kwargs):
super(Creator, self).__init__(*args, **kwargs)
from openpype.api import get_current_project_settings
from openpype.settings import get_current_project_settings
resolve_p_settings = get_current_project_settings().get("resolve")
self.presets = {}
if resolve_p_settings:

View file

@ -1,6 +1,6 @@
import os
from openpype.lib import Logger
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
log = Logger.get_logger(__name__)

View file

@ -10,7 +10,7 @@ import pyblish.api
from openpype.client import get_project, get_asset_by_name
from openpype.hosts import tvpaint
from openpype.api import get_current_project_settings
from openpype.settings import get_current_project_settings
from openpype.lib import register_event_callback
from openpype.pipeline import (
legacy_io,

View file

@ -24,7 +24,7 @@ from openpype.pipeline import (
legacy_io,
)
from openpype.pipeline.context_tools import get_current_project_asset
from openpype.api import get_current_project_settings
from openpype.settings import get_current_project_settings
from openpype.hosts.unreal.api import plugin
from openpype.hosts.unreal.api import pipeline as unreal_pipeline

View file

@ -500,6 +500,10 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline):
plugin_info["Renderer"] = renderer
# this is needed because renderman plugin in Deadline
# handles directory and file prefixes separately
plugin_info["OutputFilePath"] = job_info.OutputDirectory[0]
return job_info, plugin_info
def _get_vray_export_payload(self, data):

View file

@ -18,7 +18,7 @@ from openpype_modules.ftrack.lib import (
tool_definitions_from_app_manager
)
from openpype.api import get_system_settings
from openpype.settings import get_system_settings
from openpype.lib import ApplicationManager
"""

View file

@ -1,7 +1,7 @@
import os
import ftrack_api
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.lib import PostLaunchHook

View file

@ -43,7 +43,7 @@ import platform
import click
from openpype.modules import OpenPypeModule
from openpype.api import get_system_settings
from openpype.settings import get_system_settings
class JobQueueModule(OpenPypeModule):

View file

@ -12,7 +12,7 @@ from openpype.client import (
get_assets,
)
from openpype.pipeline import AvalonMongoDB
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.modules.kitsu.utils.credentials import validate_credentials

View file

@ -1,4 +1,4 @@
from openpype.api import get_system_settings, get_project_settings
from openpype.settings import get_system_settings, get_project_settings
from openpype.modules.shotgrid.lib.const import MODULE_NAME

View file

@ -1,5 +1,8 @@
from pyblish import api
from openpype.api import get_current_project_settings, get_system_settings
from openpype.settings import (
get_current_project_settings,
get_system_settings,
)
class CollectSettings(api.ContextPlugin):

View file

@ -4,8 +4,6 @@ import clique
import errno
import shutil
from bson.objectid import ObjectId
from pymongo import InsertOne, ReplaceOne
import pyblish.api
from openpype.client import (
@ -14,10 +12,15 @@ from openpype.client import (
get_archived_representations,
get_representations,
)
from openpype.client.operations import (
OperationsSession,
new_hero_version_doc,
prepare_hero_version_update_data,
prepare_representation_update_data,
)
from openpype.lib import create_hard_link
from openpype.pipeline import (
schema,
legacy_io,
schema
)
from openpype.pipeline.publish import get_publish_template_name
@ -187,35 +190,32 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
repre["name"].lower(): repre for repre in old_repres
}
op_session = OperationsSession()
entity_id = None
if old_version:
new_version_id = old_version["_id"]
else:
new_version_id = ObjectId()
new_hero_version = {
"_id": new_version_id,
"version_id": src_version_entity["_id"],
"parent": src_version_entity["parent"],
"type": "hero_version",
"schema": "openpype:hero_version-1.0"
}
schema.validate(new_hero_version)
# Don't make changes in database until everything is O.K.
bulk_writes = []
entity_id = old_version["_id"]
new_hero_version = new_hero_version_doc(
src_version_entity["_id"],
src_version_entity["parent"],
entity_id=entity_id
)
if old_version:
self.log.debug("Replacing old hero version.")
bulk_writes.append(
ReplaceOne(
{"_id": new_hero_version["_id"]},
new_hero_version
)
update_data = prepare_hero_version_update_data(
old_version, new_hero_version
)
op_session.update_entity(
project_name,
new_hero_version["type"],
old_version["_id"],
update_data
)
else:
self.log.debug("Creating first hero version.")
bulk_writes.append(
InsertOne(new_hero_version)
op_session.create_entity(
project_name, new_hero_version["type"], new_hero_version
)
# Separate old representations into `to replace` and `to delete`
@ -235,7 +235,7 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
archived_repres = list(get_archived_representations(
project_name,
# Check what is type of archived representation
version_ids=[new_version_id]
version_ids=[new_hero_version["_id"]]
))
archived_repres_by_name = {}
for repre in archived_repres:
@ -382,12 +382,15 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
# Replace current representation
if repre_name_low in old_repres_to_replace:
old_repre = old_repres_to_replace.pop(repre_name_low)
repre["_id"] = old_repre["_id"]
bulk_writes.append(
ReplaceOne(
{"_id": old_repre["_id"]},
repre
)
update_data = prepare_representation_update_data(
old_repre, repre)
op_session.update_entity(
project_name,
old_repre["type"],
old_repre["_id"],
update_data
)
# Unarchive representation
@ -395,21 +398,21 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
archived_repre = archived_repres_by_name.pop(
repre_name_low
)
old_id = archived_repre["old_id"]
repre["_id"] = old_id
bulk_writes.append(
ReplaceOne(
{"old_id": old_id},
repre
)
repre["_id"] = archived_repre["old_id"]
update_data = prepare_representation_update_data(
archived_repre, repre)
op_session.update_entity(
project_name,
old_repre["type"],
archived_repre["_id"],
update_data
)
# Create representation
else:
repre["_id"] = ObjectId()
bulk_writes.append(
InsertOne(repre)
)
repre.pop("_id", None)
op_session.create_entity(project_name, "representation",
repre)
self.path_checks = []
@ -430,28 +433,22 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
archived_repre = archived_repres_by_name.pop(
repre_name_low
)
repre["old_id"] = repre["_id"]
repre["_id"] = archived_repre["_id"]
repre["type"] = archived_repre["type"]
bulk_writes.append(
ReplaceOne(
{"_id": archived_repre["_id"]},
repre
)
)
changes = {"old_id": repre["_id"],
"_id": archived_repre["_id"],
"type": archived_repre["type"]}
op_session.update_entity(project_name,
archived_repre["type"],
archived_repre["_id"],
changes)
else:
repre["old_id"] = repre["_id"]
repre["_id"] = ObjectId()
repre["old_id"] = repre.pop("_id")
repre["type"] = "archived_representation"
bulk_writes.append(
InsertOne(repre)
)
op_session.create_entity(project_name,
"archived_representation",
repre)
if bulk_writes:
legacy_io.database[project_name].bulk_write(
bulk_writes
)
op_session.commit()
# Remove backuped previous hero
if (

View file

@ -6,7 +6,7 @@ from Qt import QtWidgets, QtCore
from openpype.client import get_asset_by_name, get_subsets
from openpype import style
from openpype.api import get_current_project_settings
from openpype.settings import get_current_project_settings
from openpype.tools.utils.lib import qt_app_context
from openpype.pipeline import legacy_io
from openpype.pipeline.create import (

View file

@ -1256,7 +1256,11 @@ class RepresentationWidget(QtWidgets.QWidget):
repre_doc["parent"]
for repre_doc in repre_docs
]
version_docs = get_versions(project_name, version_ids=version_ids)
version_docs = get_versions(
project_name,
version_ids=version_ids,
hero=True
)
version_docs_by_id = {}
version_docs_by_subset_id = collections.defaultdict(list)

View file

@ -22,7 +22,7 @@ import pyblish.version
from . import util
from .constants import InstanceStates
from openpype.api import get_project_settings
from openpype.settings import get_current_project_settings
class IterationBreak(Exception):
@ -204,7 +204,7 @@ class Controller(QtCore.QObject):
def presets_by_hosts(self):
# Get global filters as base
presets = get_project_settings(os.environ['AVALON_PROJECT']) or {}
presets = get_current_project_settings()
if not presets:
return {}

View file

@ -34,7 +34,7 @@ import qtawesome
from six import text_type
from .constants import PluginStates, InstanceStates, GroupStates, Roles
from openpype.api import get_system_settings
from openpype.settings import get_system_settings
# ItemTypes

View file

@ -2,6 +2,10 @@ from Qt import QtWidgets, QtGui
from openpype import style
from openpype.settings import (
SystemSettings,
ProjectSettings
)
from openpype.settings.lib import (
get_local_settings,
save_local_settings
@ -9,10 +13,6 @@ from openpype.settings.lib import (
from openpype.lib import Logger
from openpype.tools.settings import CHILD_OFFSET
from openpype.tools.utils import MessageOverlayObject
from openpype.api import (
SystemSettings,
ProjectSettings
)
from openpype.modules import ModulesManager
from .widgets import (

View file

@ -775,12 +775,26 @@ class PypeTrayStarter(QtCore.QObject):
def main():
log = Logger.get_logger(__name__)
app = QtWidgets.QApplication.instance()
high_dpi_scale_attr = None
if not app:
# 'AA_EnableHighDpiScaling' must be set before app instance creation
high_dpi_scale_attr = getattr(
QtCore.Qt, "AA_EnableHighDpiScaling", None
)
if high_dpi_scale_attr is not None:
QtWidgets.QApplication.setAttribute(high_dpi_scale_attr)
app = QtWidgets.QApplication([])
if high_dpi_scale_attr is None:
log.debug((
"Attribute 'AA_EnableHighDpiScaling' was not set."
" UI quality may be affected."
))
for attr_name in (
"AA_EnableHighDpiScaling",
"AA_UseHighDpiPixmaps"
"AA_UseHighDpiPixmaps",
):
attr = getattr(QtCore.Qt, attr_name, None)
if attr is None:

View file

@ -17,7 +17,7 @@ from openpype.style import (
)
from openpype.resources import get_image_path
from openpype.lib import filter_profiles, Logger
from openpype.api import get_project_settings
from openpype.settings import get_project_settings
from openpype.pipeline import registered_host
log = Logger.get_logger(__name__)

View file

@ -3,7 +3,7 @@ from Qt import QtWidgets, QtCore, QtGui
from openpype import style
from openpype.resources import get_resource
from openpype.api import get_system_settings
from openpype.settings import get_system_settings
from openpype.settings.lib import (
get_local_settings,
save_local_settings