Merge branch 'develop' into enhancement/OP-2925_move-remaining-plugins

This commit is contained in:
Jakub Trllo 2022-03-22 16:14:22 +01:00
commit ac6182c792
86 changed files with 259 additions and 721 deletions

View file

@ -308,7 +308,6 @@ class ContextDialog(QtWidgets.QDialog):
self._validate_strict()
def _set_asset_to_tasks_widget(self):
# filter None docs they are silo
asset_id = self._assets_widget.get_selected_asset_id()
self._tasks_widget.set_asset_id(asset_id)

View file

@ -1,19 +1,3 @@
"""Utility script for updating database with configuration files
Until assets are created entirely in the database, this script
provides a bridge between the file-based project inventory and configuration.
- Migrating an old project:
$ python -m avalon.inventory --extract --silo-parent=f02_prod
$ python -m avalon.inventory --upload
- Managing an existing project:
1. Run `python -m avalon.inventory --load`
2. Update the .inventory.toml or .config.toml
3. Run `python -m avalon.inventory --save`
"""
import os
from Qt import QtGui
import qtawesome

View file

@ -9,14 +9,14 @@ from openpype.tools.loader.widgets import (
ThumbnailWidget,
VersionWidget,
FamilyListView,
RepresentationWidget
RepresentationWidget,
SubsetWidget
)
from openpype.tools.utils.assets_widget import MultiSelectAssetsWidget
from openpype.modules import ModulesManager
from . import lib
from .widgets import LibrarySubsetWidget
module = sys.modules[__name__]
module.window = None
@ -92,7 +92,7 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
# --- Middle part ---
# Subsets widget
subsets_widget = LibrarySubsetWidget(
subsets_widget = SubsetWidget(
dbcon,
self.groups_config,
self.family_config_cache,
@ -448,10 +448,7 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
def _set_context(self, context, refresh=True):
"""Set the selection in the interface using a context.
The context must contain `asset` data by name.
Note: Prior to setting context ensure `refresh` is triggered so that
the "silos" are listed correctly, aside from that setting the
context will force a refresh further down because it changes
the active silo and asset.
Args:
context (dict): The context to apply.
Returns:
@ -463,12 +460,6 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
return
if refresh:
# Workaround:
# Force a direct (non-scheduled) refresh prior to setting the
# asset widget's silo and asset selection to ensure it's correctly
# displaying the silo tabs. Calling `window.refresh()` and directly
# `window.set_context()` the `set_context()` seems to override the
# scheduled refresh and the silo tabs are not shown.
self._refresh_assets()
self._assets_widget.select_asset_by_name(asset_name)

View file

@ -1,7 +1,6 @@
import os
import importlib
import logging
from openpype.api import Anatomy
log = logging.getLogger(__name__)
@ -20,14 +19,3 @@ def find_config():
log.info("Found %s, loading.." % config)
return importlib.import_module(config)
class RegisteredRoots:
roots_per_project = {}
@classmethod
def registered_root(cls, project_name):
if project_name not in cls.roots_per_project:
cls.roots_per_project[project_name] = Anatomy(project_name).roots
return cls.roots_per_project[project_name]

View file

@ -1,18 +0,0 @@
from Qt import QtWidgets
from .lib import RegisteredRoots
from openpype.tools.loader.widgets import SubsetWidget
class LibrarySubsetWidget(SubsetWidget):
def on_copy_source(self):
"""Copy formatted source path to clipboard"""
source = self.data.get("source", None)
if not source:
return
project_name = self.dbcon.Session["AVALON_PROJECT"]
root = RegisteredRoots.registered_root(project_name)
path = source.format(root=root)
clipboard = QtWidgets.QApplication.clipboard()
clipboard.setText(path)

View file

@ -290,7 +290,6 @@ class LoaderWindow(QtWidgets.QDialog):
subsets_model.clear()
self.clear_assets_underlines()
# filter None docs they are silo
asset_ids = self._assets_widget.get_selected_asset_ids()
# Start loading
subsets_widget.set_loading_state(
@ -381,17 +380,9 @@ class LoaderWindow(QtWidgets.QDialog):
The context must contain `asset` data by name.
Note: Prior to setting context ensure `refresh` is triggered so that
the "silos" are listed correctly, aside from that setting the
context will force a refresh further down because it changes
the active silo and asset.
Args:
context (dict): The context to apply.
Returns:
None
refrest (bool): Trigger refresh on context set.
"""
asset = context.get("asset", None)
@ -399,12 +390,6 @@ class LoaderWindow(QtWidgets.QDialog):
return
if refresh:
# Workaround:
# Force a direct (non-scheduled) refresh prior to setting the
# asset widget's silo and asset selection to ensure it's correctly
# displaying the silo tabs. Calling `window.refresh()` and directly
# `window.set_context()` the `set_context()` seems to override the
# scheduled refresh and the silo tabs are not shown.
self._refresh()
self._assets_widget.select_asset_by_name(asset)

View file

@ -7,8 +7,7 @@ import collections
from Qt import QtWidgets, QtCore, QtGui
from avalon import api
from openpype.api import Anatomy
from openpype.pipeline import HeroVersionType
from openpype.pipeline.thumbnail import get_thumbnail_binary
from openpype.pipeline.load import (
@ -641,6 +640,7 @@ class VersionTextEdit(QtWidgets.QTextEdit):
"source": None,
"raw": None
}
self._anatomy = None
# Reset
self.set_version(None)
@ -731,20 +731,20 @@ class VersionTextEdit(QtWidgets.QTextEdit):
# Add additional actions when any text so we can assume
# the version is set.
if self.toPlainText().strip():
menu.addSeparator()
action = QtWidgets.QAction("Copy source path to clipboard",
menu)
action = QtWidgets.QAction(
"Copy source path to clipboard", menu
)
action.triggered.connect(self.on_copy_source)
menu.addAction(action)
action = QtWidgets.QAction("Copy raw data to clipboard",
menu)
action = QtWidgets.QAction(
"Copy raw data to clipboard", menu
)
action.triggered.connect(self.on_copy_raw)
menu.addAction(action)
menu.exec_(event.globalPos())
del menu
def on_copy_source(self):
"""Copy formatted source path to clipboard"""
@ -752,7 +752,11 @@ class VersionTextEdit(QtWidgets.QTextEdit):
if not source:
return
path = source.format(root=api.registered_root())
project_name = self.dbcon.Session["AVALON_PROJECT"]
if self._anatomy is None or self._anatomy.project_name != project_name:
self._anatomy = Anatomy(project_name)
path = source.format(root=self._anatomy.roots)
clipboard = QtWidgets.QApplication.clipboard()
clipboard.setText(path)
@ -772,7 +776,6 @@ class VersionTextEdit(QtWidgets.QTextEdit):
class ThumbnailWidget(QtWidgets.QLabel):
aspect_ratio = (16, 9)
max_width = 300

View file

@ -2,6 +2,7 @@ from collections import defaultdict
import logging
import os
from bson.objectid import ObjectId
import maya.cmds as cmds
from avalon import io, api
@ -157,7 +158,7 @@ def create_items_from_nodes(nodes):
return asset_view_items
for _id, id_nodes in id_hashes.items():
asset = io.find_one({"_id": io.ObjectId(_id)},
asset = io.find_one({"_id": ObjectId(_id)},
projection={"name": True})
# Skip if asset id is not found

View file

@ -6,6 +6,7 @@ import logging
import json
import six
from bson.objectid import ObjectId
import alembic.Abc
from maya import cmds
@ -231,7 +232,7 @@ def get_latest_version(asset_id, subset):
"""
subset = io.find_one({"name": subset,
"parent": io.ObjectId(asset_id),
"parent": ObjectId(asset_id),
"type": "subset"})
if not subset:
raise RuntimeError("Subset does not exist: %s" % subset)

View file

@ -5,6 +5,7 @@ from collections import defaultdict
from Qt import QtCore, QtGui
import qtawesome
from bson.objectid import ObjectId
from avalon import api, io, schema
from openpype.pipeline import HeroVersionType
@ -299,7 +300,7 @@ class InventoryModel(TreeModel):
for repre_id, group_dict in sorted(grouped.items()):
group_items = group_dict["items"]
# Get parenthood per group
representation = io.find_one({"_id": io.ObjectId(repre_id)})
representation = io.find_one({"_id": ObjectId(repre_id)})
if not representation:
not_found["representation"].append(group_items)
not_found_ids.append(repre_id)

View file

@ -2,6 +2,7 @@ import collections
import logging
from Qt import QtWidgets, QtCore
import qtawesome
from bson.objectid import ObjectId
from avalon import io, pipeline
from openpype.pipeline import (
@ -146,7 +147,7 @@ class SwitchAssetDialog(QtWidgets.QDialog):
repre_ids = set()
content_loaders = set()
for item in self._items:
repre_ids.add(io.ObjectId(item["representation"]))
repre_ids.add(ObjectId(item["representation"]))
content_loaders.add(item["loader"])
repres = list(io.find({
@ -1306,7 +1307,7 @@ class SwitchAssetDialog(QtWidgets.QDialog):
repre_docs_by_parent_id_by_name[parent_id][name] = repre_doc
for container in self._items:
container_repre_id = io.ObjectId(container["representation"])
container_repre_id = ObjectId(container["representation"])
container_repre = self.content_repres[container_repre_id]
container_repre_name = container_repre["name"]

View file

@ -4,6 +4,7 @@ from functools import partial
from Qt import QtWidgets, QtCore
import qtawesome
from bson.objectid import ObjectId
from avalon import io
@ -79,7 +80,7 @@ class SceneInventoryView(QtWidgets.QTreeView):
repre_ids = []
for item in items:
item_id = io.ObjectId(item["representation"])
item_id = ObjectId(item["representation"])
if item_id not in repre_ids:
repre_ids.append(item_id)
@ -146,7 +147,7 @@ class SceneInventoryView(QtWidgets.QTreeView):
def _on_switch_to_versioned(items):
repre_ids = []
for item in items:
item_id = io.ObjectId(item["representation"])
item_id = ObjectId(item["representation"])
if item_id not in repre_ids:
repre_ids.append(item_id)
@ -196,7 +197,7 @@ class SceneInventoryView(QtWidgets.QTreeView):
version_doc["name"]
for item in items:
repre_id = io.ObjectId(item["representation"])
repre_id = ObjectId(item["representation"])
version_id = version_id_by_repre_id.get(repre_id)
version_name = version_name_by_id.get(version_id)
if version_name is not None:
@ -659,7 +660,7 @@ class SceneInventoryView(QtWidgets.QTreeView):
active = items[-1]
# Get available versions for active representation
representation_id = io.ObjectId(active["representation"])
representation_id = ObjectId(active["representation"])
representation = io.find_one({"_id": representation_id})
version = io.find_one({
"_id": representation["parent"]

View file

@ -35,7 +35,7 @@ def _iter_model_rows(model,
class AssetModel(TreeModel):
"""A model listing assets in the silo in the active project.
"""A model listing assets in the active project.
The assets are displayed in a treeview, they are visually parented by
a `visualParent` field in the database containing an `_id` to a parent
@ -64,7 +64,7 @@ class AssetModel(TreeModel):
self.refresh()
def _add_hierarchy(self, assets, parent=None, silos=None):
def _add_hierarchy(self, assets, parent=None):
"""Add the assets that are related to the parent as children items.
This method does *not* query the database. These instead are queried
@ -72,27 +72,8 @@ class AssetModel(TreeModel):
queries. Resulting in up to 10x speed increase.
Args:
assets (dict): All assets in the currently active silo stored
by key/value
Returns:
None
assets (dict): All assets from current project.
"""
if silos:
# WARNING: Silo item "_id" is set to silo value
# mainly because GUI issue with preserve selection and expanded row
# and because of easier hierarchy parenting (in "assets")
for silo in silos:
node = Node({
"_id": silo,
"name": silo,
"label": silo,
"type": "silo"
})
self.add_child(node, parent=parent)
self._add_hierarchy(assets, parent=node)
parent_id = parent["_id"] if parent else None
current_assets = assets.get(parent_id, list())
@ -132,27 +113,19 @@ class AssetModel(TreeModel):
self.beginResetModel()
# Get all assets in current silo sorted by name
# Get all assets in current project sorted by name
db_assets = self.dbcon.find({"type": "asset"}).sort("name", 1)
silos = db_assets.distinct("silo") or None
# if any silo is set to None then it's expected it should not be used
if silos and None in silos:
silos = None
# Group the assets by their visual parent's id
assets_by_parent = collections.defaultdict(list)
for asset in db_assets:
parent_id = (
asset.get("data", {}).get("visualParent") or
asset.get("silo")
)
parent_id = asset.get("data", {}).get("visualParent")
assets_by_parent[parent_id].append(asset)
# Build the hierarchical tree items recursively
self._add_hierarchy(
assets_by_parent,
parent=None,
silos=silos
parent=None
)
self.endResetModel()
@ -174,8 +147,6 @@ class AssetModel(TreeModel):
# Allow a custom icon and custom icon color to be defined
data = node.get("_document", {}).get("data", {})
icon = data.get("icon", None)
if icon is None and node.get("type") == "silo":
icon = "database"
color = data.get("color", self._default_asset_icon_color)
if icon is None:

View file

@ -229,7 +229,6 @@ class AssetWidget(QtWidgets.QWidget):
data = {
'project': project['name'],
'asset': asset['name'],
'silo': asset.get("silo"),
'parents': self.get_parents(asset),
'task': task
}

View file

@ -57,7 +57,6 @@ class TextureCopy:
"name": project_name,
"code": project['data']['code']
},
"silo": asset.get('silo'),
"asset": asset['name'],
"family": 'texture',
"subset": 'Main',
@ -155,7 +154,6 @@ def texture_copy(asset, project, path):
t.echo(">>> Initializing avalon session ...")
os.environ["AVALON_PROJECT"] = project
os.environ["AVALON_ASSET"] = asset
os.environ["AVALON_SILO"] = ""
TextureCopy().process(asset, project, path)

View file

@ -1266,7 +1266,6 @@ def show(root=None, debug=False, parent=None, use_context=True, save=True):
if use_context:
context = {
"asset": api.Session["AVALON_ASSET"],
"silo": api.Session["AVALON_SILO"],
"task": api.Session["AVALON_TASK"]
}
window.set_context(context)