Merge branch 'develop' into feature/new_fonts_in_style

This commit is contained in:
Milan Kolar 2021-11-18 14:07:18 +01:00 committed by GitHub
commit 83326fda37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 157 additions and 82 deletions

View file

@ -1,8 +1,22 @@
# Changelog
## [3.6.2-nightly.1](https://github.com/pypeclub/OpenPype/tree/HEAD)
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.6.1...HEAD)
**🚀 Enhancements**
- Tools: SceneInventory in OpenPype [\#2255](https://github.com/pypeclub/OpenPype/pull/2255)
- Tools: Tasks widget [\#2251](https://github.com/pypeclub/OpenPype/pull/2251)
- Added endpoint for configured extensions [\#2221](https://github.com/pypeclub/OpenPype/pull/2221)
**🐛 Bug fixes**
- Burnins: Support mxf metadata [\#2247](https://github.com/pypeclub/OpenPype/pull/2247)
## [3.6.1](https://github.com/pypeclub/OpenPype/tree/3.6.1) (2021-11-16)
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.6.0...3.6.1)
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.6.1-nightly.1...3.6.1)
**🐛 Bug fixes**
@ -12,6 +26,11 @@
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.6.0-nightly.6...3.6.0)
### 📖 Documentation
- Add alternative sites for Site Sync [\#2206](https://github.com/pypeclub/OpenPype/pull/2206)
- Add command line way of running site sync server [\#2188](https://github.com/pypeclub/OpenPype/pull/2188)
**🆕 New features**
- Add validate active site button to sync queue on a project [\#2176](https://github.com/pypeclub/OpenPype/pull/2176)
@ -32,7 +51,6 @@
- Maya : Validate shape zero [\#2212](https://github.com/pypeclub/OpenPype/pull/2212)
- Maya : validate unique names [\#2211](https://github.com/pypeclub/OpenPype/pull/2211)
- Tools: OpenPype stylesheet in workfiles tool [\#2208](https://github.com/pypeclub/OpenPype/pull/2208)
- Add alternative sites for Site Sync [\#2206](https://github.com/pypeclub/OpenPype/pull/2206)
- Ftrack: Replace Queue with deque in event handlers logic [\#2204](https://github.com/pypeclub/OpenPype/pull/2204)
- Tools: New select context dialog [\#2200](https://github.com/pypeclub/OpenPype/pull/2200)
- Maya : Validate mesh ngons [\#2199](https://github.com/pypeclub/OpenPype/pull/2199)
@ -42,7 +60,6 @@
- Usage of tools code [\#2185](https://github.com/pypeclub/OpenPype/pull/2185)
- Settings: Dictionary based on project roots [\#2184](https://github.com/pypeclub/OpenPype/pull/2184)
- Subset name: Be able to pass asset document to get subset name [\#2179](https://github.com/pypeclub/OpenPype/pull/2179)
- Loader: Refactor and use OpenPype stylesheets [\#2166](https://github.com/pypeclub/OpenPype/pull/2166)
**🐛 Bug fixes**
@ -62,10 +79,6 @@
- Maya: review viewport settings [\#2177](https://github.com/pypeclub/OpenPype/pull/2177)
- Maya: Aspect ratio [\#2174](https://github.com/pypeclub/OpenPype/pull/2174)
### 📖 Documentation
- Add command line way of running site sync server [\#2188](https://github.com/pypeclub/OpenPype/pull/2188)
## [3.5.0](https://github.com/pypeclub/OpenPype/tree/3.5.0) (2021-10-17)
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.5.0-nightly.8...3.5.0)
@ -88,7 +101,6 @@
- Fix - oiiotool wasn't recognized even if present [\#2129](https://github.com/pypeclub/OpenPype/pull/2129)
- General: Disk mapping group [\#2120](https://github.com/pypeclub/OpenPype/pull/2120)
- Hiero: publishing effect first time makes wrong resources path [\#2115](https://github.com/pypeclub/OpenPype/pull/2115)
- Add startup script for Houdini Core. [\#2110](https://github.com/pypeclub/OpenPype/pull/2110)
## [3.4.1](https://github.com/pypeclub/OpenPype/tree/3.4.1) (2021-09-23)

View file

@ -532,7 +532,7 @@ class CollectLook(pyblish.api.InstancePlugin):
color_space = cmds.getAttr(color_space_attr)
except ValueError:
# node doesn't have colorspace attribute
color_space = "raw"
color_space = "Raw"
# Compare with the computed file path, e.g. the one with the <UDIM>
# pattern in it, to generate some logging information about this
# difference

View file

@ -41,6 +41,7 @@ Provides:
import re
import os
import platform
import json
from maya import cmds
@ -255,6 +256,11 @@ class CollectMayaRender(pyblish.api.ContextPlugin):
common_publish_meta_path, part)
if part == expected_layer_name:
break
# TODO: replace this terrible linux hotfix with real solution :)
if platform.system().lower() in ["linux", "darwin"]:
common_publish_meta_path = "/" + common_publish_meta_path
self.log.info(
"Publish meta path: {}".format(common_publish_meta_path))

View file

@ -332,10 +332,10 @@ class ExtractLook(openpype.api.Extractor):
if do_maketx and files_metadata[filepath]["color_space"].lower() == "srgb": # noqa: E501
linearize = True
# set its file node to 'raw' as tx will be linearized
files_metadata[filepath]["color_space"] = "raw"
files_metadata[filepath]["color_space"] = "Raw"
if do_maketx:
color_space = "raw"
# if do_maketx:
# color_space = "Raw"
source, mode, texture_hash = self._process_texture(
filepath,
@ -383,11 +383,11 @@ class ExtractLook(openpype.api.Extractor):
color_space = cmds.getAttr(color_space_attr)
except ValueError:
# node doesn't have color space attribute
color_space = "raw"
color_space = "Raw"
else:
if files_metadata[source]["color_space"] == "raw":
if files_metadata[source]["color_space"] == "Raw":
# set color space to raw if we linearized it
color_space = "raw"
color_space = "Raw"
# Remap file node filename to destination
remap[color_space_attr] = color_space
attr = resource["attribute"]

View file

@ -176,6 +176,7 @@ class PythonCodeEditor(QtWidgets.QPlainTextEdit):
class PythonTabWidget(QtWidgets.QWidget):
add_tab_requested = QtCore.Signal()
before_execute = QtCore.Signal(str)
def __init__(self, parent):
@ -185,11 +186,15 @@ class PythonTabWidget(QtWidgets.QWidget):
self.setFocusProxy(code_input)
add_tab_btn = QtWidgets.QPushButton("Add tab...", self)
add_tab_btn.setToolTip("Add new tab")
execute_btn = QtWidgets.QPushButton("Execute", self)
execute_btn.setToolTip("Execute command (Ctrl + Enter)")
btns_layout = QtWidgets.QHBoxLayout()
btns_layout.setContentsMargins(0, 0, 0, 0)
btns_layout.addWidget(add_tab_btn)
btns_layout.addStretch(1)
btns_layout.addWidget(execute_btn)
@ -198,12 +203,16 @@ class PythonTabWidget(QtWidgets.QWidget):
layout.addWidget(code_input, 1)
layout.addLayout(btns_layout, 0)
add_tab_btn.clicked.connect(self._on_add_tab_clicked)
execute_btn.clicked.connect(self._on_execute_clicked)
code_input.execute_requested.connect(self.execute)
self._code_input = code_input
self._interpreter = InteractiveInterpreter()
def _on_add_tab_clicked(self):
self.add_tab_requested.emit()
def _on_execute_clicked(self):
self.execute()
@ -352,9 +361,6 @@ class PythonInterpreterWidget(QtWidgets.QWidget):
tab_widget.setTabsClosable(False)
tab_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
add_tab_btn = QtWidgets.QPushButton("+", tab_widget)
tab_widget.setCornerWidget(add_tab_btn, QtCore.Qt.TopLeftCorner)
widgets_splitter = QtWidgets.QSplitter(self)
widgets_splitter.setOrientation(QtCore.Qt.Vertical)
widgets_splitter.addWidget(output_widget)
@ -371,14 +377,12 @@ class PythonInterpreterWidget(QtWidgets.QWidget):
line_check_timer.setInterval(200)
line_check_timer.timeout.connect(self._on_timer_timeout)
add_tab_btn.clicked.connect(self._on_add_clicked)
tab_bar.right_clicked.connect(self._on_tab_right_click)
tab_bar.double_clicked.connect(self._on_tab_double_click)
tab_bar.mid_clicked.connect(self._on_tab_mid_click)
tab_widget.tabCloseRequested.connect(self._on_tab_close_req)
self._widgets_splitter = widgets_splitter
self._add_tab_btn = add_tab_btn
self._output_widget = output_widget
self._tab_widget = tab_widget
self._line_check_timer = line_check_timer
@ -459,14 +463,41 @@ class PythonInterpreterWidget(QtWidgets.QWidget):
return
menu = QtWidgets.QMenu(self._tab_widget)
menu.addAction("Rename")
add_tab_action = QtWidgets.QAction("Add tab...", menu)
add_tab_action.setToolTip("Add new tab")
rename_tab_action = QtWidgets.QAction("Rename...", menu)
rename_tab_action.setToolTip("Rename tab")
duplicate_tab_action = QtWidgets.QAction("Duplicate...", menu)
duplicate_tab_action.setToolTip("Duplicate code to new tab")
close_tab_action = QtWidgets.QAction("Close", menu)
close_tab_action.setToolTip("Close tab and lose content")
close_tab_action.setEnabled(self._tab_widget.tabsClosable())
menu.addAction(add_tab_action)
menu.addAction(rename_tab_action)
menu.addAction(duplicate_tab_action)
menu.addAction(close_tab_action)
result = menu.exec_(global_point)
if result is None:
return
if result.text() == "Rename":
if result is rename_tab_action:
self._rename_tab_req(tab_idx)
elif result is add_tab_action:
self._on_add_requested()
elif result is duplicate_tab_action:
self._duplicate_requested(tab_idx)
elif result is close_tab_action:
self._on_tab_close_req(tab_idx)
def _rename_tab_req(self, tab_idx):
dialog = TabNameDialog(self)
dialog.set_tab_name(self._tab_widget.tabText(tab_idx))
@ -475,6 +506,16 @@ class PythonInterpreterWidget(QtWidgets.QWidget):
if tab_name:
self._tab_widget.setTabText(tab_idx, tab_name)
def _duplicate_requested(self, tab_idx=None):
if tab_idx is None:
tab_idx = self._tab_widget.currentIndex()
src_widget = self._tab_widget.widget(tab_idx)
dst_widget = self._add_tab()
if dst_widget is None:
return
dst_widget.set_code(src_widget.get_code())
def _on_tab_mid_click(self, global_point):
point = self._tab_widget.mapFromGlobal(global_point)
tab_bar = self._tab_widget.tabBar()
@ -525,12 +566,17 @@ class PythonInterpreterWidget(QtWidgets.QWidget):
lines.append(self.ansi_escape.sub("", line))
self._append_lines(lines)
def _on_add_clicked(self):
def _on_add_requested(self):
self._add_tab()
def _add_tab(self):
dialog = TabNameDialog(self)
dialog.exec_()
tab_name = dialog.result()
if tab_name:
self.add_tab(tab_name)
return self.add_tab(tab_name)
return None
def _on_before_execute(self, code_text):
at_max = self._output_widget.vertical_scroll_at_max()
@ -562,6 +608,7 @@ class PythonInterpreterWidget(QtWidgets.QWidget):
def add_tab(self, tab_name, index=None):
widget = PythonTabWidget(self)
widget.before_execute.connect(self._on_before_execute)
widget.add_tab_requested.connect(self._on_add_requested)
if index is None:
if self._tab_widget.count() > 0:
index = self._tab_widget.currentIndex() + 1

View file

@ -12,6 +12,12 @@ class ValidateEditorialAssetName(pyblish.api.ContextPlugin):
order = pyblish.api.ValidatorOrder
label = "Validate Editorial Asset Name"
hosts = [
"hiero",
"standalonepublisher",
"resolve",
"flame"
]
def process(self, context):

View file

@ -173,9 +173,9 @@
"workfile_families": [],
"texture_families": [],
"color_space": [
"linsRGB",
"raw",
"acesg"
"sRGB",
"Raw",
"ACEScg"
],
"input_naming_patterns": {
"workfile": [

View file

@ -18,7 +18,6 @@
"green-light": "hsl(155, 80%, 80%)"
},
"color": {
"font": "#D3D8DE",
"font-hover": "#F0F2F5",
"font-disabled": "#99A3B2",
@ -50,7 +49,16 @@
"border": "#373D48",
"border-hover": "rgba(168, 175, 189, .3)",
"border-focus": "hsl(200, 60%, 60%)",
"border-focus": "rgb(92, 173, 214)",
"tab-widget": {
"bg": "#21252B",
"bg-selected": "#434a56",
"bg-hover": "#373D48",
"color": "#99A3B2",
"color-selected": "#F0F2F5",
"color-hover": "#F0F2F5"
},
"loader": {
"asset-view": {

View file

@ -325,47 +325,38 @@ QTabWidget::pane {
/* move to the right to not mess with borders of widget underneath */
QTabWidget::tab-bar {
left: 2px;
alignment: left;
}
QTabBar::tab {
padding: 5px;
border-left: 3px solid transparent;
border-top: 1px solid {color:border};
border-left: 1px solid {color:border};
border-right: 1px solid {color:border};
/* must be single like because of Nuke*/
background: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,stop: 0.5 {color:bg}, stop: 1.0 {color:bg-inputs});
padding: 5px;
background: {color:tab-widget:bg};
color: {color:tab-widget:color};
}
QTabBar::tab:selected {
background: {color:grey-lighter};
border-left: 3px solid {color:border-focus};
/* must be single like because of Nuke*/
background: qlineargradient(x1: 0, y1: 1, x2: 0, y2: 0,stop: 0.5 {color:bg}, stop: 1.0 {color:border});
}
QTabBar::tab:!selected {
background: {color:grey-light};
border-left-color: {color:tab-widget:bg-selected};
border-right-color: {color:tab-widget:bg-selected};
border-top-color: {color:border-focus};
background: {color:tab-widget:bg-selected};
color: {color:tab-widget:color-selected};
}
QTabBar::tab:!selected {}
QTabBar::tab:!selected:hover {
background: {color:grey-lighter};
background: {color:tab-widget:bg-hover};
color: {color:tab-widget:color-hover};
}
QTabBar::tab:first {
border-left: 1px solid {color:border};
}
QTabBar::tab:first:selected {
margin-left: 0;
border-left: 3px solid {color:border-focus};
}
QTabBar::tab:last:selected {
margin-right: 0;
}
QTabBar::tab:only-one {
margin: 0;
QTabBar::tab:first {}
QTabBar::tab:first:selected {}
QTabBar::tab:last:!selected {
border-right: 1px solid {color:border};
}
QTabBar::tab:last:selected {}
QTabBar::tab:only-one {}
QHeaderView {
border: 0px solid {color:border};
@ -774,6 +765,7 @@ QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
/* Python console interpreter */
#PythonInterpreterOutput, #PythonCodeEditor {
font-family: "Noto Sans Mono";
border-radius: 0px;
}
#SubsetView::item, #RepresentationView:item {

View file

@ -113,9 +113,7 @@ class ContextDialog(QtWidgets.QDialog):
assets_widget.selection_changed.connect(self._on_asset_change)
assets_widget.refresh_triggered.connect(self._on_asset_refresh_trigger)
assets_widget.refreshed.connect(self._on_asset_widget_refresh_finished)
tasks_widget.task_changed.selectionChanged.connect(
self._on_task_change
)
tasks_widget.task_changed.connect(self._on_task_change)
ok_btn.clicked.connect(self._on_ok_click)
self._dbcon = dbcon

View file

@ -38,6 +38,7 @@ class App(QtWidgets.QWidget):
# Store callback references
self._callbacks = []
self._connections_set_up = False
filename = get_workfile()
@ -46,17 +47,10 @@ class App(QtWidgets.QWidget):
self.setWindowFlags(QtCore.Qt.Window)
self.setParent(parent)
# Force to delete the window on close so it triggers
# closeEvent only once. Otherwise it's retriggered when
# the widget gets garbage collected.
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.resize(750, 500)
self.setup_ui()
self.setup_connections()
# Force refresh check on initialization
self._on_renderlayer_switch()
@ -111,6 +105,16 @@ class App(QtWidgets.QWidget):
asset_outliner.view.setColumnWidth(0, 200)
look_outliner.view.setColumnWidth(0, 150)
asset_outliner.selection_changed.connect(
self.on_asset_selection_changed)
asset_outliner.refreshed.connect(
lambda: self.echo("Loaded assets..")
)
look_outliner.menu_apply_action.connect(self.on_process_selected)
remove_unused_btn.clicked.connect(remove_unused_looks)
# Open widgets
self.asset_outliner = asset_outliner
self.look_outliner = look_outliner
@ -123,15 +127,8 @@ class App(QtWidgets.QWidget):
def setup_connections(self):
"""Connect interactive widgets with actions"""
self.asset_outliner.selection_changed.connect(
self.on_asset_selection_changed)
self.asset_outliner.refreshed.connect(
lambda: self.echo("Loaded assets.."))
self.look_outliner.menu_apply_action.connect(self.on_process_selected)
self.remove_unused.clicked.connect(remove_unused_looks)
if self._connections_set_up:
return
# Maya renderlayer switch callback
callback = om.MEventMessage.addEventCallback(
@ -139,14 +136,23 @@ class App(QtWidgets.QWidget):
self._on_renderlayer_switch
)
self._callbacks.append(callback)
self._connections_set_up = True
def closeEvent(self, event):
def remove_connection(self):
# Delete callbacks
for callback in self._callbacks:
om.MMessage.removeCallback(callback)
return super(App, self).closeEvent(event)
self._callbacks = []
self._connections_set_up = False
def showEvent(self, event):
self.setup_connections()
super(App, self).showEvent(event)
def closeEvent(self, event):
self.remove_connection()
super(App, self).closeEvent(event)
def _on_renderlayer_switch(self, *args):
"""Callback that updates on Maya renderlayer switch"""

View file

@ -991,7 +991,7 @@ class Window(QtWidgets.QMainWindow):
workdir, filename = os.path.split(filepath)
asset_docs = self.assets_widget.get_selected_assets()
asset_doc = asset_docs[0]
task_name = self.tasks_widget.get_current_task_name()
task_name = self.tasks_widget.get_selected_task_name()
create_workfile_doc(asset_doc, task_name, filename, workdir, io)
def set_context(self, context):

View file

@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Package declaring Pype version."""
__version__ = "3.6.1"
__version__ = "3.6.2-nightly.1"

View file

@ -1,6 +1,6 @@
[tool.poetry]
name = "OpenPype"
version = "3.6.1" # OpenPype
version = "3.6.2-nightly.1" # OpenPype
description = "Open VFX and Animation pipeline with support."
authors = ["OpenPype Team <info@openpype.io>"]
license = "MIT License"