From 5208583d8fc9026930f186306ebafb3332ad1081 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Sat, 12 Jun 2021 12:29:41 +0200 Subject: [PATCH 01/39] reversed logic of drawing in drawTrigon --- .../widgets/color_widgets/color_triangle.py | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/openpype/widgets/color_widgets/color_triangle.py b/openpype/widgets/color_widgets/color_triangle.py index d4db175d84..ed7fefa7e8 100644 --- a/openpype/widgets/color_widgets/color_triangle.py +++ b/openpype/widgets/color_widgets/color_triangle.py @@ -724,27 +724,29 @@ class QtColorTriangle(QtWidgets.QWidget): lx = leftX[y] rx = rightX[y] + # if the xdist is 0, don't draw anything. + xdist = rx - lx + if xdist == 0.0: + continue + lxi = int(floor(lx)) rxi = int(floor(rx)) rc = rightColors[y] lc = leftColors[y] - # if the xdist is 0, don't draw anything. - xdist = rx - lx - if xdist != 0.0: - r = lc.r - g = lc.g - b = lc.b - rdelta = (rc.r - r) / xdist - gdelta = (rc.g - g) / xdist - bdelta = (rc.b - b) / xdist + r = lc.r + g = lc.g + b = lc.b + rdelta = (rc.r - r) / xdist + gdelta = (rc.g - g) / xdist + bdelta = (rc.b - b) / xdist - # Inner loop 2. Draws the line from left to right. - for x in range(lxi, rxi + 1): - buf.setPixel(x, y, QtGui.qRgb(int(r), int(g), int(b))) - r += rdelta - g += gdelta - b += bdelta + # Inner loop 2. Draws the line from left to right. + for x in range(lxi, rxi): + buf.setPixel(x, y, QtGui.qRgb(int(r), int(g), int(b))) + r += rdelta + g += gdelta + b += bdelta def _radius_at(self, pos, rect): mousexdist = pos.x() - float(rect.center().x()) From fbea4e4f9d0504d4d4af8a7a3e91fbfc58143f0c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Sat, 12 Jun 2021 12:29:56 +0200 Subject: [PATCH 02/39] draw 2 more pixels on each side of trigon --- openpype/widgets/color_widgets/color_triangle.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openpype/widgets/color_widgets/color_triangle.py b/openpype/widgets/color_widgets/color_triangle.py index ed7fefa7e8..a6ee0e864f 100644 --- a/openpype/widgets/color_widgets/color_triangle.py +++ b/openpype/widgets/color_widgets/color_triangle.py @@ -741,6 +741,10 @@ class QtColorTriangle(QtWidgets.QWidget): gdelta = (rc.g - g) / xdist bdelta = (rc.b - b) / xdist + # Draw 2 more pixels on left side for smoothing + for x in range(lxi - 2, lxi): + buf.setPixel(x, y, QtGui.qRgb(int(r), int(g), int(b))) + # Inner loop 2. Draws the line from left to right. for x in range(lxi, rxi): buf.setPixel(x, y, QtGui.qRgb(int(r), int(g), int(b))) @@ -748,6 +752,10 @@ class QtColorTriangle(QtWidgets.QWidget): g += gdelta b += bdelta + # Draw 2 more pixels on right side for smoothing + for x in range(rxi, rxi + 3): + buf.setPixel(x, y, QtGui.qRgb(int(r), int(g), int(b))) + def _radius_at(self, pos, rect): mousexdist = pos.x() - float(rect.center().x()) mouseydist = pos.y() - float(rect.center().y()) From c9b30f276850bf12189c01a7ffdb49a5fe957b29 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Sat, 12 Jun 2021 12:30:39 +0200 Subject: [PATCH 03/39] draw trigon to different image which is painter over background with clipping --- .../widgets/color_widgets/color_triangle.py | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/openpype/widgets/color_widgets/color_triangle.py b/openpype/widgets/color_widgets/color_triangle.py index a6ee0e864f..f4a86c4fa5 100644 --- a/openpype/widgets/color_widgets/color_triangle.py +++ b/openpype/widgets/color_widgets/color_triangle.py @@ -241,7 +241,11 @@ class QtColorTriangle(QtWidgets.QWidget): # Blit the static generated background with the hue gradient onto # the double buffer. - buf = QtGui.QImage(self.bg_image.copy()) + buf = QtGui.QImage( + self.bg_image.width(), + self.bg_image.height(), + QtGui.QImage.Format_RGB32 + ) # Draw the trigon # Find the color with only the hue, and max value and saturation @@ -254,9 +258,21 @@ class QtColorTriangle(QtWidgets.QWidget): ) # Slow step: convert the image to a pixmap - pix = QtGui.QPixmap.fromImage(buf) + pix = self.bg_image.copy() pix_painter = QtGui.QPainter(pix) - pix_painter.setRenderHint(QtGui.QPainter.Antialiasing) + + pix_painter.setRenderHint(QtGui.QPainter.HighQualityAntialiasing) + + trigon_path = QtGui.QPainterPath() + trigon_path.moveTo(self.point_a) + trigon_path.lineTo(self.point_b) + trigon_path.lineTo(self.point_c) + trigon_path.closeSubpath() + pix_painter.setClipPath(trigon_path) + + pix_painter.drawImage(0, 0, buf) + + pix_painter.setClipping(False) # Draw an outline of the triangle pix_painter.setPen(self._triangle_outline_pen) From 1e502773fdaf9c66a27f5a251bf46768da67b4d9 Mon Sep 17 00:00:00 2001 From: jezscha Date: Mon, 14 Jun 2021 10:31:57 +0000 Subject: [PATCH 04/39] Create draft PR for #1698 From ac219c1535675f54c98850a3d73380b86489ba5f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 14 Jun 2021 15:00:27 +0200 Subject: [PATCH 05/39] color entity can have defined if can use alpha --- openpype/settings/entities/color_entity.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/openpype/settings/entities/color_entity.py b/openpype/settings/entities/color_entity.py index 7a1b1d9848..dfaa75e761 100644 --- a/openpype/settings/entities/color_entity.py +++ b/openpype/settings/entities/color_entity.py @@ -12,6 +12,17 @@ class ColorEntity(InputEntity): def _item_initalization(self): self.valid_value_types = (list, ) self.value_on_not_set = [0, 0, 0, 255] + self.use_alpha = self.schema_data.get("use_alpha", True) + + def set_override_state(self, *args, **kwargs): + super(ColorEntity, self).set_override_state(*args, **kwargs) + value = self._current_value + if ( + not self.use_alpha + and isinstance(value, list) + and len(value) == 4 + ): + value[3] = 255 def convert_to_valid_type(self, value): """Conversion to valid type. @@ -51,4 +62,8 @@ class ColorEntity(InputEntity): ).format(value) raise BaseInvalidValueType(reason, self.path) new_value.append(item) + + # Make sure + if not self.use_alpha: + new_value[3] = 255 return new_value From 0c99c730c775582c5813fffa3507dde53d737d0e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 14 Jun 2021 15:01:11 +0200 Subject: [PATCH 06/39] color widget can show color dialog without alpha based on `use_alpha` attribute --- .../tools/settings/settings/color_widget.py | 8 ++- .../color_widgets/color_picker_widget.py | 55 ++++++++++++------- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/openpype/tools/settings/settings/color_widget.py b/openpype/tools/settings/settings/color_widget.py index fa0cd2c989..b38b46f3cb 100644 --- a/openpype/tools/settings/settings/color_widget.py +++ b/openpype/tools/settings/settings/color_widget.py @@ -25,7 +25,9 @@ class ColorWidget(InputWidget): self._dialog.open() return - dialog = ColorDialog(self.input_field.color(), self) + dialog = ColorDialog( + self.input_field.color(), self.entity.use_alpha, self + ) self._dialog = dialog dialog.open() @@ -120,12 +122,12 @@ class ColorViewer(QtWidgets.QWidget): class ColorDialog(QtWidgets.QDialog): - def __init__(self, color=None, parent=None): + def __init__(self, color=None, use_alpha=True, parent=None): super(ColorDialog, self).__init__(parent) self.setWindowTitle("Color picker dialog") - picker_widget = ColorPickerWidget(color, self) + picker_widget = ColorPickerWidget(color, use_alpha, self) footer_widget = QtWidgets.QWidget(self) diff --git a/openpype/widgets/color_widgets/color_picker_widget.py b/openpype/widgets/color_widgets/color_picker_widget.py index 81ec1f87aa..228d35a77c 100644 --- a/openpype/widgets/color_widgets/color_picker_widget.py +++ b/openpype/widgets/color_widgets/color_picker_widget.py @@ -17,19 +17,12 @@ from .color_inputs import ( class ColorPickerWidget(QtWidgets.QWidget): color_changed = QtCore.Signal(QtGui.QColor) - def __init__(self, color=None, parent=None): + def __init__(self, color=None, use_alpha=True, parent=None): super(ColorPickerWidget, self).__init__(parent) # Color triangle color_triangle = QtColorTriangle(self) - alpha_slider_proxy = QtWidgets.QWidget(self) - alpha_slider = AlphaSlider(QtCore.Qt.Horizontal, alpha_slider_proxy) - - alpha_slider_layout = QtWidgets.QHBoxLayout(alpha_slider_proxy) - alpha_slider_layout.setContentsMargins(5, 5, 5, 5) - alpha_slider_layout.addWidget(alpha_slider, 1) - # Eye picked widget pick_widget = PickScreenColorWidget() pick_widget.setMaximumHeight(50) @@ -47,8 +40,6 @@ class ColorPickerWidget(QtWidgets.QWidget): color_view = ColorViewer(self) color_view.setMaximumHeight(50) - alpha_inputs = AlphaInputs(self) - color_inputs_color = QtGui.QColor() col_inputs_by_label = [ ("HEX", HEXInputs(color_inputs_color, self)), @@ -58,6 +49,7 @@ class ColorPickerWidget(QtWidgets.QWidget): ] layout = QtWidgets.QGridLayout(self) + empty_col = 1 label_col = empty_col + 1 input_col = label_col + 1 @@ -65,6 +57,9 @@ class ColorPickerWidget(QtWidgets.QWidget): empty_widget.setFixedWidth(10) layout.addWidget(empty_widget, 0, empty_col) + layout.setColumnStretch(0, 1) + layout.setColumnStretch(input_col, 1) + row = 0 layout.addWidget(btn_pick_color, row, label_col) layout.addWidget(color_view, row, input_col) @@ -84,20 +79,41 @@ class ColorPickerWidget(QtWidgets.QWidget): layout.setRowStretch(row, 1) row += 1 - layout.addWidget(alpha_slider_proxy, row, 0) + alpha_label = None + alpha_slider_proxy = None + alpha_slider = None + alpha_inputs = None + if not use_alpha: + color.setAlpha(255) + else: + alpha_inputs = AlphaInputs(self) + alpha_label = QtWidgets.QLabel("Alpha", self) + alpha_slider_proxy = QtWidgets.QWidget(self) + alpha_slider = AlphaSlider( + QtCore.Qt.Horizontal, alpha_slider_proxy + ) + + alpha_slider_layout = QtWidgets.QHBoxLayout(alpha_slider_proxy) + alpha_slider_layout.setContentsMargins(5, 5, 5, 5) + alpha_slider_layout.addWidget(alpha_slider, 1) + + layout.addWidget(alpha_slider_proxy, row, 0) + + layout.addWidget(alpha_label, row, label_col) + layout.addWidget(alpha_inputs, row, input_col) + + row += 1 - layout.addWidget(QtWidgets.QLabel("Alpha", self), row, label_col) - layout.addWidget(alpha_inputs, row, input_col) - row += 1 layout.setRowStretch(row, 1) color_view.set_color(color_triangle.cur_color) color_triangle.color_changed.connect(self.triangle_color_changed) - alpha_slider.valueChanged.connect(self._on_alpha_slider_change) pick_widget.color_selected.connect(self.on_color_change) - alpha_inputs.alpha_changed.connect(self._on_alpha_inputs_changed) btn_pick_color.released.connect(self.pick_color) + if alpha_slider: + alpha_slider.valueChanged.connect(self._on_alpha_slider_change) + alpha_inputs.alpha_changed.connect(self._on_alpha_inputs_changed) self.color_input_fields = color_input_fields self.color_inputs_color = color_inputs_color @@ -131,7 +147,8 @@ class ColorPickerWidget(QtWidgets.QWidget): return self.color_view.color() def set_color(self, color): - self.alpha_inputs.set_alpha(color.alpha()) + if self.alpha_inputs: + self.alpha_inputs.set_alpha(color.alpha()) self.on_color_change(color) def pick_color(self): @@ -163,10 +180,10 @@ class ColorPickerWidget(QtWidgets.QWidget): def alpha_changed(self, value): self.color_view.set_alpha(value) - if self.alpha_slider.value() != value: + if self.alpha_slider and self.alpha_slider.value() != value: self.alpha_slider.setValue(value) - if self.alpha_inputs.alpha_value != value: + if self.alpha_inputs and self.alpha_inputs.alpha_value != value: self.alpha_inputs.set_alpha(value) def _on_alpha_inputs_changed(self, value): From f67b496bba879e909407ba2d14536fd6bf7aa035 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 14 Jun 2021 15:01:30 +0200 Subject: [PATCH 07/39] fix color view piece size --- openpype/widgets/color_widgets/color_view.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/widgets/color_widgets/color_view.py b/openpype/widgets/color_widgets/color_view.py index 8644281a1d..b5fce28894 100644 --- a/openpype/widgets/color_widgets/color_view.py +++ b/openpype/widgets/color_widgets/color_view.py @@ -5,6 +5,8 @@ def draw_checkerboard_tile(piece_size=None, color_1=None, color_2=None): if piece_size is None: piece_size = 7 + # Make sure piece size is not float + piece_size = int(piece_size) if color_1 is None: color_1 = QtGui.QColor(188, 188, 188) From c21165643a92e52f2545acb02902d6881b5368f8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 14 Jun 2021 15:02:55 +0200 Subject: [PATCH 08/39] added overscan_color to extract review settings --- .../settings/defaults/project_settings/global.json | 6 ++++++ .../projects_schema/schemas/schema_global_publish.json | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 4351f18a60..a86b3c712a 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -58,6 +58,12 @@ "overscan_crop": "", "width": 0, "height": 0, + "overscan_color": [ + 0, + 0, + 0, + 255 + ], "bg_color": [ 0, 0, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 0c89575d74..9f7a573df9 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -202,6 +202,16 @@ "minimum": 0, "maximum": 100000 }, + { + "type": "label", + "label": "Overscan color is used only when output aspect pixel ratio is not same as input ratio." + }, + { + "type": "color", + "label": "Overscan color", + "key": "overscan_color", + "use_alpha": false + }, { "type": "label", "label": "Background color is used only when input have transparency and Alpha is higher than 0." From a733640a7f8c34ac496d236888e2e223da7e0b6d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 14 Jun 2021 15:07:57 +0200 Subject: [PATCH 09/39] overscan color is used inside extract review if is set --- openpype/plugins/publish/extract_review.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index e1e24af3ea..47c5461517 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -1154,13 +1154,24 @@ class ExtractReview(pyblish.api.InstancePlugin): self.log.debug("height_scale: `{}`".format(height_scale)) self.log.debug("height_half_pad: `{}`".format(height_half_pad)) + # Overscal color + overscan_color_value = "black" + overscan_color = output_def.get("overscan_color") + if overscan_color: + bg_red, bg_green, bg_blue, _ = overscan_color + overscan_color_value = "#{0:0>2X}{1:0>2X}{2:0>2X}".format( + bg_red, bg_green, bg_blue + ) + self.log.debug("Overscan color: `{}`".format(overscan_color_value)) + filters.extend([ "scale={}x{}:flags=lanczos".format( width_scale, height_scale ), - "pad={}:{}:{}:{}:black".format( + "pad={}:{}:{}:{}:{}".format( output_width, output_height, - width_half_pad, height_half_pad + width_half_pad, height_half_pad, + overscan_color_value ), "setsar=1" ]) From cc06efc4156bdedd59b4382aec72a5b7dce8a2f2 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 14 Jun 2021 23:00:35 +0200 Subject: [PATCH 10/39] Nuke: settings prerender use limit by default --- openpype/settings/defaults/project_settings/nuke.json | 3 ++- .../schemas/projects_schema/schema_project_nuke.json | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 3736f67268..6ff732634e 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -13,7 +13,8 @@ "fpath_template": "{work}/renders/nuke/{subset}/{subset}.{frame}.{ext}" }, "CreateWritePrerender": { - "fpath_template": "{work}/prerenders/nuke/{subset}/{subset}.{frame}.{ext}" + "fpath_template": "{work}/prerenders/nuke/{subset}/{subset}.{frame}.{ext}", + "use_range_limit": true } }, "publish": { diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json b/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json index f709e84651..01a954f283 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_nuke.json @@ -77,6 +77,11 @@ "type": "text", "key": "fpath_template", "label": "Path template" + }, + { + "type": "boolean", + "key": "use_range_limit", + "label": "Use Frame range limit by default" } ] } From b78f990c3c53ec61d42302ac6e23caeb3e144c95 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 14 Jun 2021 23:01:41 +0200 Subject: [PATCH 11/39] Nuke: render node linked knobs move to lib --- openpype/hosts/nuke/api/lib.py | 40 ++++++++++++------- .../plugins/create/create_write_prerender.py | 20 +++------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index 7c274a03c7..d7f3fdc6ba 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -286,7 +286,8 @@ def add_button_write_to_read(node): node.addKnob(knob) -def create_write_node(name, data, input=None, prenodes=None, review=True): +def create_write_node(name, data, input=None, prenodes=None, + review=True, linked_knobs=None): ''' Creating write node which is group node Arguments: @@ -465,12 +466,16 @@ def create_write_node(name, data, input=None, prenodes=None, review=True): GN.addKnob(nuke.Text_Knob('', 'Rendering')) # Add linked knobs. - linked_knob_names = [ - "_grp-start_", - "use_limit", "first", "last", - "_grp-end_", - "Render" - ] + linked_knob_names = [] + + # add input linked knobs and create group only if any input + if linked_knobs: + linked_knob_names.append("_grp-start_") + linked_knob_names.extend(linked_knobs) + linked_knob_names.append("_grp-end_") + + linked_knob_names.append("Render") + for name in linked_knob_names: if "_grp-start_" in name: knob = nuke.Tab_Knob( @@ -481,13 +486,20 @@ def create_write_node(name, data, input=None, prenodes=None, review=True): "rnd_attr_end", "Rendering attributes", nuke.TABENDGROUP) GN.addKnob(knob) else: - link = nuke.Link_Knob("") - link.makeLink(write_node.name(), name) - link.setName(name) - if "Render" in name: - link.setLabel("Render Local") - link.setFlag(0x1000) - GN.addKnob(link) + if "___" in name: + # add devider + GN.addKnob(nuke.Text_Knob("")) + else: + # add linked knob by name + link = nuke.Link_Knob("") + link.makeLink(write_node.name(), name) + link.setName(name) + + # make render + if "Render" in name: + link.setLabel("Render Local") + link.setFlag(0x1000) + GN.addKnob(link) # adding write to read button add_button_write_to_read(GN) diff --git a/openpype/hosts/nuke/plugins/create/create_write_prerender.py b/openpype/hosts/nuke/plugins/create/create_write_prerender.py index 6e1a2ddd96..bb01236801 100644 --- a/openpype/hosts/nuke/plugins/create/create_write_prerender.py +++ b/openpype/hosts/nuke/plugins/create/create_write_prerender.py @@ -103,7 +103,8 @@ class CreateWritePrerender(plugin.PypeCreator): write_data, input=selected_node, prenodes=[], - review=False) + review=False, + linked_knobs=["channels", "___", "first", "last", "use_limit"]) # relinking to collected connections for i, input in enumerate(inputs): @@ -122,19 +123,10 @@ class CreateWritePrerender(plugin.PypeCreator): w_node = n write_node.end() - # add inner write node Tab - write_node.addKnob(nuke.Tab_Knob("WriteLinkedKnobs")) + if self.presets.get("use_range_limit"): + w_node["use_limit"].setValue(True) + w_node["first"].setValue(nuke.root()["first_frame"].value()) + w_node["last"].setValue(nuke.root()["last_frame"].value()) - # linking knobs to group property panel - linking_knobs = ["channels", "___", "first", "last", "use_limit"] - for k in linking_knobs: - if "___" in k: - write_node.addKnob(nuke.Text_Knob('')) - else: - lnk = nuke.Link_Knob(k) - lnk.makeLink(w_node.name(), k) - lnk.setName(k.replace('_', ' ').capitalize()) - lnk.clearFlag(nuke.STARTLINE) - write_node.addKnob(lnk) return write_node From be02d1582247db69e9b79a68998ac3d10664e4ac Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 15 Jun 2021 11:57:09 +0200 Subject: [PATCH 12/39] overscan color is also used in overscan crop --- openpype/plugins/publish/extract_review.py | 41 ++++++++++++++-------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index 47c5461517..42fb2a8f93 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -986,9 +986,21 @@ class ExtractReview(pyblish.api.InstancePlugin): output_width = output_def.get("width") or None output_height = output_def.get("height") or None + # Overscal color + overscan_color_value = "black" + overscan_color = output_def.get("overscan_color") + if overscan_color: + bg_red, bg_green, bg_blue, _ = overscan_color + overscan_color_value = "#{0:0>2X}{1:0>2X}{2:0>2X}".format( + bg_red, bg_green, bg_blue + ) + self.log.debug("Overscan color: `{}`".format(overscan_color_value)) + # Convert overscan value video filters overscan_crop = output_def.get("overscan_crop") - overscan = OverscanCrop(input_width, input_height, overscan_crop) + overscan = OverscanCrop( + input_width, input_height, overscan_crop, overscan_color_value + ) overscan_crop_filters = overscan.video_filters() # Add overscan filters to filters if are any and modify input # resolution by it's values @@ -1154,16 +1166,6 @@ class ExtractReview(pyblish.api.InstancePlugin): self.log.debug("height_scale: `{}`".format(height_scale)) self.log.debug("height_half_pad: `{}`".format(height_half_pad)) - # Overscal color - overscan_color_value = "black" - overscan_color = output_def.get("overscan_color") - if overscan_color: - bg_red, bg_green, bg_blue, _ = overscan_color - overscan_color_value = "#{0:0>2X}{1:0>2X}{2:0>2X}".format( - bg_red, bg_green, bg_blue - ) - self.log.debug("Overscan color: `{}`".format(overscan_color_value)) - filters.extend([ "scale={}x{}:flags=lanczos".format( width_scale, height_scale @@ -1718,12 +1720,15 @@ class OverscanCrop: item_regex = re.compile(r"([\+\-])?([0-9]+)(.+)?") relative_source_regex = re.compile(r"%([\+\-])") - def __init__(self, input_width, input_height, string_value): + def __init__( + self, input_width, input_height, string_value, overscal_color=None + ): # Make sure that is not None string_value = string_value or "" self.input_width = input_width self.input_height = input_height + self.overscal_color = overscal_color width, height = self._convert_string_to_values(string_value) self._width_value = width @@ -1778,16 +1783,22 @@ class OverscanCrop: elif width >= self.input_width and height >= self.input_height: output.append( - "pad={}:{}:(iw-ow)/2:(ih-oh)/2".format(width, height) + "pad={}:{}:(iw-ow)/2:(ih-oh)/2:{}".format( + width, height, self.overscal_color + ) ) elif width > self.input_width and height < self.input_height: output.append("crop=iw:{}".format(height)) - output.append("pad={}:ih:(iw-ow)/2:(ih-oh)/2".format(width)) + output.append("pad={}:ih:(iw-ow)/2:(ih-oh)/2:{}".format( + width, self.overscal_color + )) elif width < self.input_width and height > self.input_height: output.append("crop={}:ih".format(width)) - output.append("pad=iw:{}:(iw-ow)/2:(ih-oh)/2".format(height)) + output.append("pad=iw:{}:(iw-ow)/2:(ih-oh)/2:{}".format( + height, self.overscal_color + )) return output From 8b7326e9ec43e8a7cf7ca4a67bfa4bb1475dafb2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 15 Jun 2021 12:21:33 +0200 Subject: [PATCH 13/39] changed position of overscan color --- .../defaults/project_settings/global.json | 4 ++-- .../schemas/schema_global_publish.json | 20 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index a86b3c712a..b7fa5e32e8 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -56,14 +56,14 @@ ] }, "overscan_crop": "", - "width": 0, - "height": 0, "overscan_color": [ 0, 0, 0, 255 ], + "width": 0, + "height": 0, "bg_color": [ 0, 0, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index 9f7a573df9..8ca203e3bc 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -182,6 +182,16 @@ "key": "overscan_crop", "label": "Overscan crop" }, + { + "type": "label", + "label": "Overscan color is used when input aspect ratio is not same as output aspect ratio." + }, + { + "type": "color", + "label": "Overscan color", + "key": "overscan_color", + "use_alpha": false + }, { "type": "label", "label": "Width and Height must be both set to higher value than 0 else source resolution is used." @@ -202,16 +212,6 @@ "minimum": 0, "maximum": 100000 }, - { - "type": "label", - "label": "Overscan color is used only when output aspect pixel ratio is not same as input ratio." - }, - { - "type": "color", - "label": "Overscan color", - "key": "overscan_color", - "use_alpha": false - }, { "type": "label", "label": "Background color is used only when input have transparency and Alpha is higher than 0." From 2c6c381450a4e334a3ef935db5c0d693272d8814 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 15 Jun 2021 12:37:00 +0200 Subject: [PATCH 14/39] updated output defs settings image --- .../global_extract_review_output_defs.png | Bin 19871 -> 26078 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/website/docs/project_settings/assets/global_extract_review_output_defs.png b/website/docs/project_settings/assets/global_extract_review_output_defs.png index ce3c00ca40387344fbcad18194a0fa73c82801f2..f4c1661b110d93aeab337e2556fb13ae5692ea16 100644 GIT binary patch literal 26078 zcmdqJcU+TOw=Rl^5{wAT0w`TnP>`b1JE&Lz8@(E;5D+3A5|L(uSdb2Zg#t?Nod61< zgHi&7Dv%%{R0)KTYONz0bbqcmMDg3Gmb@;3AHWZ6j@mc1Sy&2@;4Rxd zz|R~Hub9GESPpz<{@aCd&$44-v4>r~sD0PhiZn`mE6|@zV8jo`>s1$Wi8rRiv3s*^ z@w|9pFMZHW{@_b<(1~M~EMRk?>eq?a%@tDd-{QiL?mv53L{#?j-cb9*`Vc5NLVfBe z#8r7?Xs@bTL($mMUPc#XX8mqT&RcP`-??Jx(RZec?D>X-%9+-joKLH_jC^QKjEbdm zyMfiQ#2pCL+WtKLpZyf$3O2Tct zJ{lyBDlRC-y4AM1Zcg)*axzES&@4QEWOmw{mnW(RtS3t5jo7wd=3(^_53%x|$uVPR zju})!)jVppP(-BD{7#4(YOtR1VJTH%{-(aUdcH0D&3qZ`f~X;!{T1>tEA!jws-?H) zoolNBdWTqNcn_3%ZjYUQHGdhzJhsQDwSRr;{QCU1!0o$c+%bH|TCUhkkU2Wlrbg6I zXE?qXU*di^tuqY0WSvW58w_l^hcBy+N}viWJJeCyxH`-i;WqG;_S7BovP9JdQ#qstCC86as@RD`Gu~3LFtnn9#(GiZ)B=0NF@E4ZTI)HwpujKl zob7t{jh|7kmeyCt>)eI5GN#c4qB-s5(4fzukRk%wdk>&aU_2q)>W zEoZNn=gJXlyH*DlHDoaerPmR%rj*epLVk%W(Uf+f;mL|3@cqLz0iB<>`KD4$V9Tm6r2OmXHD>v_%bqzJR za=HjwdG07Rcbq08KO(>UVx8_|yS=Hswh*0ET3n{2FdvayFA2$lIJmk_{W5UPOgZf8Jtu*v@qm{sPI6}(5)kexp^GWqzIvaHu@36vxD->U!L{i>+Av%zt^z9HmvIX zL+?Dw|I3JCk!tWaX+~kU)cjC2GOuRSZ8CK_fMv!-q@=22A+v*vK|6guv;Tt|rSVU{ zg$^!H`%Lt@7*(Fztia{Fq@HnSc^&oh$l%Ua`|3^{ek1cFc5zqV+&Ouj)R&?Viv3D; z;EMWVV7N~6tHQ0qUBJ*A>^c)qY177wLo!dW%#jnNiX*OLTQk*_MF{ov0P3YB=JYSh z$D#0qj$Yv%`9;{G2AM`ABV3tpBHpk_+_^fI{v+B)_9CN^7QNub} z4S~Pb*swZIORM}bfa|MLDM9a_3nW%+p7Vi2FLC;K4Wjq^$DsE!W5x|hoe4gR8cHvo zq`7r9H+yPCnBl5mS#&A)Z6PB5W$vCDl`h&cBj%Upfr25PkJdO=S6tjbdC9rg(NtmB zT5DsXz)`AdJ|pqi%6+*1!g}i{4uLh9t4%GHG<#f!z(CF8p#tapn78%nXW08B!I zl_{$hH!HT`WGwVN*k{ZoN@FXOGr;|1!_7L7RUNxw-QMq;wIPfT`cPNOabJp%7UkGe z+h%4E?NR^FMxOud^KbuP&8I&%Rb72LWPZ;GCk?~h5$}W=yLb`ZSC1IS;}%pNEFh-i zD0oRtS@&9MFr_tr>^u^s1ZAohSzx1PI6uk&I^?!c;n<|MIbDpO!H!*UXV4As*4?x* zHOfdkKB`(+;K7c|)ddNh=RjyONK||SLdA`_QI(XQKZlA)=N;VEZ{pka7S4|=EkEIO z?MAFe;J>HLwH?XA5@;t2Mp<|spFc8>u*onl(-O>H>ALN3qEth?_3CV8)|%kM>1Z0uWY zBWlXKWLn)N>MD-`iU`ZyuedLxSRU2r|iD+29_@>`hk_hFImMz6?x zfG{!5Y@PQAhZLIEfOOda@V{FJQUMn%Ge)bo@Ej_$h<`~NSfs}u zTS(Yw3Sd;rDgaME{?QY~ZIZRVz~*2d8$X0I$gsTy4sP-`8!ecYP6a{$;Qu3pG;Ql1 zVQVXka4}H{rH*yEd#g_kr1%y7V}`iu)!3zl{as`9E1L6HDY~d)&3577@v4rO)*wQkUN+^jCJsW@+8!q2voJxx zDYs_JXHM@+9mQw1s?q-8=+)uhODHR^sn5L*ZjCW|YSOQ=+78mm`5HC|Mz@SAdHy;+ zSdU@K>HWRuJeq{0yx{E={SfK9B#caiWLmZTS|{LxU6)&EsYYFK@lN@*OH3#4rnKa@I$bQ2?G=AabZKKXKaRLQnjrbMQ11`c z8SvESzt+g7#uyb&NOY^cnVYRkZBOk2qM8_tfHmrSXdFRnPj#fUrve&KUviu+s-Y=S z6FNr!i~{^S;Gw%6dQY17sT`%owho%rZ@Y2#AKM32h2&N`1(=Gg44Rx_#=DBgq0jq_ zQoTyMUKgTQH_;zOW$>8K;_i7erbUO(tGpigKD%!pT4SBfowlV5cHuD(?3`Q zk5Z>!jGtG8{2qRDhbUm@KIs*6@~R1NASs`}#!16-DtZy!AwZJ+C~b^U6>xvX4pwN z_mJpP%st-6x3eSqz3nX+>|8(ALOvX)EwMy5fhJME18lN z&`XjA7Pzza)`{>fXgo;iDD_yY?Rhsk)Am}cpUcr8W9r%bfzkS@Yv$H+Y@a3vNZlL@ zBQtHIey>r*ei{x!eNmrX%vBr_H6uxa?hE&*l8LbG4A16KNm3bbuF30~QZwb*>GM&h zc{Rs#D5O;%bmPMTDT^2+|2G|*R=M|>AB|=*CP&t@!|QX#NHU!7wd?N?a>Co*Oyvz) z!xx;XkH(n`y?njhncq|V;o)6|(@)+Qr;L96bjYm6<0tnZIv^G-yBnBJHx;oz%)_%G z*8wDz==ho21myAT6yan*N0C2shN(YiN;s)Xvjw{h?ShYU%08fgbZycfzKi}b75undhN1k!B@IPt+?VgzFFfoq!V@Mev;hT`$Yw-v3$Fc)#V`Xl@%kB#QqGxxMk$ zv5w~rXU-O{rE><)CBdNIC^3=7g=ll5TED8Y1tq43cnN5pnGkD0QO`76TH~HXp>?cA zt?c)(Rv`{==_JaQMo1KHaXg)*#}OqhOPTlBD|%!2z#pvr%Dls&Ff!TlC@T#PS7i#F zo-tFRA6mcsP+Je|#{5E-Qj&BTBz0*!P402~Kcm-7ll{A;loW>5uSyT@XD(q-%l5Z5 zMTGrjc0BmsW@i%j+w5$&2R~V3Bmw3Zfxg*lg+%Usw48M zYUxd`!+IpOGczwvj@ROgJn*W=-jzRQ)e^(U=2PjT3}gb z8I)Y<>77X#^h*TBWenrn9XsT)3#ANgp}crduofFIXc|#l!mACe-}xjl{bA=t5ZiH3 zFlpN@w*YR4^AA>B7}Ht3(gU#_dmdg-%f|nVFODy5Qm(aZNHSG|f0J^>&Lte1F{$&2 zOdPJW8;FvLKbq?Xf^Y^$Sj#WgFg_{2?*|0AA)zDEV`vIWGF6LbL*F}(dM9|Hy);Bb z^r1yFP_Yp@pO0pUG97LS;C`L1a0MTH)s-+q)2^&NAGi1OlD=`-D3Lg>t#)?Cnb!DR za-G$rx6q0mLI5mE>A)KxB^1aO(ll2jV{;P?QHp0PQH@cDFl}d z0EzCClQ&sMBJh2aH}O5!YfOvi3pKl1lVJN=<^lvt+3!+_iu-iK@P zn{8D;jvC>-5%OHv^P-#ile^qb-$bULe5mc6jd*_wa{5H5z0c{BIS#Y{A6XKdBrxLf zV=5-a`sR!lmvMY@8kToF8Y?88V@ zF-C3ayfLuLEG#5lV6PttvDRwMu*ZyeUj=pSNfKqX4}N(B{-~b_`P~1>l>9kP#mz2h zP@r@PKld44iZnL{1)IjbaE+K5N=A=aewMm;kaZV}78uZl@PvqZm0b?Wx~U}wjUTB> z8RV~RV;C)}F!*dTWJu{9Y<|5pY+6TazBKp1x2mt<^<$P=>$kquElvFisLk6KJKLa{ zwJ~$h$wDc*{yTeK(NBR=1~g4rT9A-u2r@}>4*-beBu)k{Pl94tasR&6c~o|@E8 zbqM@TWyS!!;~oxJvG$Yyzrv)#tH~q{2#;8J<73o+noG zR&8-7k~uJE1;q~zI`9}%ZNKg9nyx6?6fvaw>=lCyLz^UkQb}@sY|Q4A9W!jE1_A1< zYcJYUl=hJ!r>80K%*ybFCTnFD+cB(h8x3l#Fl%CkuCp3!YcAh){w$cGlEtqpXv{AT z;? zAIFZfm9-BHB|EInoSy^RoMy)H*(?LAy0fOjGn%=lfCYW23e$S|1uyB)30R%Hu;!x9 zS{R_mkbdei4XqFy%z-v5V>h0q^Q8v~;wsFlPPEqcsBEUNL@LDz- zUj$}3QRbRhJf0?Hop$6e7x3FpY=(Vgz8a6FmowZLA!-)q0p$Vd*i^SL{GDYU1HXfM z(=$3FX`OoXu5c|=;V_p|+iP;=-4^~hhnJb(eo<~dZoseH7k#)Yzk27UsdK9+h3VAs4Zf&_H>leNqjpNs*{Yk^&jBh-16eh;>} z@h1LiJMVxbn~;CQ)+|9LPCY#*k(;hO+ym=BB_E}$nh%6ZR#9#fz0i8myKsTKPppsq z+y`yfv9YM-_Kh&5Q6likpKQ)K6__G>&QEJ>!AjByZBY#VV*e}I+1kx;&3IJzf=i2s zynI)sw-q4do?k*ra0FA3p)q^ZW!N%&I4n^!w7i?Qa=D#&SJ77+buV4vyD-=X0`qrj z>hb&MT|US+Th@WzXAD{2Vk3w0NdJYxRSzt^83mb^t79`)a8iMtfs($1%wyF;pNuF&~iw2wVYs zH)h{AJhQ3Sm;~hwuYcnKBg}Ea5T35^#I5B$5MNpVW;x5xstwJ^!UAT^!Y8cBwz+66 ziUy1YIQxg7YoHQQx0zJq#V1ya$VNLKN=;RKQ$L(9n)}D5R}>#|3Z2|t5yq9jM*Krr!P-d50b+qJ0Ec1Scn zxqiul;%bSmyIYyq>Q$^+{*!zeZ z&dpou82c2BV`XGs#u^`Gg$17g?Xyi?!Zpw7*d~t~XRof`GBO@e7&vt>W&8X-N#)E8 zw_BE{Mncw))Nl+h897>@#;wSN&hbLpxNLVUn^sz~F#s5~sY+Q4I`067j)<&?&cxo+ zfodfwpSYbC+x%qWj+^&Hq_uK!7FHRib%BrACZh$jC0+PQVhtIHB)Xt1LjXEk`K{4R zw1ym&zI7nw;NXLB0Pkgx+M7#eoN-Iiw%4|`PiJV6t&RG|NE$fz$Dm*$h9O=5NfmDY zU9{jhU#MuBo8=W3VuY5a%?7j-ZjW0aeA4(hqIdhywi4efLs@{bs}3pIfT9cH*Vcw( zBjeW=X&R|K*GjjoV=2P+F<>69u}+}+t$m2o(EQfud&7(8&#a2eeL&2)bOaH(kWG$HIE-8^uzM* zMfcry3_d|p4J(W6zECY2K>$~rm559XBS_2<{v-!}1F=BGi$g*}T z4<$VJO=Na%#)6F&fP`p(9uSTIK0{>3^+oV4;7{{R~Q*fgY8FQ7?S$x_UHM^U*M6H;YZ*@9CtN30%pM9e3e9q*C4MS{HaZ zNE8U}PLdptLSAuKczNd)I2>ns>U!^?z^0r^{BSLPieQ;l$LvCtM6y-d0?(BFHAWfH z`@sP~ebhn#EIxKFTl=KEdi5mBzW?p00K6sD1&C6iJggr&Du1@Q01p1~vy5EF&q=53 zfnXvEKux@p!8zb-n>S9xApray1rTeCe9k-N;kQh59d}~bU!lYKHqaM4=*j6~A4NW~ z8~FOvv$7OUSVA-qJwh!$o5iQAw=$=``se>2rVceI@EKzi7%IHdMaK6!cHxti9^l*B zO66pY%5%tFjF5<*KnD2uYTDn04KME!^@QZ(27kxZ#vsZz7%{#HU;e?CkkFaczHDL-jw5H&T+N@Wvcm*MxU6D$^h}g6 zphb{>qeYX4Tu%TAvTa89-WQ)d&-NUCVkXzKK>|-U^H+0we$ufKQ7q%ff=k{_VL5~4 zyL9K3B-h_YJB#+bqhJ6_D)?Hm<{H=g{v|i)#PqR&wxlHvg*Pk`(U0$Ds~v+|*qjd6 zLL+$WbXqld_cdhlMd=LtR&vL64Y`}E(68v&xNi-5I0y@$#UWL&p+v$Db~E7IBLC&w z3SP5m-8w>UYh&LZ3=fbWks$foH$9w&K`P0Wh3~jcl<9mrsoqH;V;ny#{g3Kq1J-FG z^DlP6|ICXs*sWU1>4W__Z(D}8HCE#t*R=+lIay6?&YRp-ZFI1NBCj>_=Tb9w=9Zq_Zi4Ri0ab^g+< zt^t%34)+Wc+v>kP2PC?$TudZkCE`QV{HNH?`23-FtY>G)&#(V>$WcI#WUv0qa`ysX z-#GX$uLKst^7i82weD+*9q?`aiT^vNW^w>ha{)tT+pY;(0vXzW9G2^VgOO@*sdO5L z6)=s>n^2qk7k=O_o^qbninB5VA!J&@L#H&RZX9Iqnh7Ph`gUiBvG7V;^1BVbTHU)MAT!-GSG)9jRJrY{ z&UMiwiqEOAqWnY1cy{RQ55JX`;BS?7UhhN;y5PtJWn9^Glw%azIYs>GRXf+ZNX$*b zJI^#}G0d#6doo75d0#h5)i|v12_|>WV;R%3+$9IZ?9v@^!#RRKvo~CLKgj*(NK?B` zFjz=C@sq!%#EG>zK?(UAvuRmqO+`K4q8je0Cog#GODd=PM%_(=ZfA^Jg7L4`uH!h> z+_DB`d}_Re*cD?-BEc^dS}N({Z)7DIF=6$tjJB!o?k=kU{U?`aM_O4?*<My4gqXqL}TU6_Go&Hwb62g9kh7!y9cm9?_Uc{*Rc`3pyZ~F+IxtX&ws?aQY!p# zX&txFWQh&UziXIWlSDIVy}NvQlY%iP zc)VH}pckuYHRJFVD&b^ zTdX21EXfDA&vVCl{568vW%zIY0RVe|^L?xU`2W9^2!4aX{~h=CFI9(|&Y&7nUOJwx z7ZvYbx3YV60N@Ltw&v7VH=gx60DU@#?%-}-6=zVe6HrbCHlZrx0-MH$0jBe71WHy> z*zAINSx|EasjfAU(h`K{7q^mS(w_Y2)tVQ0-RY0gijmw;%d+`dHND490gu~!c6RAE zbO!AQ|C=uK9#L-Sc12Aq(aEL1r(U#Yn@sh?7?CsZ2kTdFFJ0!_dw6ssw3dH@$K|YR zrc!j2|9S}f@&w!Se~@-`M25Fv+vB{Wrl7#t1bS9Pw)^gazYWaU2F2)f&Y`yo$Ki+fx4Y%(C5}}YNJ#380I-!}TDp z;~D#$j{a?^?WD**wsEHbCTE0;?HFD@c|N_L6Jjx?pBv&p=`e+vHV zi;6^P!dtg`m!D&DQQ|Z?B&wHg0dxvzycDecK;A$_+nODdVUF&lKetYj0T8F}`n?u4x`#<53tY6Mpri%-eQ)PUpvQjP%p3WnvUz zv%NbE8V~9J^R%bHO7VJtZqWp+p@X5UfVHqZSj1aH|2lrPXzD!-8D;vxM_e}1CH1G$ znYoqdRSP+S10-PTu+aF1#y)})R&!9Fkd$cLDi__Q=|6G=n@%FmUGMrRDCs%!l@`$$ zbb(JXdcYV}?Lf^6O0Iw%Qm2bXm6Ml0;7n0#foi*000(t3OH{V3zJ*8XB#v(R#l+Gm z#uEyeQXDdNGdJ}OyAQ#kEG48Rx#k*|`(Ve&SYH@Y2*UYI!}JPy;e;=^ZP4Q)QKxWE zUfHOPtEx|auBLtka(3%ZpAd~F15l2ERTU=#2+6-4b7EaJY2p7QY>n@y8E*0t+($!Sl|Zliz`^= zpvso^HARUH#i;&4c0?!7e+J)EKe>7p)4oR*XRX;yLB5T&6?GDZxR1D6w`sJ`?VGyH zQ!(uQw(v6sBb+&ROu!fvjcCUU3+keU`Y~$W`q@#{kN$aG$pH%jRD$@#W(*1I#^q7N zS*EzK%*Fx~mATWx>s4$!$K5;?-=DE~5H#ZLs>UGbnA=Yt*+-2aXz@5nvXdISq}z%V zj$qRJ?1dp`=g*&{wzbt(MnEo;Z*`j6G)IY<@jjP&*iYIE!8E@{!KQqXmTA&QVj`yA zbq$TXEo~6W-mTsx$6>lYZt<%we4|A?3A%7p@ouSg`KXid>s5gjj7&0y8)NPhp!<8j z{6UWxF9fBojOd&!-*|N?5`2h*fhZ0s^X@1bN5G(v7s-RZw+TEqTFYqaviVSNahXx+ z=K>M^=C5)EyJarJ(Ajq7y_<~|##FH8QCwGbdG}IMw2-l^LxrFaOuxtgkuprVjZFVj z`mR#9Jl?|H)m=Nu)lqwRph-xTCg6fWt$mCuMq8>dp360^-t{_5B$Uu$`31>hQ$N>v z)lpwP4&I}7mL-zX$zI<#FB9axEDwy7A!Z!~g$<6LcLB2$09JF+6m;0zb}opmU0T1f z>1n|W0c@9f(oEZ-!b{Kj6$Qq}^Z2?^iz|Pg)4z(o;kNbtc&~IxqwH(xkr6lytclPp zO1*;_*t|Y*wft>QCj@NGlM_#M_q+=E0JlpNNg8cS#Q ztN2}id(Bw;X2k{oql|Ys$VT}?J6#hnQ!EiA(6|E1qT4MFEg_&CA0DIM zZ7Ot(_8aoBO#B7`&0X8>{Hy?)r3>K-R$!s{>=LZxj|&$EzkR^fn2$5Av1jkd>f zik9NQQS6;hu;aqj^-*uT#8ez!t9UD2=JOQ8*eu3fCW~()7{5@h)U-&>U}=`t?z~9e z1F#wGLq^<~emO$Pu;AkoLo8rQPeA}82P!BhL^l>bZ)nM*yD$p|P=^50u+3>ic*Z5la zPrHDbR8B`)*-0PV#S^La!r4;b2bDowzTyS0uF#hj)h)^OMRMD$&z;@g(6t#w9~cJf zxnNdBCDv7gy;XC$So=D@KVTd%J0?+F9n!E!8lqI3~#VDn16 z%T)JSz=d#7UEI+#Q}O7k<`j>&wf zM1a-yiJT2df}{)nf~iIk^)e@SkqGFZakYOz-6vbu0V-*+Evc1YrO=HE8g;F*d!ceU z{#H~_!=+dcpZkr_Aq7XxYZ5+hwlKf&u(LgA3-KmwQ|>ya;V5(2)DP5+xHZQb9**sAH;YYrGv*A zg(?~6qY7vA-}0!*`b`(E2>(tOyhN9-`;6S7N+;ug@YX@<3N}i;1QWRjg?8|+WwuW0 zR$2^WgG3FJOWb7AmBEVEm2MD%&O{dkzlIV#uUaz^-1@7XT6%^J{-Y~kUibkA#&s?Y zgHiwzfdw!AYB{BZUTU2m2_e3NXKiyL9_P8-14ZXQc!lme8a31h z5bMsb!)eRFgWjMUbNcF4;<&Np*-DEZa5>m+zG&&G+0Fq}8HLpotSG^>PvH+cl12^U zh3V8g4*J>GN11uTd^|P*X&ItW#=|P?+d4{8brc$m=Q>_lW}5o8I<)Yi_}V$6d#Yb{ zy1rhyz-QZ|ih3-7>?G!;b$)0VzwH-Kxj zD_?m2V4L7)tBvZ>u{|Av#YZS{r?2hgFieReVq>5tU`)qH5Albjc=yDx>L>+arc@51 zvK6~$B@k=p5$rva08{E80ua}QE&vpKPuq^9Uvy5()$$A5Pi=}8oM7?yGM#-3pBvTK z7Ml}lea?mHeT}dR=}Ixu$w1e=#}s(=cS>=7BA~pvvTl~c){6q`gQdEuwK(G~Cr8c0 zZ)uTuNP)!^RW z;b_m^xpHA|gY;Q}%N|m>n!Ol1=^-!$MyVLQ@-jp z29>z_jq-H+cC6f?5?r(~j_1gWWtbM{?c!yA})xJ<=x zc#Xd~w0bje4+fP8YZS(bBgfksTyYEHgJslq!E8{sPcp`eNbtZ25bvbt`5p+tSZ$DQ z*D_dslrIZsHd2tCpP#EKgt>SON%hBB!%^Az)w#gyQT>{VD=;JLspTv1yZ~BE3YQmZ zO^El81@zCtBC4r8*s8Y1YK=-=eXf2vC^8S6Z=Eq87(h@&3nKPclChJ+>^%>1_XmFu zTVw!S*<9l{ax!P<#ZCzKs;#3C3gyOZT8@1X_qzK77BG_4>hh}e-Oua_DQxwX!~-X6 zgA~>WKZ^F$X`iue9^@nkEjrySp=?!}TPCP%Jx4h}5QrkR_g_W7Z7r+b>yPv5TDL(4)pwp8 z5YH-pVT|q)RxKw9zQ{%vQkU~6u1P<)F!YCQiz}9&F}kYo zTGkp#5Az({8p|NV=_E?MF!u#{^;~2g~ zy+03OH69zeKtYGCO|}xYuWr1v1|>2EQdRFQv+6`QI`BN0{FI&s`;Brxp&3`Khuvba%u>iAL%-M zw7N$x9+s?NYFXcpHFXVzP;jMP#sJ4zTBUm;=@j^aY2Ohc;^5XN{Ow_xiMjhh`)I_4 z>}H+w7?=EH;JEG+(hUiHan`md4K(^(43R(Cr@mB>ycxMr-0WezFwQTgfE@9jmwUcU zmT&P}UO$xVGA;KA_xa_Kdmb+f{VsO9nEZYmFEL~%5uvsARfT4bA?s8{rSW^KH@cRGziYcMM@K>1 zdy!t3FalpKEG%=7Mg%g6Vc}#BNi+4%^@Dn1U53;?bw!vNL*SDd*9qA#XEu4ri!wo`>O*w)Aj_6AG32eRR>fR~=xb+BUyNFthVy=L%Uo;V-(Z5gNaL{%(&#C_RSolvpg&ZF8E(<& z$NPAX)4iiK$|Sp=gBCk#! zF)+JUnsBK}MR=O|)2{fJZ_U(h5c*|Et&J8u6nq&B?QNFXr~z28@(h zRM(G9LvyCq?j(dI)17kExSMp&(L(pQFvZoMH^MX%0Gb@oC38B-(->!DL1i%nGAe+M_J1H5{GUweS`IBnxR)&s z+LpPEK9H`MU|n5CA^-w)D$Fifj3{Wj-m7#rl**m!=oiiWLN#)@?x?`0qX%%f(bHzliu&a_)^=fQ&-p6st! zfCM2UnXMs+%9TYtx!v@$VE?OBDSrYLOb|;2Ful4kZC0=I<%;SP;Mx20q7MPqY!Ken z0Vq?tW9`NE2d}jE41-00{NTc7J9_Inte-3xwwgtn;ex60J&&f{Y>vTC{LB^Tm^;x?X@h4Z zfg_xswlzYem4q&Ut^O84wX--0uG{f5ZMy-noiLZkiS~pEQie*G8*TH{vf5einPu)R zD?ndnHEoTX^ww`34AW>!B9^qyJqi>!%*@o0A*`Ix8=yzF`98*-dv#{=OvoPBv!$eF zG!vXLXGY7Z>P^q(z|^JaNJ~)qn5Cwo6%eVC7wT^+X3M|CUeFWJjG=W#<mDjgln~r1;K>T z`*+(I%yZ@11<{u95g$f2;IH~N*LAW+^>qj_Cf}--CbazBX7ojBA(b`qmsNQ zPsR>ehtsKOMgVNNi8m1$G!Fqb5U?cy)5Vr5y#dYPsurL;@E`Ay|4S2Tr^@p`F>D~) z{tvNX0W$huR`=}F<}LF@8b!f#{PVH?5k0>H!+{!21*@p&DQl!($xNXeRbH7xDZ(#_ z%SHk)N1%JZD(Toc{M{mL{?Ud*2>|@9luhWD-$|m*gE0mPVI=!CqDYzMN7dp7`0Ta| zUQuGhmz5QX8O?P>0c*kC$l@`qeliBqf{{{Ss9+QZrrd3&S4|c%!^%!E-6!%rj3Nm& z4!4EgDr9>dz)l{EkH)-l*~hmJ@RdC}shmEQibCaDZ8A{~JO(_C_w^SzUDJ7dQU>Yo z-Fg5v>Q9r1{fBiw7B1dW*Z-$ixeij0Ya9H06tw|rAx}{^6Y^J)=&wm0wH#+w7%>~wMT2z1Ho)wNLM?E@F>p@f9XI1^pFD5C`74`9vG6I8URf9=@H0OD(%VpYx9d6n38YWOPcBCs( z2JSW!N3?cVDMcs8ejCTR+p5x(8NTcUWuiF@{tkkt9(W{0m)n?`9Jw@DcYodt8>*N> zH<^Q$lA5tPZgdXd8hj*^T`kX+;cn|TH`8hrCFYg zBQ%^aY%^I~Cz0)W$Hp|SbzhfI(O)vTmyEK>nT7XHMRis;E8oI>i4x^bM3CdwnqA=P z_bjsE=vO6c3r}X6J?8nw)a>S6yQ~sbR!{SNFFZiFx4u~bttG%K1fQmuQ++6D-|#LNkI5F^cjLm z970Lq@ns-V0FA2JiP$YQ^!KrcwG-m*7H*=GV_DPV59Qtkz$62vq=%$uB9HLv!ljc9 z>dV&X>+(~Z>^|UmZ`p{42s3`;Se#MUO^M-gTvX{DUiIAz)m?tAZMO?O8mmT>bgfk9 zJTQ36sieO6JH4>UveE99MJ?=|>A^<$9{6|>B>=O~?e&UcXWu1@EIlVuiI8&uUZRmxs&7D_hI znrm!&ZS8;{e@;6W(Z~-U-SgDbP3J3p%zFmDxw@zh-#w4B{&K}~A?fLx<@-~IyDZ)F zKEPfIIbKm-n5}V1I+T0!Cm(Aer5eRvn=(x(f`F-~r=`P^VFirYRrelB1vws%^qRtk zy-Kz&SUO-0_Vl8AI8j~wYr~@Hg)WjfcQb;!i`Q_Wd^}3U!E}5V@)Az3>?|pyvT{?q z`;J8R9lSM=Xc%o?52_lC6*5p_3<~VJ%fuxgM0?Km%-n3D&Kk;W?Qw5hh&&Vcxecl} zR?%J-w1SU2YgJQtA9CTSH6Y=wybiFGsG^(gR>BK!(n#o^v|1q zD$Aq|Dpksb`7DIjdaKcPbn|rLogZ>+_g8&1d80lqtQ}S^YmD3Hmv^$8G6ox!Y;XP< zHHykccUP^RcG@uETB$PR?l2gR=_((p%=M{#*S^V%KQZNpIo37aDVB7{Rv@!st5ME{ zoEs!%mN=pzhP{$p_*ui$9C;gykgD}QKH}I~QJNQa3dUy0EQLl#)Q<@Umri#otfNsY z86`z?qk=cuixkW0iLi}~_)%MlpOQo5!NM&hYQSoLY_~Wj>S&D|yM5*OQ~}P}vdmxz z<@2%(QM>2L&>io%UmCBp?}8Y56Hif zNWwns8YA1}gGFaNR`V7O`zuG!*RSDw^RX?ZGr~Sa$*SvNQwx#lg4QI=73Em_Aa)fV zin8~OA7${!KECQ6@lo;zFMFhY8no3S5ly~}j@ZPpd}pQ%Qf$MDB8!|KGs|Vy#_K)Z zGgdCg!oOTl`3gP)Fx8|SO@SZNNC zsS&ukB0vdLN2~`h>7~oQOQO z93XKx>^t>ENHP2S$N|q<%AA@(h;mFyz*OYHaW;v2{^qhMx4`Wv(05 z!tw_s9=jp0=$%)qF&V%Ev|N}?{x3Qr;fKxbSZ;c#?_x3J-_9hWVrVF{b#(P>hVtII z34c}=8`*8_{qNp_`7eSJI~C@Ci%tqGr7LF7oiB#O4pmZ50m$iNnLRFv$?InFws)`~ z^CC`JcK&(eu7wN2s_usXG~Y+fXOPf1h6oq-#!l8Cy@IydM*3Qb$!KR71hM)WT`X!i zpf~xu8?aq^uDYU=Y$OD*5cdK%TGC0^9Z0|hmalUc@6~Ptsj4g~wz^e%#Dhv8-P%12 z(9Qp;Tqzm%3%8hA-VqbXmg<;kdq;~r!6qGlr}ag8jTZ1=Hr_Dr0FWLDmT(W6kN*ty z0%qOsRI5AD@xArLMs5NnXFk<5PmoRg0$a?{0MH0TXk&>x{>ew6$ z_iQ*lBF%BTa^k|pR4LGtu{Le~a{*~L$%jU2qY<>J>|yIXt0AL{Kt=exZf6 zVp$)kNg1t|>am9{E$Ez@sT?=BL2bfY4H`}BiXa4myy;O04=d$4$mYg?Dw`R(3q^eq z*OVVIyQj%&bmh;3(H7RH*UK%3QXzh{O@AL580_bw#Xij%KTKI!k(v5>LER%Eb>NUT zQkbH_?R{9=SyO*0ozgY=CwF2G>xuv2J#NsPM}2T zsPU2QzxBG@rEK8Uy_f5xtmyx#%W^%%L9IE0*5}Rxe=Fqj1qEhP<Ud+_K^yitBvqtphTR$W9tI50B@tZx{&9ag(` z)4&Ai@YX+W7W`X#!ILC1_=ejAW1=%5v|8V-aUt_SCT{!IZpm~%pxPz7h1vHEeD&2$ z4Nd&rG{|U>-LE&~ou7|jUoMHxTmu7tbPa596XQvGLY^Cp(bOM;2Z)xV^Ghs$3~r8W zQajosv?{@~qcogfM@`qL7N8|M2WR&(<&quXmS_<7;q7^y8qKBGG;s=d@YNF$2h2SC z^?=N;rS2+55`4Jud+s%q6ZQ5!vNYfVL#-AT-F{TS@yDP%KBnzot#}Hs;-{Y4X8|h? zhEr`>?Inh-$%o)M@`L$X=Kan6Gi7>*SxLzaFnn;b8}L_|QgKXIq5xdG;EQS`6OXXY zI8w44^b5u(x+be4v=)G3)#I2q;~cKff#SmMV=kbQ$&BVjwoUEAGXl=G4|)o9h6jhr z*i_E;oU*7cU{vUepqbZQRdjy4=L=)pCR6z#*Z4fOPY=b6SA!8;GQ7t_WbHB5%7ghX z=Zqwd_4(6i=m#q3?_mbGJRjE~jV($apQ=jvT@AJstTy1I6rDt0AK^F?*QCvaMUu`x;!IMB3&xG5gs)aG;vPyyf_{NLbs;=Vu!{ z;vvY~(I){gzbu(hK&7B3gWb3fvX*z@HSL+#Tmfp-L^SUI%PUOVMI)B~HB$b+TX5h5 zV%c9;*x$VLPk|~gs5E;>O{r*Fsw~=PO!8%p$|60I>xe;|oYm;Hq(y%eKMRC;8=#L{ z!u^S3S3++JaA`fUYIr4FWzH|^e$7>7pQ$)ZMHE!MYv`XFgni+byz=<)uUTt+?NhI7 zG$KfIKLwlQ`|Mtt;MNlIuT^GX%4Ej1i<4^6c?o`{oR4jpMV}S!*;+Z0wcu9d1IsZ( zJ)6E&*LDxATomLemf}qF6K6Yqiy&79)jyTrzdJN;tu8!#bbJtB{fB4)?^yBw)7_cJ zCAF=6+_Vxi%TA?sow72^GMh|s!nE0JvK&z?D=kG*oDjis$R@SaGKbOzkCuvQisD#S zk~vULC?HxXD1@dY9M~XtWB0wCPVXP*^S*!G`_KMs?X~wB_FB(+e$VsWGPm18>g~9l z+6s^Cz&AdhV28qJVKkwzp5b_wm`7R~dz?%JrNFy=_VZR%6I1!Nj zljp)(&$b{Is<^A40~Tl;5JbizvG6jShanl>Pe~(&QNu-(Z@AY|PFzS*Y4m#Ut?e0u z7c`r|D7UyPowrso;4ba#R&V`N?A1rBZMF4%s}~ES|M6{dQF7JGN)Hr%RbN3jR@zNw zt_E(EJr5Y{$p=<^6W?fT#xn4!xzp5)Q}jM~6xoAqV=#*9!Q{N6_E}OZ3WI};+3Ymm zZ>&|gN@|RPgFGHO%svnIxof7NlgMrCPf+C-C)Jhxj;fZ|qGY6A0c^80x7W8jI)Z&M)|=2K7>82s!`u^ z3a(LE&+X)D(*3}*Ct7V*4wKaY$29UE_{Sjn`CZwLUvf^LIn)yCK2QbGdtMF=p!%I; zlw)=amRJ${q8CVY8taOk3R%#bxzfod;sZGDYjt%^lU7*DV1YF&nY--^Hw|!~(QWy> ze9SdZ2N8;B$Vx%(WtCTi_iE70}4hcU~Iu z6tg<^HXOdcwd%sAtDV%uPG|-^mlVub9iahlY2E%@A`&(tx?hMb*FWX&^#{8z^o&$X=*6LTn0*_bOypd`jI?y1ZbW^OJx-?^1Ww8 zKG~-=Zr(F)8eQ+>7RMh_VbR6|4z#|Y+ApFpPU_Gqs$I+jJ*d$~~&bbwwiQkr$2f{o>cPqcS5v;YxajO+@WgSDq*Fj&_9zTr}hU}}$6 zd{eo(B=k#h$&Jq(G%>9Y)<8MzPWxPB=7{k97Y9Q@d=$`o9jjW*2oy% zqWB6E=;CdL(g80u^Jd94Y+H72wg))L*_=+kXH7~vZ*`+;AIdMqz&+iMtVu5jDAh&p zZq#wr0v{FE89pO@n z>ig~PG2@{Y3;HgnQx8t$v_u;tROie}aqk>_ruL*yYR;)QKkw=NhyG;frD4uUl1b#Y z3e>|OYYe}&ITaSBhxy#mzP@oEFR8!C)BBtF^5=LubB3C_+u>v`^j+D0On;pO*K_Vs z@bnC3LGplWl->a#L&y1j!4#w0#x};PaKpye$LmGn>-9|Qfbp(t*2y36dSK&M!~EE5 zmfScYc1ys;;oWil_(v2<=%q1Ohs&@fBmu3;K1KxBw@Pl;V2W<+A1Ym%#Ay5*=?tCh;2zcy7 zq&!B3B9v^2^OzPdq2T)d==&~Ry~KEM`v8z-SJ)_Ij(nFew=cTH6o8Hn zhHevxIVzoygF*&&rmLr`Iw-f7r7p zbcRHX>{_F=e`E$Xbgvww}cfw=Bm%dZ{R8ZLj zMPRE^dVp+MxnR{giRQi^BTJx~nwVr#;8qAXInU-wv%&iyVXWi0P^msdb6IPQ(PmNq z{C!k!m4y6{Z&e=z>A2=*JA?#I)nf7YV26U}s=h5m8v?@?XGnH2GX=olrgL8L(N6Kv z(DSo>?U;G^U39nbo$h-6(b+E$)<4}iGhN#Lgx!!&$dI3p>ecV!< zxJk{C;BD`$9vY=@=mhi~8Ev-A{IX5$zK6xT_VqEY9kNKy)I+MdjuAs3XawCX48LT# zp}oU21`$R(ZXsKmyLE3vc$Hf0jOycc*jtakPhxN;PaLbC`$B(aR1FQr>K4sL92{Mt zXl@^8x4mQyxArt%4N|Q06m~NUNOElFba`lm3!*V-1O-`OtnC0~RpK=UM z<{rpIkKLw%i=x6(r~jlZad|pD*!2H*Zu^cxO2>p*qL62v7}U_ufOq+&2>=1ZKOFwt zQ5WoZ_ z@y6iX{;j}@F#UVafI`d^m?|fJeH0{lgFYX-{J)Ybz5_2@b}J51BPMp_irV}ZuzovM zFz?0tNpMcN(QH30%2qan--DhR?Y)3K8Peq> z0Dm1Y#0Kp>X9vV6pt8c5?n>GR34OT%g5MNrRuvNcwkD1Cvd%V%tAqZ@dam@Nq)YjjLr6D~A&sM6P zii>}txMBk&6Qjk-=JU^ws^ZL4 zF40R#E(5Nl`4Ngraq)Ix#aj|)-D3)%eXvK4-vH?pz1?bjZ2JQ)!8I-~y+?ZO3Lw;f zHn_Zyx0(Pt&7xkm-pN1dR1dhg=xGP!sgJUF_)^n>4o)lH=m;$l2YxvjNy}vvru0|l%ZkxsiZ3hIeHh&xPV^x}Ku8Cwm?3FKaNc4vSV%9zCz>!%pWhIiFBkI26 zUJ2?(3jW!SX_Y)8FL(Vgc;3EA3vF3`mco>RRC3QAP#RLma|)+SY|Gu(TRltNyx&TM zp9vqh@Cd8`$%?(c$(0TkQb;>ss~FXP$6Z^YG>0cm_K~wXFP;h~=aBID(s}~;5*LZz zr@%X1yDB2c9I62KAMi%Iy?=-GDK7{@L6N5ozS0KxtW-x>$!x_CB%y1m~zw5C8xG literal 19871 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 From 9aec3761de8b920aba0635abf3c777bd3c2dd9ef Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 15 Jun 2021 13:05:09 +0200 Subject: [PATCH 15/39] added basic infor about overscan color and background color --- .../docs/project_settings/settings_project_global.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/website/docs/project_settings/settings_project_global.md b/website/docs/project_settings/settings_project_global.md index 5d23dd75e6..5c46cd185a 100644 --- a/website/docs/project_settings/settings_project_global.md +++ b/website/docs/project_settings/settings_project_global.md @@ -112,6 +112,10 @@ Profile may generate multiple outputs from a single input. Each output must defi | "-10% -200px" | 1800px 800px | | "-10% -0px" | 1800px 1000px | +- **`Overscan color`** + - Color of empty area caused by different aspect ratio of input and output. + - By default is set to black color. + - **`Letter Box`** - **Enabled** - Enable letter boxes - **Ratio** - Ratio of letter boxes @@ -124,6 +128,14 @@ Profile may generate multiple outputs from a single input. Each output must defi ![global_extract_review_letter_box_settings](assets/global_extract_review_letter_box_settings.png) ![global_extract_review_letter_box](assets/global_extract_review_letter_box.png) +- **`Background color`** + - Background color can be used for inputs with possible transparency (e.g. png sequence). + - Input's without possible alpha channel are ignored all the time (e.g. mov). + - Background color slows down rendering process. + - set alpha to `0` to not use this option at all (in most of cases background stays black) + - other than `0` alpha will draw color as background + + ### IntegrateAssetNew Saves information for all published subsets into DB, published assets are available for other hosts, tools and tasks after. From d1f0003a927ebac997f3f898ee57c58836c0d320 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 15 Jun 2021 14:04:46 +0200 Subject: [PATCH 16/39] Nuke: fixing version frame range prerender exception --- .../nuke/plugins/publish/precollect_writes.py | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/precollect_writes.py b/openpype/hosts/nuke/plugins/publish/precollect_writes.py index 5eaac89e84..0b5fbc0479 100644 --- a/openpype/hosts/nuke/plugins/publish/precollect_writes.py +++ b/openpype/hosts/nuke/plugins/publish/precollect_writes.py @@ -1,5 +1,6 @@ import os import re +from pprint import pformat import nuke import pyblish.api import openpype.api as pype @@ -17,6 +18,7 @@ class CollectNukeWrites(pyblish.api.InstancePlugin): def process(self, instance): _families_test = [instance.data["family"]] + instance.data["families"] + self.log.debug("_families_test: {}".format(_families_test)) node = None for x in instance: @@ -133,22 +135,29 @@ class CollectNukeWrites(pyblish.api.InstancePlugin): "outputDir": output_dir, "ext": ext, "label": label, - "handleStart": handle_start, - "handleEnd": handle_end, - "frameStart": first_frame + handle_start, - "frameEnd": last_frame - handle_end, - "frameStartHandle": first_frame, - "frameEndHandle": last_frame, "outputType": output_type, "colorspace": colorspace, "deadlineChunkSize": deadlineChunkSize, "deadlinePriority": deadlinePriority }) - if "prerender" in _families_test: + if self.is_prerender(_families_test): instance.data.update({ - "family": "prerender", - "families": [] + "handleStart": 0, + "handleEnd": 0, + "frameStart": first_frame, + "frameEnd": last_frame, + "frameStartHandle": first_frame, + "frameEndHandle": last_frame, + }) + else: + instance.data.update({ + "handleStart": handle_start, + "handleEnd": handle_end, + "frameStart": first_frame + handle_start, + "frameEnd": last_frame - handle_end, + "frameStartHandle": first_frame, + "frameEndHandle": last_frame, }) # * Add audio to instance if exists. @@ -170,4 +179,7 @@ class CollectNukeWrites(pyblish.api.InstancePlugin): "filename": api.get_representation_path(repre_doc) }] - self.log.debug("instance.data: {}".format(instance.data)) + self.log.debug("instance.data: {}".format(pformat(instance.data))) + + def is_prerender(self, families): + return next((f for f in families if "prerender" in f), None) From b2cc66ba2282934b04dc8b8fd2369bc08b39dcb1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 15 Jun 2021 14:34:58 +0200 Subject: [PATCH 17/39] added smoothnes to alpha slider --- openpype/widgets/color_widgets/color_inputs.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py index eda8c618f1..ada8befd65 100644 --- a/openpype/widgets/color_widgets/color_inputs.py +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -80,7 +80,7 @@ class AlphaSlider(QtWidgets.QSlider): painter.fillRect(event.rect(), QtCore.Qt.transparent) - painter.setRenderHint(QtGui.QPainter.SmoothPixmapTransform) + painter.setRenderHint(QtGui.QPainter.HighQualityAntialiasing) rect = self.style().subControlRect( QtWidgets.QStyle.CC_Slider, opt, @@ -135,19 +135,8 @@ class AlphaSlider(QtWidgets.QSlider): painter.save() - gradient = QtGui.QRadialGradient() - radius = handle_rect.height() / 2 - center_x = handle_rect.width() / 2 + handle_rect.x() - center_y = handle_rect.height() - gradient.setCenter(center_x, center_y) - gradient.setCenterRadius(radius) - gradient.setFocalPoint(center_x, center_y) - - gradient.setColorAt(0.9, QtGui.QColor(127, 127, 127)) - gradient.setColorAt(1, QtCore.Qt.transparent) - painter.setPen(QtCore.Qt.NoPen) - painter.setBrush(gradient) + painter.setBrush(QtGui.QColor(127, 127, 127)) painter.drawEllipse(handle_rect) painter.restore() From bf6504eac53ff536a6b677f89dd98b55a38924eb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 15 Jun 2021 14:35:09 +0200 Subject: [PATCH 18/39] removed unused slide_style --- .../widgets/color_widgets/color_inputs.py | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/openpype/widgets/color_widgets/color_inputs.py b/openpype/widgets/color_widgets/color_inputs.py index ada8befd65..6f5d4baa02 100644 --- a/openpype/widgets/color_widgets/color_inputs.py +++ b/openpype/widgets/color_widgets/color_inputs.py @@ -4,35 +4,6 @@ from Qt import QtWidgets, QtCore, QtGui from .color_view import draw_checkerboard_tile -slide_style = """ -QSlider::groove:horizontal { - background: qlineargradient( - x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #000, stop: 1 #fff - ); - height: 8px; - border-radius: 4px; -} - -QSlider::handle:horizontal { - background: qlineargradient( - x1:0, y1:0, x2:1, y2:1, stop:0 #ddd, stop:1 #bbb - ); - border: 1px solid #777; - width: 8px; - margin-top: -1px; - margin-bottom: -1px; - border-radius: 4px; -} - -QSlider::handle:horizontal:hover { - background: qlineargradient( - x1:0, y1:0, x2:1, y2:1, stop:0 #eee, stop:1 #ddd - ); - border: 1px solid #444;ff - border-radius: 4px; -}""" - - class AlphaSlider(QtWidgets.QSlider): def __init__(self, *args, **kwargs): super(AlphaSlider, self).__init__(*args, **kwargs) From 98a1b9973ee6d8118c395c9dc4bbc96594883931 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 15 Jun 2021 15:12:21 +0200 Subject: [PATCH 19/39] Nuke: improving validator of rendered frames --- .../publish/validate_rendered_frames.py | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/validate_rendered_frames.py b/openpype/hosts/nuke/plugins/publish/validate_rendered_frames.py index 8b71aff1ac..0c88014649 100644 --- a/openpype/hosts/nuke/plugins/publish/validate_rendered_frames.py +++ b/openpype/hosts/nuke/plugins/publish/validate_rendered_frames.py @@ -61,7 +61,6 @@ class ValidateRenderedFrames(pyblish.api.InstancePlugin): hosts = ["nuke", "nukestudio"] actions = [RepairCollectionActionToLocal, RepairCollectionActionToFarm] - def process(self, instance): for repre in instance.data["representations"]: @@ -78,10 +77,10 @@ class ValidateRenderedFrames(pyblish.api.InstancePlugin): collection = collections[0] - frame_length = int( - instance.data["frameEndHandle"] - - instance.data["frameStartHandle"] + 1 - ) + fstartH = instance.data["frameStartHandle"] + fendH = instance.data["frameEndHandle"] + + frame_length = int(fendH - fstartH + 1) if frame_length != 1: if len(collections) != 1: @@ -95,7 +94,16 @@ class ValidateRenderedFrames(pyblish.api.InstancePlugin): raise ValidationException(msg) collected_frames_len = int(len(collection.indexes)) + coll_start = min(collection.indexes) + coll_end = max(collection.indexes) + self.log.info("frame_length: {}".format(frame_length)) + self.log.info("collected_frames_len: {}".format( + collected_frames_len)) + self.log.info("fstartH-fendH: {}-{}".format(fstartH, fendH)) + self.log.info( + "coll_start-coll_end: {}-{}".format(coll_start, coll_end)) + self.log.info( "len(collection.indexes): {}".format(collected_frames_len) ) @@ -103,8 +111,11 @@ class ValidateRenderedFrames(pyblish.api.InstancePlugin): if ("slate" in instance.data["families"]) \ and (frame_length != collected_frames_len): collected_frames_len -= 1 + fstartH += 1 - assert (collected_frames_len == frame_length), ( + assert ((collected_frames_len >= frame_length) + and (coll_start <= fstartH) + and (coll_end >= fendH)), ( "{} missing frames. Use repair to render all frames" ).format(__name__) From 91d75c89b0947a6e16df50726312d664a545d18c Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 15 Jun 2021 17:54:00 +0200 Subject: [PATCH 20/39] settings: fix imageio granularity --- .../projects_schema/schemas/schema_anatomy_imageio.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json index 3c589f9492..2b2eab8868 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_anatomy_imageio.json @@ -3,7 +3,6 @@ "key": "imageio", "label": "Color Management and Output Formats", "is_file": true, - "is_group": true, "children": [ { "key": "hiero", @@ -15,6 +14,7 @@ "type": "dict", "label": "Workfile", "collapsible": false, + "is_group": true, "children": [ { "type": "form", @@ -89,6 +89,7 @@ "type": "dict", "label": "Colorspace on Inputs by regex detection", "collapsible": true, + "is_group": true, "children": [ { "type": "list", @@ -123,6 +124,7 @@ "type": "dict", "label": "Viewer", "collapsible": false, + "is_group": true, "children": [ { "type": "text", @@ -136,6 +138,7 @@ "type": "dict", "label": "Workfile", "collapsible": false, + "is_group": true, "children": [ { "type": "form", @@ -233,6 +236,7 @@ "type": "dict", "label": "Nodes", "collapsible": true, + "is_group": true, "children": [ { "key": "requiredNodes", @@ -335,6 +339,7 @@ "type": "dict", "label": "Colorspace on Inputs by regex detection", "collapsible": true, + "is_group": true, "children": [ { "type": "list", From 69dc652db35410e0d85f4ec351bd9e9cff213116 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 15 Jun 2021 17:54:43 +0200 Subject: [PATCH 21/39] nuke: default `create_directories` nuke write node https://github.com/pypeclub/client/issues/66 --- openpype/settings/defaults/project_anatomy/imageio.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openpype/settings/defaults/project_anatomy/imageio.json b/openpype/settings/defaults/project_anatomy/imageio.json index ff16c22663..fcebc876f5 100644 --- a/openpype/settings/defaults/project_anatomy/imageio.json +++ b/openpype/settings/defaults/project_anatomy/imageio.json @@ -78,6 +78,10 @@ { "name": "colorspace", "value": "linear" + }, + { + "name": "create_directories", + "value": "True" } ] }, @@ -114,6 +118,10 @@ { "name": "colorspace", "value": "linear" + }, + { + "name": "create_directories", + "value": "True" } ] } From 53112e04d67cd85cc87eb1265871daf67a6165e6 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 15 Jun 2021 19:19:53 +0200 Subject: [PATCH 22/39] fix condition --- openpype/hosts/maya/plugins/publish/extract_playblast.py | 2 +- openpype/hosts/maya/plugins/publish/extract_thumbnail.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_playblast.py b/openpype/hosts/maya/plugins/publish/extract_playblast.py index fa1ce7f9a9..57e3f478f1 100644 --- a/openpype/hosts/maya/plugins/publish/extract_playblast.py +++ b/openpype/hosts/maya/plugins/publish/extract_playblast.py @@ -72,7 +72,7 @@ class ExtractPlayblast(openpype.api.Extractor): # Isolate view is requested by having objects in the set besides a # camera. - if preset.pop("isolate_view", False) or instance.data.get("isolate"): + if preset.pop("isolate_view", False) and instance.data.get("isolate"): preset["isolate"] = instance.data["setMembers"] # Show/Hide image planes on request. diff --git a/openpype/hosts/maya/plugins/publish/extract_thumbnail.py b/openpype/hosts/maya/plugins/publish/extract_thumbnail.py index 5a91888781..aa8adc3986 100644 --- a/openpype/hosts/maya/plugins/publish/extract_thumbnail.py +++ b/openpype/hosts/maya/plugins/publish/extract_thumbnail.py @@ -75,7 +75,7 @@ class ExtractThumbnail(openpype.api.Extractor): # Isolate view is requested by having objects in the set besides a # camera. - if preset.pop("isolate_view", False) or instance.data.get("isolate"): + if preset.pop("isolate_view", False) and instance.data.get("isolate"): preset["isolate"] = instance.data["setMembers"] with maintained_time(): From bca04289ef1771f96679ab3da94fb957e9b0fdff Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 16 Jun 2021 12:16:33 +0200 Subject: [PATCH 23/39] set default subset template for review family in tvpaint --- .../settings/defaults/project_settings/global.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index b7fa5e32e8..c3c43c3b3b 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -232,6 +232,16 @@ ], "tasks": [], "template": "{family}{Task}_{Render_layer}_{Render_pass}" + }, + { + "families": [ + "review" + ], + "hosts": [ + "tvpaint" + ], + "tasks": [], + "template": "{family}{Task}" } ] }, From 18b8666b8166a89f570bbfd5d3c43a07e7327378 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 16 Jun 2021 12:20:57 +0200 Subject: [PATCH 24/39] added workfile to families --- openpype/settings/defaults/project_settings/global.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index c3c43c3b3b..037fa63a29 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -235,7 +235,8 @@ }, { "families": [ - "review" + "review", + "workfile" ], "hosts": [ "tvpaint" From 00998f310d650dfa54bcfcfdd07e2397fdda8778 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 16 Jun 2021 14:33:58 +0200 Subject: [PATCH 25/39] initial commit of subset name template docstrings --- .../settings_project_global.md | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/website/docs/project_settings/settings_project_global.md b/website/docs/project_settings/settings_project_global.md index 5c46cd185a..4bda13f91b 100644 --- a/website/docs/project_settings/settings_project_global.md +++ b/website/docs/project_settings/settings_project_global.md @@ -172,6 +172,38 @@ Applicable context filters: ## Tools Settings for OpenPype tools. +## Creator +Settings related to [Creator tool](artist_tools.md#details). + +### Subset name profiles +![global_tools_creator_subset_template](assets/global_tools_creator_subset_template.png) +Subset name helps to identify published content. More specific name helps with organization and avoid mixing of content. Subset name is defined using one of templates defined in Subset name profiles settings. The template is filled with information from context in which creation was triggered. + +Templates in settings are filtered by creator's family, host and task name. Template without filters is used as default template. It is recommend to set default template. If default template is not available `"{family}{Task}"` is used. + +**Formatting keys** + +All templates can contain text and formatting keys **family**, **task** and **variant** e.g. `"MyStudio_{family}_{task}"` (example - not recommended in production). + +|Key|Description| +|---|---| +|family|Creators family| +|task|Task under which is creation triggered| +|variant|User input in creator tool| + +**Formatting keys have 3 variants with different letter capitalization.** + +|Task|Key variant|Description|Result| +|---|---|---|---| +|`bgAnim`|`{task}`|Keep original value as is.|`bgAnim`| +|`bgAnim`|`{Task}`|Capitalize first letter of value.|`BgAnim`| +|`bgAnim`|`{TASK}`|Each letter which be capitalized.|`BGANIM`| + +Template may look like `"{family}{Task}{Variant}"`. + +Some creators may have other keys as their context may require more information or more specific values. Make sure you've read documentation of host you're using. + + ## Workfiles All settings related to Workfile tool. From d0cfbb03bdf22974d1665e4ef29f7d7b56d211f7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 16 Jun 2021 14:34:08 +0200 Subject: [PATCH 26/39] added screenshot --- .../global_tools_creator_subset_template.png | Bin 0 -> 17550 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 website/docs/project_settings/assets/global_tools_creator_subset_template.png diff --git a/website/docs/project_settings/assets/global_tools_creator_subset_template.png b/website/docs/project_settings/assets/global_tools_creator_subset_template.png new file mode 100644 index 0000000000000000000000000000000000000000..c4e863c4e0f28982c91e0d4768d113af200e4440 GIT binary patch literal 17550 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 Date: Wed, 16 Jun 2021 15:22:47 +0200 Subject: [PATCH 27/39] added admin tvpaint host documentation with families --- website/docs/admin_hosts_tvpaint.md | 41 +++++++++++++++++++++++++++++ website/sidebars.js | 3 ++- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 website/docs/admin_hosts_tvpaint.md diff --git a/website/docs/admin_hosts_tvpaint.md b/website/docs/admin_hosts_tvpaint.md new file mode 100644 index 0000000000..4db8f89166 --- /dev/null +++ b/website/docs/admin_hosts_tvpaint.md @@ -0,0 +1,41 @@ +--- +id: admin_hosts_tvpaint +title: TVPaint +sidebar_label: TVPaint +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +## Families +Families that can be published form TVPaint using OpenPype integration. + +### renderLayer +Render layer is represented by TVPaint group and all layers under the group. Output of `renderLayer` family are all visible layers rendered together into png sequence. + +Render layer has additional keys for subset name template. It is possible to use **render_layer** and **render_pass**. + +- Key **render_layer** is alias for variant (user's input). +- For key **render_pass** is used predefined value `"Beauty"` (ATM value can't be changed). + +### renderPass +Render pass is represented by one or more TVPaint layers. Is dependent on created `renderLayer`. All layers must be in same group of `renderLayer`. + +Render pass has additional keys for subset name template. It is possible to use **render_layer** and **render_pass**. +- Key **render_layer** is filled with value of **render_pass** from `renderLayer` group. +- Key **render_pass** is alias for variant (user's input). + +:::note Subset name template +It is recommended to use same subset name template for both **renderLayer** and **renderPass** families. +- Example template: `"{family}{Task}_{Render_layer}_{Render_pass}"` +::: + +### review +Review of whole scene. Exports all visible layers into sequence which is then processed in ExtractReview plugin. It is possible to deactivate publishing of review after collection. + +### workfile +Publish workfile and create it's backup outside of workfiles directory. It is possible to deactivate publishing of workfile after collection. + +:::note Dynamic families +Families **review** and **workfile** are not manually created but are automatically generated during publishing. That's why it is recommended to not use **variant** key in their subset name template. Recommented subset name template is `"{family}{Task}"`. +::: diff --git a/website/sidebars.js b/website/sidebars.js index 59071ec34f..d38973e40f 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -90,7 +90,8 @@ module.exports = { "admin_hosts_maya", "admin_hosts_resolve", "admin_hosts_harmony", - "admin_hosts_aftereffects" + "admin_hosts_aftereffects", + "admin_hosts_tvpaint" ], }, { From 56b858defa287de328d6ba54508845ed30daa7f7 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 16 Jun 2021 15:34:36 +0200 Subject: [PATCH 28/39] removed most of not important stuff from admin section --- website/docs/admin_hosts_tvpaint.md | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/website/docs/admin_hosts_tvpaint.md b/website/docs/admin_hosts_tvpaint.md index 4db8f89166..6c9c5ff881 100644 --- a/website/docs/admin_hosts_tvpaint.md +++ b/website/docs/admin_hosts_tvpaint.md @@ -7,35 +7,24 @@ sidebar_label: TVPaint import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -## Families -Families that can be published form TVPaint using OpenPype integration. - -### renderLayer -Render layer is represented by TVPaint group and all layers under the group. Output of `renderLayer` family are all visible layers rendered together into png sequence. +## Subset name templates +Definition of possibile subset name templates in TVPaint integration. +### [Render Layer](artist_hosts_tvpaint#render-layer) Render layer has additional keys for subset name template. It is possible to use **render_layer** and **render_pass**. - Key **render_layer** is alias for variant (user's input). - For key **render_pass** is used predefined value `"Beauty"` (ATM value can't be changed). -### renderPass -Render pass is represented by one or more TVPaint layers. Is dependent on created `renderLayer`. All layers must be in same group of `renderLayer`. - +### [Render pass](artist_hosts_tvpaint#render-pass) Render pass has additional keys for subset name template. It is possible to use **render_layer** and **render_pass**. - Key **render_layer** is filled with value of **render_pass** from `renderLayer` group. - Key **render_pass** is alias for variant (user's input). -:::note Subset name template +:::important Render Layer/Pass templates It is recommended to use same subset name template for both **renderLayer** and **renderPass** families. - Example template: `"{family}{Task}_{Render_layer}_{Render_pass}"` ::: -### review -Review of whole scene. Exports all visible layers into sequence which is then processed in ExtractReview plugin. It is possible to deactivate publishing of review after collection. - -### workfile -Publish workfile and create it's backup outside of workfiles directory. It is possible to deactivate publishing of workfile after collection. - -:::note Dynamic families -Families **review** and **workfile** are not manually created but are automatically generated during publishing. That's why it is recommended to not use **variant** key in their subset name template. Recommented subset name template is `"{family}{Task}"`. -::: +### [Review](artist_hosts_tvpaint#review) and Workfile +Families **review** and **workfile** are not manually created but are automatically generated during publishing. That's why it is recommended to not use **variant** key in their subset name template. From 774595fba8fada980453e0aed3e650ccb99ef043 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 16 Jun 2021 15:43:50 +0200 Subject: [PATCH 29/39] updated review and workfile families in tvpaint docs --- website/docs/artist_hosts_tvpaint.md | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/website/docs/artist_hosts_tvpaint.md b/website/docs/artist_hosts_tvpaint.md index 19cb615158..2e831e64d8 100644 --- a/website/docs/artist_hosts_tvpaint.md +++ b/website/docs/artist_hosts_tvpaint.md @@ -45,7 +45,7 @@ In TVPaint you can find the Tools in OpenPype menu extension. The OpenPype Tools ## Create -In TVPaint you can create and publish **[Reviews](#review)**, **[Render Passes](#render-pass)**, and **[Render Layers](#render-layer)**. +In TVPaint you can create and publish **[Reviews](#review)**, **[Workfile](#workfile)**, **[Render Passes](#render-pass)** and **[Render Layers](#render-layer)**. You have the possibility to organize your layers by using `Color group`. @@ -67,26 +67,13 @@ OpenPype specifically never tries to guess what you want to publish from the sce When you want to publish `review` or `render layer` or `render pass`, open the `Creator` through the Tools menu `Create` button. -### Review +### Review +`Review` renders the whole file as is and sends the resulting QuickTime to Ftrack. +- Is automatically created during publishing. -
-
- -`Review` renders the whole file as is and sends the resulting QuickTime to Ftrack. - -To create reviewable quicktime of your animation: - -- select `Review` in the `Creator` -- press `Create` -- When you run [publish](#publish), file will be rendered and converted to quicktime.` - -
-
- -![createreview](assets/tvp_create_review.png) - -
-
+### Workfile +`Workfile` stores the source workfile as is during publishing (e.g. for backup). +- Is automatically created during publishing. ### Render Layer From 776e784df9c111cec4914e74e315fa62d615d790 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 16 Jun 2021 15:44:07 +0200 Subject: [PATCH 30/39] added link to workfile family --- website/docs/admin_hosts_tvpaint.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/admin_hosts_tvpaint.md b/website/docs/admin_hosts_tvpaint.md index 6c9c5ff881..a99cd19010 100644 --- a/website/docs/admin_hosts_tvpaint.md +++ b/website/docs/admin_hosts_tvpaint.md @@ -26,5 +26,5 @@ It is recommended to use same subset name template for both **renderLayer** and - Example template: `"{family}{Task}_{Render_layer}_{Render_pass}"` ::: -### [Review](artist_hosts_tvpaint#review) and Workfile +### [Review](artist_hosts_tvpaint#review) and [Workfile](artist_hosts_tvpaint#workfile) Families **review** and **workfile** are not manually created but are automatically generated during publishing. That's why it is recommended to not use **variant** key in their subset name template. From a9d51ce003b99b6d8c51e3ef7394d257c71ded40 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 16 Jun 2021 15:44:15 +0200 Subject: [PATCH 31/39] removed unused image --- website/docs/assets/tvp_create_review.png | Bin 30635 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 website/docs/assets/tvp_create_review.png diff --git a/website/docs/assets/tvp_create_review.png b/website/docs/assets/tvp_create_review.png deleted file mode 100644 index d6e9f6342850dda4afbc534b4678dacd8366b264..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30635 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 Date: Wed, 16 Jun 2021 15:51:20 +0200 Subject: [PATCH 32/39] rephrasing subset templates --- website/docs/project_settings/settings_project_global.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/docs/project_settings/settings_project_global.md b/website/docs/project_settings/settings_project_global.md index 4bda13f91b..e6336c36e2 100644 --- a/website/docs/project_settings/settings_project_global.md +++ b/website/docs/project_settings/settings_project_global.md @@ -177,9 +177,10 @@ Settings related to [Creator tool](artist_tools.md#details). ### Subset name profiles ![global_tools_creator_subset_template](assets/global_tools_creator_subset_template.png) -Subset name helps to identify published content. More specific name helps with organization and avoid mixing of content. Subset name is defined using one of templates defined in Subset name profiles settings. The template is filled with information from context in which creation was triggered. -Templates in settings are filtered by creator's family, host and task name. Template without filters is used as default template. It is recommend to set default template. If default template is not available `"{family}{Task}"` is used. +Subset name helps to identify published content. More specific name helps with organization and avoid mixing of published content. Subset name is defined using one of templates defined in **Subset name profiles settings**. The template is filled with context information at the time of creation. + +Usage of template is defined by profile filtering using creator's family, host and task name. Profile without filters is used as default template and it is recommend to set default template. If default template is not available `"{family}{Task}"` is used. **Formatting keys** From 855d5a9ae410fcd67405e90c51fb16b1d2120e80 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 17 Jun 2021 13:46:59 +0200 Subject: [PATCH 33/39] use layer name instead of group name for default render layer variant --- .../plugins/create/create_render_layer.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/tvpaint/plugins/create/create_render_layer.py b/openpype/hosts/tvpaint/plugins/create/create_render_layer.py index eeb7d32d50..af6c0f0eee 100644 --- a/openpype/hosts/tvpaint/plugins/create/create_render_layer.py +++ b/openpype/hosts/tvpaint/plugins/create/create_render_layer.py @@ -58,18 +58,14 @@ class CreateRenderlayer(plugin.Creator): # Get currently selected layers layers_data = lib.layers_data() - group_ids = set() - for layer in layers_data: - if layer["selected"]: - group_ids.add(layer["group_id"]) - + selected_layers = [ + layer + for layer in layers_data + if layer["selected"] + ] # Return layer name if only one is selected - if len(group_ids) == 1: - group_id = list(group_ids)[0] - groups_data = lib.groups_data() - for group in groups_data: - if group["group_id"] == group_id: - return group["name"] + if len(selected_layers) == 1: + return selected_layers[0]["name"] # Use defaults if cls.defaults: From 4ecc8669717faf0e4113723ea04f645dabe32276 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 17 Jun 2021 15:00:13 +0200 Subject: [PATCH 34/39] ProjectModel has resetless logic of refresh --- openpype/tools/launcher/models.py | 52 +++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/openpype/tools/launcher/models.py b/openpype/tools/launcher/models.py index 25b6dcdbf0..846a07e081 100644 --- a/openpype/tools/launcher/models.py +++ b/openpype/tools/launcher/models.py @@ -325,19 +325,59 @@ class ProjectModel(QtGui.QStandardItemModel): self.hide_invisible = False self.project_icon = qtawesome.icon("fa.map", color="white") + self._project_names = set() def refresh(self): - self.clear() - self.beginResetModel() - + project_names = set() for project_doc in self.get_projects(): - item = QtGui.QStandardItem(self.project_icon, project_doc["name"]) - self.appendRow(item) + project_names.add(project_doc["name"]) - self.endResetModel() + origin_project_names = set(self._project_names) + self._project_names = project_names + + project_names_to_remove = origin_project_names - project_names + if project_names_to_remove: + row_counts = {} + continuous = None + for row in range(self.rowCount()): + index = self.index(row, 0) + index_name = index.data(QtCore.Qt.DisplayRole) + if index_name in project_names_to_remove: + if continuous is None: + continuous = row + row_counts[continuous] = 0 + row_counts[continuous] += 1 + else: + continuous = None + + for row in reversed(sorted(row_counts.keys())): + count = row_counts[row] + self.removeRows(row, count) + + continuous = None + row_counts = {} + for idx, project_name in enumerate(sorted(project_names)): + if project_name in origin_project_names: + continuous = None + continue + + if continuous is None: + continuous = idx + row_counts[continuous] = [] + + row_counts[continuous].append(project_name) + + for row in reversed(sorted(row_counts.keys())): + items = [] + for project_name in row_counts[row]: + item = QtGui.QStandardItem(self.project_icon, project_name) + items.append(item) + + self.invisibleRootItem().insertRows(row, items) def get_projects(self): project_docs = [] + for project_doc in sorted( self.dbcon.projects(), key=lambda x: x["name"] ): From 912c6b3b575e4e66e7de35168890917cc2b810a0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 17 Jun 2021 15:08:45 +0200 Subject: [PATCH 35/39] added refresh timer which will update projects each 10 seconds --- openpype/tools/launcher/widgets.py | 22 ++++++++++++++++++++++ openpype/tools/launcher/window.py | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/openpype/tools/launcher/widgets.py b/openpype/tools/launcher/widgets.py index 22b08d7d15..59fa2b729e 100644 --- a/openpype/tools/launcher/widgets.py +++ b/openpype/tools/launcher/widgets.py @@ -22,6 +22,9 @@ from .constants import ( class ProjectBar(QtWidgets.QWidget): project_changed = QtCore.Signal(int) + # Project list will be refreshed each 10000 msecs + refresh_interval = 10000 + def __init__(self, dbcon, parent=None): super(ProjectBar, self).__init__(parent) @@ -47,14 +50,19 @@ class ProjectBar(QtWidgets.QWidget): QtWidgets.QSizePolicy.Maximum ) + refresh_timer = QtCore.QTimer() + refresh_timer.setInterval(self.refresh_interval) + self.model = model self.project_delegate = project_delegate self.project_combobox = project_combobox + self.refresh_timer = refresh_timer # Initialize self.refresh() # Signals + refresh_timer.timeout.connect(self._on_refresh_timeout) self.project_combobox.currentIndexChanged.connect(self.project_changed) # Set current project by default if it's set. @@ -62,6 +70,20 @@ class ProjectBar(QtWidgets.QWidget): if project_name: self.set_project(project_name) + def showEvent(self, event): + if not self.refresh_timer.isActive(): + self.refresh_timer.start() + super(ProjectBar, self).showEvent(event) + + def _on_refresh_timeout(self): + if not self.isVisible(): + # Stop timer if widget is not visible + self.refresh_timer.stop() + + elif self.isActiveWindow(): + # Refresh projects if window is active + self.model.refresh() + def get_current_project(self): return self.project_combobox.currentText() diff --git a/openpype/tools/launcher/window.py b/openpype/tools/launcher/window.py index af749814b7..25aa273ca0 100644 --- a/openpype/tools/launcher/window.py +++ b/openpype/tools/launcher/window.py @@ -91,6 +91,8 @@ class ProjectsPanel(QtWidgets.QWidget): """Projects Page""" project_clicked = QtCore.Signal(str) + # Refresh projects each 10000 msecs + refresh_interval = 10000 def __init__(self, dbcon, parent=None): super(ProjectsPanel, self).__init__(parent=parent) @@ -111,16 +113,36 @@ class ProjectsPanel(QtWidgets.QWidget): layout.addWidget(view) + refresh_timer = QtCore.QTimer() + refresh_timer.setInterval(self.refresh_interval) + + refresh_timer.timeout.connect(self._on_refresh_timeout) view.clicked.connect(self.on_clicked) self.model = model self.view = view + self.refresh_timer = refresh_timer def on_clicked(self, index): if index.isValid(): project_name = index.data(QtCore.Qt.DisplayRole) self.project_clicked.emit(project_name) + def showEvent(self, event): + self.model.refresh() + if not self.refresh_timer.isActive(): + self.refresh_timer.start() + super(ProjectsPanel, self).showEvent(event) + + def _on_refresh_timeout(self): + if not self.isVisible(): + # Stop timer if widget is not visible + self.refresh_timer.stop() + + elif self.isActiveWindow(): + # Refresh projects if window is active + self.model.refresh() + class AssetsPanel(QtWidgets.QWidget): """Assets page""" From d6e345addc67006c2e1d48e30c9a4c0c0b95e378 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 17 Jun 2021 15:09:09 +0200 Subject: [PATCH 36/39] removed unnecessary refresh calls --- openpype/tools/launcher/window.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openpype/tools/launcher/window.py b/openpype/tools/launcher/window.py index 25aa273ca0..5e47cfd154 100644 --- a/openpype/tools/launcher/window.py +++ b/openpype/tools/launcher/window.py @@ -108,7 +108,6 @@ class ProjectsPanel(QtWidgets.QWidget): flick.activateOn(view) model = ProjectModel(self.dbcon) model.hide_invisible = True - model.refresh() view.setModel(model) layout.addWidget(view) @@ -434,7 +433,6 @@ class LauncherWindow(QtWidgets.QDialog): def on_back_clicked(self): self.dbcon.Session["AVALON_PROJECT"] = None self.set_page(0) - self.project_panel.model.refresh() # Refresh projects self.discover_actions() def on_action_clicked(self, action): From 8d9ccaf45bb6a0c5d96455359eb5d43fb317aee8 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 17 Jun 2021 15:15:27 +0200 Subject: [PATCH 37/39] simplified refreshing of project bar --- openpype/tools/launcher/widgets.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/openpype/tools/launcher/widgets.py b/openpype/tools/launcher/widgets.py index 59fa2b729e..11301aba64 100644 --- a/openpype/tools/launcher/widgets.py +++ b/openpype/tools/launcher/widgets.py @@ -91,27 +91,14 @@ class ProjectBar(QtWidgets.QWidget): index = self.project_combobox.findText(project_name) if index < 0: # Try refresh combobox model - self.project_combobox.blockSignals(True) - self.model.refresh() - self.project_combobox.blockSignals(False) - + self.refresh() index = self.project_combobox.findText(project_name) if index >= 0: self.project_combobox.setCurrentIndex(index) def refresh(self): - prev_project_name = self.get_current_project() - - # Refresh without signals - self.project_combobox.blockSignals(True) - self.model.refresh() - self.set_project(prev_project_name) - - self.project_combobox.blockSignals(False) - - self.project_changed.emit(self.project_combobox.currentIndex()) class ActionBar(QtWidgets.QWidget): From 193296ffaa63732eb43938b7b81e247218d76156 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 17 Jun 2021 15:15:44 +0200 Subject: [PATCH 38/39] dont refresh on init --- openpype/tools/launcher/widgets.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/openpype/tools/launcher/widgets.py b/openpype/tools/launcher/widgets.py index 11301aba64..0e8caeb278 100644 --- a/openpype/tools/launcher/widgets.py +++ b/openpype/tools/launcher/widgets.py @@ -58,9 +58,6 @@ class ProjectBar(QtWidgets.QWidget): self.project_combobox = project_combobox self.refresh_timer = refresh_timer - # Initialize - self.refresh() - # Signals refresh_timer.timeout.connect(self._on_refresh_timeout) self.project_combobox.currentIndexChanged.connect(self.project_changed) From 5872a1364caeaa0739b5b9cc421644fd6e66dbf4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 17 Jun 2021 15:24:54 +0200 Subject: [PATCH 39/39] added refresh timer for actions --- openpype/tools/launcher/window.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/openpype/tools/launcher/window.py b/openpype/tools/launcher/window.py index 5e47cfd154..a6d34bbe9d 100644 --- a/openpype/tools/launcher/window.py +++ b/openpype/tools/launcher/window.py @@ -297,6 +297,8 @@ class AssetsPanel(QtWidgets.QWidget): class LauncherWindow(QtWidgets.QDialog): """Launcher interface""" + # Refresh actions each 10000msecs + actions_refresh_timeout = 10000 def __init__(self, parent=None): super(LauncherWindow, self).__init__(parent) @@ -365,6 +367,10 @@ class LauncherWindow(QtWidgets.QDialog): layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) + actions_refresh_timer = QtCore.QTimer() + actions_refresh_timer.setInterval(self.actions_refresh_timeout) + + self.actions_refresh_timer = actions_refresh_timer self.message_label = message_label self.project_panel = project_panel self.asset_panel = asset_panel @@ -374,6 +380,7 @@ class LauncherWindow(QtWidgets.QDialog): self._page = 0 # signals + actions_refresh_timer.timeout.connect(self._on_action_timer) actions_bar.action_clicked.connect(self.on_action_clicked) action_history.trigger_history.connect(self.on_history_action) project_panel.project_clicked.connect(self.on_project_clicked) @@ -388,9 +395,11 @@ class LauncherWindow(QtWidgets.QDialog): self.resize(520, 740) def showEvent(self, event): - super().showEvent(event) - # TODO implement refresh/reset which will trigger updating - self.discover_actions() + if not self.actions_refresh_timer.isActive(): + self.actions_refresh_timer.start() + self.discover_actions() + + super(LauncherWindow, self).showEvent(event) def set_page(self, page): current = self.page_slider.currentIndex() @@ -423,6 +432,15 @@ class LauncherWindow(QtWidgets.QDialog): def filter_actions(self): self.actions_bar.filter_actions() + def _on_action_timer(self): + if not self.isVisible(): + # Stop timer if widget is not visible + self.actions_refresh_timer.stop() + + elif self.isActiveWindow(): + # Refresh projects if window is active + self.discover_actions() + def on_project_clicked(self, project_name): self.dbcon.Session["AVALON_PROJECT"] = project_name # Refresh projects