Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ocioview image and PySide6 updates #1912

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/apps/ocioview/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pathlib import Path

import PyOpenColorIO as ocio
from PySide6 import QtCore, QtGui, QtWidgets, QtOpenGL
from PySide6 import QtCore, QtGui, QtWidgets

import ocioview.log_handlers # Import to initialize logging
from ocioview.main_window import OCIOView
Expand Down
2 changes: 1 addition & 1 deletion src/apps/ocioview/ocioview/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

# Sizes
ICON_SIZE_ITEM = QtCore.QSize(20, 20)
ICON_SIZE_BUTTON = QtCore.QSize(24, 24)
ICON_SIZE_BUTTON = QtCore.QSize(20, 20)
ICON_SCALE_FACTOR = 1.15

MARGIN_WIDTH = 13 # Pixels
Expand Down
1 change: 1 addition & 0 deletions src/apps/ocioview/ocioview/inspect/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
# Copyright Contributors to the OpenColorIO Project.

from .code_inspector import CodeInspector
from .curve_inspector import CurveInspector
from .log_inspector import LogInspector
4 changes: 3 additions & 1 deletion src/apps/ocioview/ocioview/inspect/code_inspector.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ def __init__(self, parent: Optional[QtCore.QObject] = None):

html_css = HtmlFormatter(style="material").get_style_defs()
# Update line number colors to match palette
html_css = html_css.replace("#263238", palette.color(palette.ColorRole.Base).name())
html_css = html_css.replace(
"#263238", palette.color(palette.ColorRole.Base).name()
)
html_css = html_css.replace(
"#37474F", palette.color(palette.ColorRole.Text).darker(150).name()
)
Expand Down
10 changes: 5 additions & 5 deletions src/apps/ocioview/ocioview/inspect/curve_inspector.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,21 +249,21 @@ def __init__(
# Initialize
self._update_x_samples()
msg_router = MessageRouter.get_instance()
msg_router.cpu_processor_ready.connect(self._on_cpu_processor_ready)
msg_router.processor_ready.connect(self._on_processor_ready)

def showEvent(self, event: QtGui.QShowEvent) -> None:
"""Start listening for processor updates, if visible."""
super().showEvent(event)

msg_router = MessageRouter.get_instance()
msg_router.set_cpu_processor_updates_allowed(True)
msg_router.set_processor_updates_allowed(True)

def hideEvent(self, event: QtGui.QHideEvent) -> None:
"""Stop listening for processor updates, if not visible."""
super().hideEvent(event)

msg_router = MessageRouter.get_instance()
msg_router.set_cpu_processor_updates_allowed(False)
msg_router.set_processor_updates_allowed(False)

def resizeEvent(self, event: QtGui.QResizeEvent) -> None:
"""Re-fit graph on resize, to always be centered."""
Expand Down Expand Up @@ -549,7 +549,7 @@ def _update_curves(self) -> None:
"""
self._update_x_samples()
if self._prev_cpu_proc is not None:
self._on_cpu_processor_ready(self._prev_cpu_proc)
self._on_processor_ready(self._prev_cpu_proc)

def _update_x_samples(self):
"""
Expand Down Expand Up @@ -603,7 +603,7 @@ def _fit(self) -> None:
self.update()

@QtCore.Slot(ocio.CPUProcessor)
def _on_cpu_processor_ready(self, cpu_proc: ocio.CPUProcessor) -> None:
def _on_processor_ready(self, cpu_proc: ocio.CPUProcessor) -> None:
"""
Update curves from sampled OCIO CPU processor.

Expand Down
3 changes: 1 addition & 2 deletions src/apps/ocioview/ocioview/inspect_dock.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@

from PySide6 import QtCore, QtWidgets

from .inspect.curve_inspector import CurveInspector
from .inspect import LogInspector, CodeInspector
from .inspect import CodeInspector, CurveInspector, LogInspector
from .utils import get_glyph_icon
from .widgets.structure import TabbedDockWidget

Expand Down
4 changes: 3 additions & 1 deletion src/apps/ocioview/ocioview/items/config_item_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ def __init__(self, parent: Optional[QtWidgets.QWidget] = None):

if self.__has_transforms__:
self.__has_tabs__ = True
no_tf_color = palette.color(palette.ColorGroup.Disabled, palette.ColorRole.Text)
no_tf_color = palette.color(
palette.ColorGroup.Disabled, palette.ColorRole.Text
)
self._from_ref_icon = get_glyph_icon("mdi6.layers-plus")
self._no_from_ref_icon = get_glyph_icon(
"mdi6.layers-plus", color=no_tf_color
Expand Down
85 changes: 58 additions & 27 deletions src/apps/ocioview/ocioview/message_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from typing import Any, Optional
from queue import Empty, SimpleQueue

import numpy as np
import PyOpenColorIO as ocio
from PySide6 import QtCore, QtGui, QtWidgets

Expand All @@ -30,9 +31,10 @@ class MessageRunner(QtCore.QObject):
error_logged = QtCore.Signal(str)
debug_logged = QtCore.Signal(str)

cpu_processor_ready = QtCore.Signal(ocio.CPUProcessor)
config_html_ready = QtCore.Signal(str)
ctf_html_ready = QtCore.Signal(str, ocio.GroupTransform)
image_ready = QtCore.Signal(np.ndarray)
processor_ready = QtCore.Signal(ocio.CPUProcessor)
shader_html_ready = QtCore.Signal(str, ocio.GPUProcessor)

LOOP_INTERVAL = 0.5 # In seconds
Expand Down Expand Up @@ -64,21 +66,23 @@ def __init__(self, parent: Optional[QtCore.QObject] = None):
self._gpu_language = ocio.GPU_LANGUAGE_GLSL_4_0

self._prev_config = None
self._prev_proc = None
self._prev_cpu_proc = None
self._prev_image_array = None

self._cpu_processor_updates_allowed = False
self._config_updates_allowed = False
self._ctf_updates_allowed = False
self._image_updates_allowed = False
self._processor_updates_allowed = False
self._shader_updates_allowed = False

def get_gpu_language(self) -> ocio.GpuLanguage:
return self._gpu_language

def set_gpu_language(self, gpu_language: ocio.GpuLanguage) -> None:
self._gpu_language = gpu_language
if self._shader_updates_allowed and self._prev_proc is not None:
if self._shader_updates_allowed and self._prev_cpu_proc is not None:
# Rebroadcast last processor record
message_queue.put_nowait(self._prev_proc)
message_queue.put_nowait(self._prev_cpu_proc)

def config_updates_allowed(self) -> bool:
return self._config_updates_allowed
Expand All @@ -89,32 +93,41 @@ def set_config_updates_allowed(self, allowed: bool) -> None:
# Rebroadcast last config record
message_queue.put_nowait(self._prev_config)

def cpu_processor_updates_allowed(self) -> bool:
return self._cpu_processor_updates_allowed

def set_cpu_processor_updates_allowed(self, allowed: bool) -> None:
self._cpu_processor_updates_allowed = allowed
if allowed and self._prev_config is not None:
# Rebroadcast last config record
message_queue.put_nowait(self._prev_config)

def ctf_updates_allowed(self) -> bool:
return self._ctf_updates_allowed

def set_ctf_updates_allowed(self, allowed: bool) -> None:
self._ctf_updates_allowed = allowed
if allowed and self._prev_proc is not None:
if allowed and self._prev_cpu_proc is not None:
# Rebroadcast last processor record
message_queue.put_nowait(self._prev_proc)
message_queue.put_nowait(self._prev_cpu_proc)

def image_updates_allowed(self) -> bool:
return self._image_updates_allowed

def set_image_updates_allowed(self, allowed: bool) -> None:
self._image_updates_allowed = allowed
if allowed and self._prev_image_array is not None:
# Rebroadcast last image record
message_queue.put_nowait(self._prev_image_array)

def processor_updates_allowed(self) -> bool:
return self._processor_updates_allowed

def set_processor_updates_allowed(self, allowed: bool) -> None:
self._processor_updates_allowed = allowed
if allowed and self._prev_config is not None:
# Rebroadcast last config record
message_queue.put_nowait(self._prev_config)
Comment on lines +105 to +121
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we use properties here?

    @property
    def image_updates_allowed(self) -> bool:
        return self._image_updates_allowed

    @image_updates_allowed.setter
    def image_updates_allowed(self, allowed: bool) -> None:
        self._image_updates_allowed = allowed
        if allowed and self._prev_image_array is not None:
            # Rebroadcast last image record
            message_queue.put_nowait(self._prev_image_array)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I will address this in a future PR


def shader_updates_allowed(self) -> bool:
return self._shader_updates_allowed

def set_shader_updates_allowed(self, allowed: bool) -> None:
self._shader_updates_allowed = allowed
if allowed and self._prev_proc is not None:
if allowed and self._prev_cpu_proc is not None:
# Rebroadcast last processor record
message_queue.put_nowait(self._prev_proc)
message_queue.put_nowait(self._prev_cpu_proc)

def is_routing(self) -> bool:
"""Whether runner is routing messages."""
Expand Down Expand Up @@ -144,14 +157,20 @@ def start_routing(self) -> None:

# OCIO processor
elif isinstance(msg_raw, ocio.Processor):
self._prev_proc = msg_raw
self._prev_cpu_proc = msg_raw
if (
self._cpu_processor_updates_allowed
self._processor_updates_allowed
or self._ctf_updates_allowed
or self._shader_updates_allowed
):
self._handle_processor_message(msg_raw)

# Image array
elif isinstance(msg_raw, np.ndarray):
self._prev_image_array = msg_raw
if self._image_updates_allowed:
self._handle_image_message(msg_raw)

# Python or OCIO log record
else:
self._handle_log_message(msg_raw)
Expand All @@ -162,7 +181,7 @@ def _handle_config_message(self, config: ocio.Config) -> None:
"""
Handle OCIO config received in the message queue.

:config: OCIO config instance
:param config: OCIO config instance
"""
try:
config_html_data = config_to_html(config)
Expand All @@ -171,22 +190,22 @@ def _handle_config_message(self, config: ocio.Config) -> None:
# Pass error to log
self._handle_log_message(str(e), force_level=self.LOG_LEVEL_WARNING)

def _handle_processor_message(self, processor: ocio.Processor) -> None:
def _handle_processor_message(self, cpu_proc: ocio.Processor) -> None:
"""
Handle OCIO processor received in the message queue.

:config: OCIO processor instance
:param cpu_proc: OCIO processor instance
"""
try:
if self._cpu_processor_updates_allowed:
self.cpu_processor_ready.emit(processor.getDefaultCPUProcessor())
if self._processor_updates_allowed:
self.processor_ready.emit(cpu_proc.getDefaultCPUProcessor())

if self._ctf_updates_allowed:
ctf_html_data, group_tf = processor_to_ctf_html(processor)
ctf_html_data, group_tf = processor_to_ctf_html(cpu_proc)
self.ctf_html_ready.emit(ctf_html_data, group_tf)

if self._shader_updates_allowed:
gpu_proc = processor.getDefaultGPUProcessor()
gpu_proc = cpu_proc.getDefaultGPUProcessor()
shader_html_data = processor_to_shader_html(
gpu_proc, self._gpu_language
)
Expand All @@ -196,6 +215,18 @@ def _handle_processor_message(self, processor: ocio.Processor) -> None:
# Pass error to log
self._handle_log_message(str(e), force_level=self.LOG_LEVEL_WARNING)

def _handle_image_message(self, image_array: np.ndarray) -> None:
"""
Handle image buffer received in the message queue.

:param image_array: Image array
"""
try:
self.image_ready.emit(image_array)
except Exception as e:
# Pass error to log
self._handle_log_message(str(e), force_level=self.LOG_LEVEL_WARNING)

def _handle_log_message(
self, log_record: str, force_level: Optional[str] = None
) -> None:
Expand Down
10 changes: 10 additions & 0 deletions src/apps/ocioview/ocioview/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,13 @@ def increase_html_lineno_padding(html: str) -> str:
r"\1\2  \3",
html,
)


def float_to_uint8(value: float) -> int:
"""
Convert float value to an 8-bit clamped unsigned integer value.

:param value: Float value
:return: Integer value
"""
return max(0, min(255, int(value * 255)))
1 change: 1 addition & 0 deletions src/apps/ocioview/ocioview/viewer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
# Copyright Contributors to the OpenColorIO Project.

from .image_viewer import ViewerChannels, ImageViewer
from .utils import load_image
Loading
Loading