Compare commits

...
2 Commits
Author SHA1 Message Date
+3 92db29b9e7 Integrate main into RB-2.3 branch and update library version (#1918)
* Fix support for X86 32-bit (#1842)

Signed-off-by: Mark Reid <mindmark@gmail.com>
(cherry picked from commit 16b3157f2e)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Add some small arm neon optimizations (#1847)

* Remove unused includes

Signed-off-by: Mark Reid <mindmark@gmail.com>

* Use neon hardware support for f16 conversions

Signed-off-by: Mark Reid <mindmark@gmail.com>

* Add some small neon optimizations
use blendv,floor and fma intrinsics were possible

Signed-off-by: Mark Reid <mindmark@gmail.com>

---------

Signed-off-by: Mark Reid <mindmark@gmail.com>
(cherry picked from commit 14f0afa2d8)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Add links to new release notes documentation (#1848)

Signed-off-by: Kevin Wheatley <kevin.wheatley@framestore.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 87126fad7f)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Changing version to 2.4.0 (#1852)

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 381d1fc371)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Correctly recover CXX_FLAGS in CheckSupportSSE2.cmake (#1861)

Signed-off-by: Chongyun Lee <uchkks@protonmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit c429400170)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix regression in cccid handling when no value is supplied (#1855)

In v1 of OCIO FileTransforms are able to load .cc files
without specifying a cccid. In v2 this broke causing an
exception to be raised instead of using the first cc found
in the file.

Signed-off-by: Kevin Wheatley <kevin.wheatley@framestore.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit c7ad35340a)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix missing cache id reset on look update. (#1873)

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>
(cherry picked from commit dddbee023d)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* ocioview: Curve Inspector improvements (#1845)

* Curve inspector improvements

- Move README to root app folder
- Change curve inspector grid to always render as a square with 10 segments.
- Add transform init callback to set new transform subscriptions to the current viewer if set to passthrough.

Signed-off-by: Michael Dolan <michdolan@gmail.com>

* Improve log range calculation

Signed-off-by: Michael Dolan <michdolan@gmail.com>

* Improve channel sample comparison

Signed-off-by: Michael Dolan <michdolan@gmail.com>

* Update src/apps/ocioview/ocioview/inspect/curve_inspector.py

Signed-off-by: Michael Dolan <michdolan@gmail.com>

Co-authored-by: Doug Walker <doug.walker@autodesk.com>
Signed-off-by: Michael Dolan <michdolan@gmail.com>

---------

Signed-off-by: Michael Dolan <michdolan@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 8add374dad)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix missing Default View Transform on equal operator (#1886)

Add the missing assignment of the the default view transform when a config is copied using the equal operator

Signed-off-by: Michael De Caria <decariamichael@gmail.com>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit bc8569b2db)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Remove circular import caused by typing annotations. (#1882)

Signed-off-by: Thomas Mansencal <thomas.mansencal@gmail.com>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 1fad4666c3)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* fix(grammatical): Spelling mistakes (#1892)

Signed-off-by: AbhineshJha <abhinesh_223002@saitm.org>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 0d00b2c538)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Improve ocioview mac support and simplify dependencies (#1853)

* PySide 6, remove imath, add imageio support

Signed-off-by: Rémi Achard <remiachard@gmail.com>

Remove Imath

Signed-off-by: Rémi Achard <remiachard@gmail.com>

Support imageio as fallback for openimageio

Signed-off-by: Rémi Achard <remiachard@gmail.com>

Further adjustments following latest updates

Signed-off-by: Rémi Achard <remiachard@gmail.com>

Fix pixel probe

Signed-off-by: Remi Achard <remiachard@gmail.com>

Add OpenColorIO to requirements

Signed-off-by: Remi Achard <remiachard@gmail.com>

* Fix rebase issue

Signed-off-by: Remi Achard <remiachard@gmail.com>

---------

Signed-off-by: Remi Achard <remiachard@gmail.com>
Signed-off-by: Thomas Mansencal <thomas.mansencal@gmail.com>
Signed-off-by: Michael Dolan <michdolan@gmail.com>
Co-authored-by: Thomas Mansencal <thomas.mansencal@gmail.com>
Co-authored-by: Michael Dolan <michdolan@gmail.com>
(cherry picked from commit 45544ce667)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Issue #1874 Cast to unsigned char for isspace. (#1888)

* Issue #1874 Cast to unsigned char for isspace.

Signed-off-by: pylee <penne.y.lee@intel.com>

* Add unit test.

Signed-off-by: pylee <penne.y.lee@intel.com>

* Add test comment as suggested in code review.

Signed-off-by: pylee <penne.y.lee@intel.com>

---------

Signed-off-by: pylee <penne.y.lee@intel.com>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit ed852073f2)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Tentative fix for the doxygen installation in the CI (Windows) (#1890)

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit b94a184e4b)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Simplify the Findyaml-cpp module (#1891)

This fixes compatibility with yaml-cpp 0.8, which previously failed
because of a `get_property` call with the wrong target name.
I took the liberty to add a few simplifications along the way.

Signed-off-by: Tobias Mayer <tobim@fastmail.fm>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 1d3b69502e)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Skip processor concatenation if the display color space is also data. (#1896)

* Skip processor concatenation if the display view transform is also data.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Moved missing display color space exception before processor creation.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

---------

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 52b496528c)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Restore GPU workflow and minor updates to CI (#1899)

* Restore GPU workflow runs

Signed-off-by: Rémi Achard <remiachard@gmail.com>

* Enable undefined behaviour sanitizer

Signed-off-by: Rémi Achard <remiachard@gmail.com>

* Fix SIMD option for platform_latest

Signed-off-by: Rémi Achard <remiachard@gmail.com>

* Fix install_docs_env on CI workflow (not used at the moment)

Signed-off-by: Rémi Achard <remiachard@gmail.com>

* Fix OpenEXR build flag

Signed-off-by: Rémi Achard <remiachard@gmail.com>

---------

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 382dcb6ce7)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Improve handling of pystring include dir (#1901)

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 9078753990)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Improve compatibility with minizip-ng COMPAT mode (#1902)

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit ffd0f70ad5)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix NamedTransform context var issue (#1905)

Signed-off-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 4d64b32bc7)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix env serialization for v1 configs (#1904)

Signed-off-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 4f4f30e1d3)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix yaml-cpp build issues (#1907)

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 41441bb2e6)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Adsk Contrib - Improve heuristics for finding known color spaces (#1913)

* Improve heuristics

Signed-off-by: Doug Walker <doug.walker@autodesk.com>

* Add some comments

Signed-off-by: Doug Walker <doug.walker@autodesk.com>

---------

Signed-off-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit d8852b5d6c)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Add Python 3.12 wheels (#1898)

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit f2cfec330e)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Increment library version to 2.3.1

Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix wrong RPATH being injected into Python bindings DSO (#1849)

Signed-off-by: Kevin Wheatley <kevin.wheatley@framestore.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit ba2b41e309)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

---------

Signed-off-by: Mark Reid <mindmark@gmail.com>
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>
Signed-off-by: Kevin Wheatley <kevin.wheatley@framestore.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Chongyun Lee <uchkks@protonmail.com>
Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>
Signed-off-by: Michael Dolan <michdolan@gmail.com>
Signed-off-by: Michael De Caria <decariamichael@gmail.com>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Signed-off-by: Thomas Mansencal <thomas.mansencal@gmail.com>
Signed-off-by: AbhineshJha <abhinesh_223002@saitm.org>
Signed-off-by: Remi Achard <remiachard@gmail.com>
Signed-off-by: pylee <penne.y.lee@intel.com>
Signed-off-by: Tobias Mayer <tobim@fastmail.fm>
Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Mark Reid <mindmark@gmail.com>
Co-authored-by: Kevin Wheatley <kevin.wheatley@framestore.com>
Co-authored-by: Cédrik Fuoco <105517825+cedrik-fuoco-adsk@users.noreply.github.com>
Co-authored-by: Uchiha Kakashi <45286352+licy183@users.noreply.github.com>
Co-authored-by: Éric Renaud-Houde <eric.renaud.houde@gmail.com>
Co-authored-by: Michael Dolan <michdolan@gmail.com>
Co-authored-by: Michael De Caria <decariamichael@gmail.com>
Co-authored-by: Thomas Mansencal <thomas.mansencal@gmail.com>
Co-authored-by: Abhinesh <142514166+AbhineshJha@users.noreply.github.com>
Co-authored-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: PenneLee <pennelee@gmail.com>
Co-authored-by: tobim <tobim+github@fastmail.fm>
2023-12-07 20:02:08 -05:00
Cédrik Fuoco b35fb73b86 Update release type (#1839)
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
2023-08-31 21:38:17 -04:00
143 changed files with 5619 additions and 659 deletions
+17 -2
View File
@@ -77,6 +77,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2023
install-ext-packages: MISSING
- build: 11
build-type: Release
build-shared: 'ON'
@@ -89,6 +90,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2023
install-ext-packages: ALL
- build: 10
build-type: Release
build-shared: 'OFF'
@@ -101,6 +103,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2023
install-ext-packages: ALL
# -------------------------------------------------------------------
# VFX CY2022 (Python 3.9)
# -------------------------------------------------------------------
@@ -116,6 +119,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2022
install-ext-packages: ALL
- build: 8
build-type: Release
build-shared: 'ON'
@@ -128,6 +132,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2022
install-ext-packages: MISSING
- build: 7
build-type: Release
build-shared: 'OFF'
@@ -140,6 +145,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2022
install-ext-packages: ALL
# -------------------------------------------------------------------
# VFX CY2021 (Python 3.7)
# -------------------------------------------------------------------
@@ -155,6 +161,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2021
install-ext-packages: MISSING
- build: 5
build-type: Release
build-shared: 'OFF'
@@ -167,6 +174,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2021
install-ext-packages: ALL
- build: 4
build-type: Debug
build-shared: 'ON'
@@ -179,6 +187,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2021
install-ext-packages: ALL
# -------------------------------------------------------------------
# VFX CY2020 (Python 3.7)
# -------------------------------------------------------------------
@@ -194,6 +203,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2020
install-ext-packages: MISSING
- build: 2
build-type: Debug
build-shared: 'OFF'
@@ -206,6 +216,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2020
install-ext-packages: ALL
- build: 1
build-type: Release
build-shared: 'ON'
@@ -218,6 +229,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2020
install-ext-packages: ALL
env:
CXX: ${{ matrix.cxx-compiler }}
CC: ${{ matrix.cc-compiler }}
@@ -245,7 +257,7 @@ jobs:
-DOCIO_BUILD_GPU_TESTS=OFF \
-DOCIO_USE_SIMD=${{ matrix.use-simd }} \
-DOCIO_USE_OIIO_FOR_APPS=${{ matrix.use-oiio }} \
-DOCIO_INSTALL_EXT_PACKAGES=ALL \
-DOCIO_INSTALL_EXT_PACKAGES=${{ matrix.install-ext-packages }} \
-DOCIO_WARNING_AS_ERROR=ON \
-DPython_EXECUTABLE=$(which python)
working-directory: _build
@@ -527,7 +539,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- name: Install docs env
run: share/ci/scripts/windows/install_docs_env.sh
run: |
DOXYGEN_PATH=$GITHUB_WORKSPACE/doxygen
share/ci/scripts/windows/install_docs_env.sh "$DOXYGEN_PATH"
echo "$DOXYGEN_PATH" >> $GITHUB_PATH
shell: bash
if: matrix.build-docs == 'ON'
- name: Install tests env
+15 -4
View File
@@ -54,6 +54,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2022
use-oiio: 'ON'
- build: 2
build-docs: 'OFF'
build-openfx: 'OFF'
@@ -62,6 +63,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2021
use-oiio: 'OFF'
# -------------------------------------------------------------------
# Clang
# -------------------------------------------------------------------
@@ -73,6 +75,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2022
use-oiio: 'OFF'
- build: 4
build-docs: 'ON'
build-openfx: 'ON'
@@ -81,6 +84,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2021
use-oiio: 'ON'
env:
CXX: ${{ matrix.cxx-compiler }}
CC: ${{ matrix.cc-compiler }}
@@ -132,7 +136,7 @@ jobs:
-DOCIO_INSTALL_EXT_PACKAGES=NONE \
-DOCIO_WARNING_AS_ERROR=OFF \
-DPython_EXECUTABLE=$(which python) \
-DOCIO_USE_OIIO_CMAKE_CONFIG=ON
-DOCIO_USE_OIIO_FOR_APPS=${{ matrix.use-oiio }}
working-directory: _build
- name: Build
run: |
@@ -176,11 +180,13 @@ jobs:
build-openfx: 'ON'
cxx-standard: 17
python-version: '3.11'
use-oiio: 'ON'
- build: 2
build-docs: 'ON'
build-openfx: 'ON'
cxx-standard: 14
python-version: '3.9'
use-oiio: 'OFF'
steps:
- name: Setup Python
uses: actions/setup-python@v4
@@ -235,7 +241,7 @@ jobs:
-DOCIO_INSTALL_EXT_PACKAGES=NONE \
-DOCIO_WARNING_AS_ERROR=OFF \
-DPython_EXECUTABLE=$(which python) \
-DOCIO_USE_OIIO_CMAKE_CONFIG=ON
-DOCIO_USE_OIIO_FOR_APPS=${{ matrix.use-oiio }}
working-directory: _build
- name: Build
run: |
@@ -279,11 +285,13 @@ jobs:
build-openfx: 'ON'
cxx-standard: 17
python-version: '3.11'
use-oiio: 'ON'
- build: 2
build-docs: 'ON'
build-openfx: 'ON'
cxx-standard: 14
python-version: '3.9'
use-oiio: 'OFF'
steps:
- name: Setup Python
uses: actions/setup-python@v4
@@ -292,7 +300,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- name: Install docs env
run: share/ci/scripts/windows/install_docs_env.sh
run: |
DOXYGEN_PATH=$GITHUB_WORKSPACE/doxygen
share/ci/scripts/windows/install_docs_env.sh "$DOXYGEN_PATH"
echo "$DOXYGEN_PATH" >> $GITHUB_PATH
shell: bash
if: matrix.build-docs == 'ON'
- name: Install tests env
@@ -359,7 +370,7 @@ jobs:
-DOCIO_WARNING_AS_ERROR=OFF \
-DPython_EXECUTABLE=$(which python) \
-DOCIO_BUILD_PYTHON=OFF \
-DOCIO_USE_OIIO_CMAKE_CONFIG=ON
-DOCIO_USE_OIIO_FOR_APPS=${{ matrix.use-oiio }}
shell: bash
working-directory: _build
- name: Build
-2
View File
@@ -16,8 +16,6 @@ on:
tags-ignore:
- v0.*
- v1.*
paths:
- .github/workflows/gpu_workflow.yml
jobs:
# ---------------------------------------------------------------------------
+3 -3
View File
@@ -104,7 +104,7 @@ jobs:
-DOCIO_BUILD_OPENFX=ON \
-DOCIO_BUILD_GPU_TESTS=OFF \
-DOCIO_BUILD_PYTHON=${{ matrix.build-python}} \
-DOCIO_USE_SSE=ON \
-DOCIO_USE_SIMD=ON \
-DOCIO_USE_OIIO_FOR_APPS=OFF \
-DOCIO_INSTALL_EXT_PACKAGES=ALL \
-DOCIO_WARNING_AS_ERROR=ON \
@@ -219,7 +219,7 @@ jobs:
-DOCIO_BUILD_OPENFX=ON \
-DOCIO_BUILD_GPU_TESTS=OFF \
-DOCIO_BUILD_PYTHON=${{ matrix.build-python}} \
-DOCIO_USE_SSE=ON \
-DOCIO_USE_SIMD=ON \
-DOCIO_USE_OIIO_FOR_APPS=OFF \
-DOCIO_INSTALL_EXT_PACKAGES=ALL \
-DOCIO_WARNING_AS_ERROR=ON \
@@ -333,7 +333,7 @@ jobs:
-DOCIO_BUILD_OPENFX=ON \
-DOCIO_BUILD_GPU_TESTS=OFF \
-DOCIO_BUILD_PYTHON=${{ matrix.build-python}} \
-DOCIO_USE_SSE=ON \
-DOCIO_USE_SIMD=ON \
-DOCIO_USE_OIIO_FOR_APPS=OFF \
-DOCIO_INSTALL_EXT_PACKAGES=ALL \
-DOCIO_WARNING_AS_ERROR=ON \
+20 -5
View File
@@ -95,6 +95,9 @@ jobs:
- build: CPython 3.11 64 bits
python: cp311-manylinux*
arch: x86_64
- build: CPython 3.12 64 bits
python: cp312-manylinux*
arch: x86_64
# -------------------------------------------------------------------
# CPython ARM 64 bits
# -------------------------------------------------------------------
@@ -113,6 +116,9 @@ jobs:
- build: CPython 3.11 ARM 64 bits
python: cp311-manylinux*
arch: aarch64
- build: CPython 3.12 ARM 64 bits
python: cp312-manylinux*
arch: aarch64
steps:
- uses: actions/checkout@v3
@@ -128,7 +134,7 @@ jobs:
platforms: all
- name: Build wheels
uses: pypa/cibuildwheel@v2.13.1
uses: pypa/cibuildwheel@v2.16.2
env:
CIBW_BUILD: ${{ matrix.python }}
CIBW_ARCHS: ${{ matrix.arch }}
@@ -143,7 +149,7 @@ jobs:
macos:
name: Build wheels on macOS
runs-on: macos-11
runs-on: macos-12
# Don't run on OCIO forks
if: |
github.event_name != 'schedule' ||
@@ -169,6 +175,9 @@ jobs:
- build: CPython 3.11 64 bits
python: cp311-*
arch: x86_64
- build: CPython 3.12 64 bits
python: cp312-*
arch: x86_64
# -------------------------------------------------------------------
# CPython ARM 64 bits
# -------------------------------------------------------------------
@@ -184,6 +193,9 @@ jobs:
- build: CPython 3.11 ARM 64 bits
python: cp311-*
arch: arm64
- build: CPython 3.12 ARM 64 bits
python: cp312-*
arch: arm64
steps:
- uses: actions/checkout@v3
@@ -194,7 +206,7 @@ jobs:
python-version: '3.8'
- name: Build wheels
uses: pypa/cibuildwheel@v2.13.1
uses: pypa/cibuildwheel@v2.16.2
env:
CIBW_BUILD: ${{ matrix.python }}
CIBW_ARCHS: ${{ matrix.arch }}
@@ -209,7 +221,7 @@ jobs:
windows:
name: Build wheels on Windows
runs-on: windows-2019
runs-on: windows-2022
# Don't run on OCIO forks
if: |
github.event_name != 'schedule' ||
@@ -235,6 +247,9 @@ jobs:
- build: CPython 3.11 64 bits
python: cp311-*
arch: AMD64
- build: CPython 3.12 64 bits
python: cp312-*
arch: AMD64
steps:
- uses: actions/checkout@v3
@@ -245,7 +260,7 @@ jobs:
python-version: '3.8'
- name: Build wheels
uses: pypa/cibuildwheel@v2.13.1
uses: pypa/cibuildwheel@v2.16.2
env:
CIBW_BUILD: ${{ matrix.python }}
CIBW_ARCHS: ${{ matrix.arch }}
+5
View File
@@ -3,8 +3,13 @@
This file documents releases up to 1.1.1. For a description of version 2.0 and later
please refer to the Releases page on GitHub:
https://github.com/AcademySoftwareFoundation/OpenColorIO/releases
and for more details please see the release notes in latest documentation pages:
https://opencolorio.readthedocs.io/en/latest/releases/_index.html#releases
**Version 1.1.1 (April 2 2019):**
* Added optional compatibility for building apps with OpenImageIO 1.9+
* Added USE_SSE checks to fix Linux build failure
+6 -3
View File
@@ -29,13 +29,13 @@ endif()
# Project definition.
project(OpenColorIO
VERSION 2.3.0
VERSION 2.3.1
DESCRIPTION "OpenColorIO (OCIO) is a complete color management solution"
HOMEPAGE_URL https://github.com/AcademySoftwareFoundation/OpenColorIO
LANGUAGES CXX C)
# "dev", "beta1", rc1", etc or "" for an official release.
set(OpenColorIO_VERSION_RELEASE_TYPE "dev")
set(OpenColorIO_VERSION_RELEASE_TYPE "")
###############################################################################
@@ -180,8 +180,11 @@ option(OCIO_USE_OIIO_FOR_APPS "Request OIIO to build apps (ociolutimage, ociocon
if (NOT APPLE)
if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(AMD64|IA64|EM64T|X86|x86_64|i386|i686)")
if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(AMD64|IA64|EM64T|x86_64|X86|i386|i686)")
# Intel-based architecture (not APPLE)
if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(X86|i386|i686)")
set(OCIO_ARCH_X86_32 1)
endif()
set(OCIO_ARCH_X86 1)
set(OCIO_BUILD_ENABLE_OPTIMIZATIONS_SSE ON)
set(OCIO_BUILD_ENABLE_OPTIMIZATIONS_AVX ON)
+1 -1
View File
@@ -243,7 +243,7 @@ expected to validate the behavior of every part of OCIO:
* Any change to existing functionality should have tests added if they
don't already exist.
The test should should be run, via ``ctest``, before submitting a pull request.
The test should be run, via ``ctest``, before submitting a pull request.
## Versioning Policy
+10 -4
View File
@@ -38,7 +38,7 @@ Houdini, Silhouette FX, and
[others](https://opencolorio.org/#supported_apps).
OpenColorIO is free and open source software ([LICENSE](LICENSE)), and
one of several projects actvively sponsored by the ASWF
one of several projects actively sponsored by the ASWF
([Academy Software Foundation](https://www.aswf.io/)).
OpenColorIO Project Mission
@@ -50,12 +50,12 @@ content creation applications and pipelines.
OpenColorIO aims to:
* be stable, secure, and thouroughly tested on Linux, macOS, and Windows
* be stable, secure, and thoroughly tested on Linux, macOS, and Windows
* be performant on modern CPUs and GPUs
* be simple, scalable, and well documented
* be compatible with critical color and imaging standards
* provide lossless color processing wherever possible
* maintain config backwards compatability across major versions
* maintain config backwards compatibility across major versions
* have every new feature carefully reviewed by leaders from the motion picture,
VFX, animation, and video game industries
* have a healthy and active community
@@ -65,13 +65,14 @@ OpenColorIO Project Governance
------------------------------
OpenColorIO is governed by the Academy Software Foundation (ASWF). See
[GOVERNANCE.md](GOVERNANCE.md) for detailed infomation about how the project
[GOVERNANCE.md](GOVERNANCE.md) for detailed information about how the project
operates.
Web Resources
-------------
* Website: <http://opencolorio.org>
* Documentation: <https://opencolorio.readthedocs.io/en/latest/>
* Mailing lists:
* Developer: <ocio-dev@lists.aswf.io>
* User: <ocio-user@lists.aswf.io>
@@ -99,6 +100,11 @@ The following reference implementations are provided:
* Other
* nuke-default
Sources for the newer builtin ACES configuration files can be found in the releases section of the
[OpenColorIO-Config-ACES](https://github.com/AcademySoftwareFoundation/OpenColorIO-Config-ACES)
repository.
Acknowledgements
----------------
+4
View File
@@ -2456,6 +2456,10 @@ public:
*/
bool hasChannelCrosstalk() const;
/**
* Returns a hash string generated by hashing the cachedIDs of the (unoptimized) list of ops
* contained in the Processor. (This forms part of the key used by the config's processor cache.)
*/
const char * getCacheID() const;
/**
+1 -1
View File
@@ -760,7 +760,7 @@ extern OCIOEXPORT const char * OCIO_INACTIVE_COLORSPACES_ENVVAR;
* The envvar 'OCIO_OPTIMIZATION_FLAGS' provides a way to force a given optimization level.
* Remove the variable or set the value to empty to not use it. Set the value of the variable
* to the desired optimization level as either an integer or hexadecimal value.
* Ex: OCIO_OPTIMIZATION_FLAGS="20479" or "0x4FFF" for OPTIMIZATION_LOSSLESS.
* Ex: OCIO_OPTIMIZATION_FLAGS="144457667" or "0x89c3fc3" for OPTIMIZATION_LOSSLESS.
*/
extern OCIOEXPORT const char * OCIO_OPTIMIZATION_FLAGS_ENVVAR;
+6 -2
View File
@@ -4,7 +4,10 @@ requires = [
"wheel",
"cmake>=3.13",
"ninja; sys_platform != 'win32' and platform_machine != 'arm64'",
# Documentation requirements
# Documentation requirements (see docs/requirements.txt for details)
"urllib3<2",
"docutils>=0.18.1",
"sphinx<=7.1.2",
"six",
"testresources",
"recommonmark",
@@ -34,4 +37,5 @@ before-build = "share/ci/scripts/linux/yum/install_docs_env.sh"
before-build = "share/ci/scripts/macos/install_docs_env.sh"
[tool.cibuildwheel.windows]
before-build = "bash -c share/ci/scripts/windows/install_docs_env.sh"
environment = { PATH="$GITHUB_WORKSPACE/doxygen;$PATH" }
before-build = 'bash -c "share/ci/scripts/windows/install_docs_env.sh $GITHUB_WORKSPACE/doxygen"'
+1
View File
@@ -12,6 +12,7 @@ classifiers =
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: Implementation :: CPython
Programming Language :: C++
description = OpenColorIO (OCIO) is a complete color management solution geared towards motion picture production with an emphasis on visual effects and computer animation.
+2 -1
View File
@@ -5,6 +5,7 @@
set -ex
HERE=$(dirname $0)
DOXYGEN_LOCATION="$1"
bash $HERE/install_doxygen.sh latest
bash $HERE/install_doxygen.sh "$DOXYGEN_LOCATION"
pip install -r $HERE/../../../../docs/requirements.txt
+14 -6
View File
@@ -4,10 +4,18 @@
set -ex
DOXYGEN_VERSION="$1"
DOXYGEN_LOCATION="$1"
if [ "$DOXYGEN_VERSION" == "latest" ]; then
choco install doxygen.install
else
choco install doxygen.install --version=${DOXYGEN_VERSION}
fi
# Utility to parse JSON object.
choco install jq
# Get the URL of the latest zip package for Doxygen.
url=$(curl -s 'https://api.github.com/repos/doxygen/doxygen/releases/latest' | jq -r '.assets[] | select(.name | test("doxygen-.*windows.x64.bin.zip")) | .browser_download_url')
# Download the zip.
mkdir $DOXYGEN_LOCATION
cd $DOXYGEN_LOCATION
powershell 'iwr -URI '$url' -OutFile doxygen.zip'
# Unzip the file into $DOXYGEN_LOCATION.
unzip -o doxygen.zip
@@ -216,7 +216,7 @@ macro (ocio_handle_dependency dep_name)
endif()
if(ocio_dep_REQUIRED)
if(NOT ${dep_name}_FOUND AND NOT ocio_dep_VERSION)
if(NOT ${dep_name}_FOUND)
message(SEND_ERROR "${ColorError}${dep_name} is required, will abort at the end.${ColorReset}")
endif()
endif()
+16 -1
View File
@@ -8,6 +8,7 @@
# minizip-ng_LIBRARY - minizip-ng library to link to
# minizip-ng_INCLUDE_DIR - Where to find mz.h and other headers
# minizip-ng_VERSION - The version of the library
# minizip-ng_COMPAT - Whether minizip-ng MZ_COMPAT was used or not
#
# Global targets defined by this module:
# MINIZIP::minizip-ng - IMPORTED target, if found
@@ -114,7 +115,9 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
PATH_SUFFIXES
include
include/minizip-ng
include/minizip
minizip-ng/include
minizip/include
)
# Minizip-ng uses prefix "lib" on all platform by default.
@@ -202,4 +205,16 @@ if(_minizip-ng_TARGET_CREATE)
mark_as_advanced(minizip-ng_INCLUDE_DIR minizip-ng_LIBRARY minizip-ng_VERSION)
target_link_libraries(MINIZIP::minizip-ng INTERFACE ZLIB::ZLIB)
endif()
endif()
###############################################################################
### Detect compatibility mode ###
set(minizip-ng_COMPAT FALSE)
if(minizip-ng_INCLUDE_DIR)
list(GET minizip-ng_INCLUDE_DIR 0 _minizip-ng_INCLUDE_DIR)
if(EXISTS "${_minizip-ng_INCLUDE_DIR}/mz_compat.h")
set(minizip-ng_COMPAT TRUE)
endif()
endif()
mark_as_advanced(minizip-ng_COMPAT)
+2 -1
View File
@@ -28,11 +28,12 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
# Find include directory
find_path(pystring_INCLUDE_DIR
NAMES
pystring/pystring.h
pystring.h
HINTS
${pystring_ROOT}
PATH_SUFFIXES
include
include/pystring
pystring/include
)
+41 -37
View File
@@ -10,10 +10,9 @@
# yaml-cpp_VERSION - Library's version
#
# Global targets defined by this module:
# yaml-cpp
# yaml-cpp::yaml-cpp
#
# For compatibility with the upstream CMake package, the following variables and targets are defined:
# yaml-cpp::yaml-cpp - Alias of the yaml-cpp target
# YAML_CPP_LIBRARIES - Libraries to link against yaml-cpp
# YAML_CPP_INCLUDE_DIR - Include directory
#
@@ -41,16 +40,26 @@ if(CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
set(BUILD_TYPE_DEBUG ON)
endif()
if(yaml-cpp_FIND_QUIETLY)
set(quiet QUIET)
endif()
if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
set(_yaml-cpp_REQUIRED_VARS yaml-cpp_LIBRARY)
# Search for yaml-cpp-config.cmake
if(NOT DEFINED yaml-cpp_ROOT)
# Search for yaml-cpp-config.cmake
find_package(yaml-cpp ${yaml-cpp_FIND_VERSION} CONFIG QUIET)
find_package(yaml-cpp ${yaml-cpp_FIND_VERSION} CONFIG ${quiet})
endif()
if(yaml-cpp_FOUND)
get_target_property(yaml-cpp_LIBRARY yaml-cpp LOCATION)
# Alias target for yaml-cpp < 0.8 compatibility
if(TARGET yaml-cpp AND NOT TARGET yaml-cpp::yaml-cpp)
add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp)
endif()
get_target_property(yaml-cpp_INCLUDE_DIR yaml-cpp::yaml-cpp INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(yaml-cpp_LIBRARY yaml-cpp::yaml-cpp LOCATION)
else()
# As yaml-cpp-config.cmake search fails, search an installed library
@@ -59,14 +68,14 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
list(APPEND _yaml-cpp_REQUIRED_VARS yaml-cpp_INCLUDE_DIR yaml-cpp_VERSION)
# Search for yaml-cpp.pc
find_package(PkgConfig QUIET)
pkg_check_modules(PC_yaml-cpp QUIET "yaml-cpp>=${yaml-cpp_FIND_VERSION}")
find_package(PkgConfig ${quiet})
pkg_check_modules(PC_yaml-cpp ${quiet} "yaml-cpp>=${yaml-cpp_FIND_VERSION}")
# Try to detect the version installed, if any.
if(NOT PC_yaml-cpp_FOUND)
pkg_search_module(PC_yaml-cpp QUIET "yaml-cpp")
pkg_search_module(PC_yaml-cpp ${quiet} "yaml-cpp")
endif()
# Find include directory
find_path(yaml-cpp_INCLUDE_DIR
NAMES
@@ -91,7 +100,7 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
# Prefer static lib names
set(_yaml-cpp_STATIC_LIB_NAMES
"${CMAKE_STATIC_LIBRARY_PREFIX}yaml-cpp${CMAKE_STATIC_LIBRARY_SUFFIX}")
# Starting from 0.7.0, all platforms uses the suffix "d" for debug.
# See https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt#L141
if(BUILD_TYPE_DEBUG)
@@ -127,42 +136,37 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(yaml-cpp
REQUIRED_VARS
REQUIRED_VARS
${_yaml-cpp_REQUIRED_VARS}
VERSION_VAR
yaml-cpp_VERSION
)
endif()
###############################################################################
### Create target
if(yaml-cpp_FOUND AND NOT TARGET yaml-cpp)
add_library(yaml-cpp UNKNOWN IMPORTED GLOBAL)
set(_yaml-cpp_TARGET_CREATE TRUE)
endif()
###############################################################################
### Configure target ###
if(_yaml-cpp_TARGET_CREATE)
set_target_properties(yaml-cpp PROPERTIES
IMPORTED_LOCATION ${yaml-cpp_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${yaml-cpp_INCLUDE_DIR}
)
mark_as_advanced(yaml-cpp_INCLUDE_DIR yaml-cpp_LIBRARY yaml-cpp_VERSION)
endif()
###############################################################################
### Set variables for compatibility ###
### Create target
if(TARGET yaml-cpp AND NOT TARGET yaml-cpp::yaml-cpp)
add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp)
endif()
if (yaml-cpp_FOUND AND NOT TARGET yaml-cpp::yaml-cpp)
add_library(yaml-cpp::yaml-cpp UNKNOWN IMPORTED GLOBAL)
set_target_properties(yaml-cpp::yaml-cpp PROPERTIES
IMPORTED_LOCATION ${yaml-cpp_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${yaml-cpp_INCLUDE_DIR}
)
if(yaml-cpp_INCLUDE_DIR)
set(YAML_CPP_INCLUDE_DIR "${yaml-cpp_INCLUDE_DIR}")
endif()
# Required because Installyaml-cpp.cmake creates `yaml-cpp::yaml-cpp`
# as an alias, and aliases get resolved in exported targets, causing the
# find_dependency(yaml-cpp) call in OpenColorIOConfig.cmake to fail.
# This can be removed once Installyaml-cpp.cmake targets yaml-cpp 0.8.
if (NOT TARGET yaml-cpp)
add_library(yaml-cpp ALIAS yaml-cpp::yaml-cpp)
endif ()
endif ()
set(YAML_CPP_LIBRARIES yaml-cpp::yaml-cpp)
if (yaml-cpp_FOUND)
# TODO: Remove this variable and use the `yaml-cpp::yaml-cpp` target
# directly when the minimum version of yaml-cpp is updated to 0.8.
get_target_property(YAML_CPP_INCLUDE_DIR yaml-cpp::yaml-cpp INCLUDE_DIRECTORIES)
set(YAML_CPP_LIBRARIES yaml-cpp::yaml-cpp)
endif ()
@@ -110,7 +110,7 @@ if(NOT OpenEXR_FOUND AND OCIO_INSTALL_EXT_PACKAGES AND NOT OCIO_INSTALL_EXT_PACK
-DBUILD_SHARED_LIBS=OFF
-DBUILD_TESTING=OFF
-DOPENEXR_INSTALL_EXAMPLES=OFF
-DOPENEXR_INSTALL_TOOLS=OFF
-DOPENEXR_BUILD_TOOLS=OFF
# Try to use in-source built Imath first, if available.
-DCMAKE_PREFIX_PATH=${_EXT_DIST_ROOT}
)
@@ -38,7 +38,7 @@ if(NOT pystring_FOUND AND OCIO_INSTALL_EXT_PACKAGES AND NOT OCIO_INSTALL_EXT_PAC
else()
set(pystring_VERSION ${pystring_FIND_VERSION})
endif()
set(pystring_INCLUDE_DIR "${_EXT_DIST_ROOT}/${CMAKE_INSTALL_INCLUDEDIR}")
set(pystring_INCLUDE_DIR "${_EXT_DIST_ROOT}/${CMAKE_INSTALL_INCLUDEDIR}/pystring")
set(pystring_LIBRARY
"${_EXT_DIST_ROOT}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}pystring${CMAKE_STATIC_LIBRARY_SUFFIX}")
@@ -21,8 +21,8 @@
###############################################################################
### Create target (if previous 'find_package' call hasn't) ###
if(NOT TARGET yaml-cpp)
add_library(yaml-cpp UNKNOWN IMPORTED GLOBAL)
if(NOT TARGET yaml-cpp::yaml-cpp)
add_library(yaml-cpp::yaml-cpp UNKNOWN IMPORTED GLOBAL)
set(_yaml-cpp_TARGET_CREATE TRUE)
endif()
@@ -138,7 +138,7 @@ if(NOT yaml-cpp_FOUND AND OCIO_INSTALL_EXT_PACKAGES AND NOT OCIO_INSTALL_EXT_PAC
--parallel
)
add_dependencies(yaml-cpp yaml-cpp_install)
add_dependencies(yaml-cpp::yaml-cpp yaml-cpp_install)
if(OCIO_VERBOSE)
message(STATUS "Installing yaml-cpp: ${yaml-cpp_LIBRARY} (version \"${yaml-cpp_VERSION}\")")
endif()
@@ -149,7 +149,7 @@ endif()
### Configure target ###
if(_yaml-cpp_TARGET_CREATE)
set_target_properties(yaml-cpp PROPERTIES
set_target_properties(yaml-cpp::yaml-cpp PROPERTIES
IMPORTED_LOCATION ${yaml-cpp_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${yaml-cpp_INCLUDE_DIR}
)
@@ -157,15 +157,5 @@ if(_yaml-cpp_TARGET_CREATE)
mark_as_advanced(yaml-cpp_INCLUDE_DIR yaml-cpp_LIBRARY yaml-cpp_VERSION)
endif()
###############################################################################
### Set variables for compatibility ###
if(TARGET yaml-cpp AND NOT TARGET yaml-cpp::yaml-cpp)
add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp)
endif()
if(yaml-cpp_INCLUDE_DIR)
set(YAML_CPP_INCLUDE_DIR "${yaml-cpp_INCLUDE_DIR}")
endif()
set(YAML_CPP_INCLUDE_DIR "${yaml-cpp_INCLUDE_DIR}")
set(YAML_CPP_LIBRARIES yaml-cpp::yaml-cpp)
+1 -1
View File
@@ -59,7 +59,7 @@ else()
message(STATUS "Performing Test COMPILER_SUPPORTS_SSE2 - Failed")
endif()
set(CMAKE_REQUIRED_FLAGS "${_cmake_cxx_flags_orig}")
set(CMAKE_CXX_FLAGS "${_cmake_cxx_flags_orig}")
unset(_cmake_cxx_flags_orig)
if(__universal_build)
+2 -2
View File
@@ -107,8 +107,8 @@ if(USE_GCC OR USE_CLANG)
endif()
if(OCIO_ENABLE_SANITIZER)
set(PLATFORM_COMPILE_OPTIONS "${PLATFORM_COMPILE_OPTIONS};-fno-omit-frame-pointer;-fsanitize=address")
set(PLATFORM_LINK_OPTIONS "${PLATFORM_LINK_OPTIONS};-fsanitize=address")
set(PLATFORM_COMPILE_OPTIONS "${PLATFORM_COMPILE_OPTIONS};-fno-omit-frame-pointer;-fsanitize=address;-fsanitize=undefined")
set(PLATFORM_LINK_OPTIONS "${PLATFORM_LINK_OPTIONS};-fsanitize=address;-fsanitize=undefined")
endif()
endif()
-1
View File
@@ -9,7 +9,6 @@
#if OCIO_USE_AVX
#include <immintrin.h>
#include <stdio.h>
#include <OpenColorIO/OpenColorIO.h>
#include "BitDepthUtils.h"
-1
View File
@@ -9,7 +9,6 @@
#if OCIO_USE_AVX2
#include <immintrin.h>
#include <stdio.h>
#include <OpenColorIO/OpenColorIO.h>
#include "BitDepthUtils.h"
+1 -1
View File
@@ -389,7 +389,7 @@ elseif(APPLE)
# Check for minizip first since our Findminizip module sets minizip-ng_LIBRARY.
if (minizip_LIBRARY)
if (minizip_LIBRARY OR minizip-ng_COMPAT)
get_filename_component(_minizip-ng_LIBDIR "${minizip_LIBRARY}" DIRECTORY)
set(_minizip-ng_NAME "minizip")
elseif(minizip-ng_LIBRARY)
+7
View File
@@ -50,6 +50,13 @@ static inline void cpuid(int index, int *data)
{
#if _MSC_VER
__cpuid(data, index);
#elif OCIO_ARCH_X86_32
__asm__ volatile (
"mov %%ebx, %%esi \n\t"
"cpuid \n\t"
"xchg %%ebx, %%esi"
: "=a" (data[0]), "=S" (data[1]), "=c" (data[2]), "=d" (data[3])
: "0" (index), "2"(0));
#else
__asm__ volatile (
"mov %%rbx, %%rsi \n\t"
+3
View File
@@ -3,10 +3,13 @@
#cmakedefine01 OCIO_ARCH_X86
#cmakedefine01 OCIO_ARCH_X86_32
// Relevant only for arm64 architecture.
#if defined(__aarch64__)
#cmakedefine01 OCIO_USE_SSE2NEON
#else
#define OCIO_USE_SSE2NEON 0
#endif
// On the Apple platform, a universal build is created for both x86_64 and arm64 architectures.
+36 -5
View File
@@ -12,6 +12,8 @@
#include <regex>
#include <functional>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "builtinconfigs/BuiltinConfigRegistry.h"
@@ -34,7 +36,6 @@
#include "Platform.h"
#include "PrivateTypes.h"
#include "Processor.h"
#include "pystring/pystring.h"
#include "transforms/FileTransform.h"
#include "utils/StringUtils.h"
#include "ViewingRules.h"
@@ -435,7 +436,7 @@ public:
{
m_viewTransforms.push_back(vt->createEditableCopy());
}
m_defaultViewTransform = rhs.m_defaultViewTransform;
m_defaultLumaCoefs = rhs.m_defaultLumaCoefs;
m_strictParsing = rhs.m_strictParsing;
@@ -2821,6 +2822,23 @@ bool Config::isColorSpaceLinear(const char * colorSpace, ReferenceSpaceType refe
auto procToReference = config.getImpl()->getProcessorWithoutCaching(
config, t, TRANSFORM_DIR_FORWARD
);
// TODO: It could be useful to try and avoid evaluating points through ops that are
// expensive but highly unlikely to be linear (with inverse Lut3D being the prime example).
// There are some heuristics that are used in ConfigUtils.cpp that are intended to filter
// out color spaces from consideration before a processor is even calculated. However,
// those are not entirely appropriate here since one could imagine wanting to know if a
// color space involving a FileTransform (an ASC CDL being a good example) is linear.
// Likewise, one might want to know whether a color space involving a Look or ColorSpace
// Transform is linear (both of those are filtered out by the ConfigUtils heuristics).
// It seems like the right approach here is to go ahead and build the processor and
// thereby convert File/Look/ColorSpace Transforms into ops. But currently there is
// no method on the Processor class to know if it contains a Lut3D. There is the
// ProcessorMetadata files list, though that is not as precise. For example, it would
// not say if a CLF or CTF file contains a Lut3D or just a matrix. Probably the best
// solution would be to have each op sub-class provide an isLinear method and then
// surface that on the Processor class, iterating over each op in the Processor.
auto optCPUProc = procToReference->getOptimizedCPUProcessor(OPTIMIZATION_NONE);
optCPUProc->apply(desc, descDst);
@@ -4100,6 +4118,10 @@ void Config::addLook(const ConstLookRcPtr & look)
if(StringUtils::Lower(getImpl()->m_looksList[i]->getName()) == namelower)
{
getImpl()->m_looksList[i] = look->createEditableCopy();
AutoMutex lock(getImpl()->m_cacheidMutex);
getImpl()->resetCacheIDs();
return;
}
}
@@ -4715,20 +4737,29 @@ ConstProcessorRcPtr Config::GetProcessorFromConfigs(const ConstContextRcPtr & sr
"the source color space.");
}
const char* csName = dstConfig->getDisplayViewColorSpaceName(dstDisplay, dstView);
const char* displayColorSpaceName = View::UseDisplayName(csName) ? dstDisplay : csName;
ConstColorSpaceRcPtr displayColorSpace = dstConfig->getColorSpace(displayColorSpaceName);
if (!displayColorSpace)
{
throw Exception("Can't create the processor for the destination config: "
"display color space not found.");
}
auto p2 = dstConfig->getProcessor(dstContext, dstInterchangeName, dstDisplay, dstView, direction);
if (!p2)
{
throw Exception("Can't create the processor for the destination config "
"and the destination color space.");
"and the destination display view transform.");
}
ProcessorRcPtr processor = Processor::Create();
processor->getImpl()->setProcessorCacheFlags(srcConfig->getImpl()->m_cacheFlags);
// If the source color spaces is a data space, its corresponding processor
// If either of the color spaces are data spaces, its corresponding processor
// will be empty, but need to make sure the entire result is also empty to
// better match the semantics of how data spaces are handled.
if (!srcColorSpace->isData())
if (!srcColorSpace->isData() && !displayColorSpace->isData())
{
if (direction == TRANSFORM_DIR_INVERSE)
{
+202 -37
View File
@@ -3,6 +3,7 @@
#include "ConfigUtils.h"
#include "MathUtils.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
namespace OCIO_NAMESPACE
@@ -165,7 +166,7 @@ bool GetInterchangeRolesForColorSpaceConversion(const char ** srcInterchangeCSNa
// Return true if the color space name or its aliases contains sRGB (case-insensitive).
//
bool containsSRGB(ConstColorSpaceRcPtr & cs)
bool containsSRGB(const ConstColorSpaceRcPtr & cs)
{
std::string name = StringUtils::Lower(cs->getName());
if (StringUtils::Find(name, "srgb") != std::string::npos)
@@ -223,10 +224,31 @@ const char * getRefSpaceName(const ConstConfigRcPtr & cfg)
return "";
}
// Find the first scene-referred color space with isdata: true.
//
const char * getDataSpaceName(const ConstConfigRcPtr & cfg)
{
int nbCs = cfg->getNumColorSpaces(SEARCH_REFERENCE_SPACE_SCENE, COLORSPACE_ALL);
for (int i = 0; i < nbCs; i++)
{
const char * csname = cfg->getColorSpaceNameByIndex(SEARCH_REFERENCE_SPACE_SCENE,
COLORSPACE_ALL,
i);
ConstColorSpaceRcPtr cs = cfg->getColorSpace(csname);
if (cs->isData())
{
return csname;
}
}
return "";
}
// Return false if the supplied Processor modifies any of the supplied float values
// by more than the supplied absolute tolerance amount.
//
bool isIdentityTransform(ConstProcessorRcPtr proc,
bool isIdentityTransform(const ConstProcessorRcPtr & proc,
std::vector<float> & RGBAvals,
float absTolerance)
{
@@ -249,28 +271,143 @@ bool isIdentityTransform(ConstProcessorRcPtr proc,
return true;
}
// Helper to avoid color spaces that are without transforms or are data spaces.
// Determine whether a Processor contains a MatrixTransform with off-diagonal coefficients.
//
bool hasNoTransform(const ConstColorSpaceRcPtr & cs)
bool hasNonTrivialMatrixTransform(const ConstProcessorRcPtr & proc)
{
GroupTransformRcPtr gt = proc->createGroupTransform();
// The result of createGroupTransform only contains transforms that correspond to ops,
// in other words, there are no complex transforms such as File, Builtin, or ColorSpace,
// and the only GroupTransform is the enclosing one.
for (int i = 0; i < gt->getNumTransforms(); ++i)
{
ConstTransformRcPtr transform = gt->getTransform(i);
if (transform->getTransformType() == TRANSFORM_TYPE_MATRIX)
{
// Check that there is a significant off-diagonal coefficient in the matrix.
// This is to avoid matrices that are not actual color primary conversions,
// for example, the scale and offset that are sometimes prepended to a Lut1D.
ConstMatrixTransformRcPtr mtx = DynamicPtrCast<const MatrixTransform>(transform);
double values[16];
mtx->getMatrix(values);
for (int j = 0; j < 3 ; ++j) // only checking rgb, not alpha
{
for (int k = 0; k < 3 ; ++k) // only checking rgb, not alpha
{
if (j != k)
{
if (std::abs(values[j * 4 + k]) > 0.1)
{
return true;
}
}
}
}
}
}
return false;
}
// Determine if the transform contains a type that is inappropriate for the heuristics.
//
bool containsBlockedTransform(const ConstTransformRcPtr & transform)
{
// If it's a GroupTransform, need to recurse into it to check the contents.
if (transform->getTransformType() == TRANSFORM_TYPE_GROUP)
{
ConstGroupTransformRcPtr gt = DynamicPtrCast<const GroupTransform>(transform);
for (int i = 0; i < gt->getNumTransforms(); ++i)
{
ConstTransformRcPtr tr = gt->getTransform(i);
if (containsBlockedTransform(tr))
{
return true;
}
}
}
// Prevent FileTransforms from being used, except for spi1d and spimtx since these
// may be used with OCIO v1 configs to implement the type of color spaces the heuristics
// are designed to look for. (E.g. The sRGB Texture space in the legacy ACES configs.)
else if (transform->getTransformType() == TRANSFORM_TYPE_FILE)
{
ConstFileTransformRcPtr ft = DynamicPtrCast<const FileTransform>(transform);
std::string filepath = ft->getSrc();
std::string root, extension;
pystring::os::path::splitext(root, extension, filepath);
extension = StringUtils::Lower(extension);
if (extension != ".spi1d" && extension != ".spimtx")
{
return true;
}
}
// Prevent transforms that may be hiding a FileTransform.
else if (transform->getTransformType() == TRANSFORM_TYPE_COLORSPACE
|| transform->getTransformType() == TRANSFORM_TYPE_DISPLAY_VIEW
|| transform->getTransformType() == TRANSFORM_TYPE_LOOK)
{
return true;
}
// Putting this here since Lut3D is the main type of transform to avoid,
// however given that the input transform comes directly from a color space
// and has not been converted to a processor yet, it should never actually
// have a transform of this type (it would still be a FileTransform).
else if (transform->getTransformType() == TRANSFORM_TYPE_LUT3D)
{
return true;
}
return false;
}
// Look at the to_ref/from_ref transforms in the color space and exclude color spaces
// that are probably not what the heuristics are looking for and could be prohibitively
// expensive to fully check.
//
// Because this check is done before a processor is built, it is inexpensive but it may
// be inaccurate. In other words, it's possible that this check will exclude some
// reasonable color spaces, but that's better than trying to invert 3d-LUTs, etc.
//
// cs -- Color space object to check.
// refSpaceType -- Exclude if the color space is not of the same reference space type.
// blockRefSpaces -- Exclude the color space if it does not have any transforms.
//
bool excludeColorSpaceFromHeuristics(const ConstColorSpaceRcPtr & cs,
ReferenceSpaceType refSpaceType,
bool blockRefSpaces)
{
if (cs->isData())
{
return true;
}
ConstTransformRcPtr srcTransform = cs->getTransform(COLORSPACE_DIR_TO_REFERENCE);
if (!srcTransform)
if (cs->getReferenceSpaceType() != refSpaceType)
{
srcTransform = cs->getTransform(COLORSPACE_DIR_FROM_REFERENCE);
if (srcTransform)
{
return false;
}
else
{
return true;
}
return true;
}
ConstTransformRcPtr transform = cs->getTransform(COLORSPACE_DIR_TO_REFERENCE);
if (transform)
{
// The to_ref transform is what the heuristics try to use first, so if that
// does not contain problematic transforms, it's ok to proceed without checking
// the from_ref transform.
return containsBlockedTransform(transform);
}
// There is no to_ref transform, check if the from_ref is present.
transform = cs->getTransform(COLORSPACE_DIR_FROM_REFERENCE);
if (transform)
{
return containsBlockedTransform(transform);
}
// Color space contains no transforms (it's a reference space).
else
{
return blockRefSpaces;
}
return false;
}
// Test the supplied color space against a set of color spaces in the built-in config.
@@ -288,17 +425,6 @@ int getReferenceSpaceFromLinearSpace(const ConstConfigRcPtr & srcConfig,
const ConstColorSpaceRcPtr & cs,
const ConstConfigRcPtr & builtinConfig)
{
// Currently only handling scene-referred spaces in the heuristics.
if (cs->getReferenceSpaceType() == REFERENCE_SPACE_DISPLAY)
{
return -1;
}
// Don't check spaces without transforms / data spaces.
if (hasNoTransform(cs))
{
return -1;
}
// Define a set of (somewhat arbitrary) RGB values to test whether the combined transform is
// enough of an identity.
std::vector<float> vals = { 0.7f, 0.4f, 0.02f, 0.f,
@@ -353,14 +479,9 @@ int getReferenceSpaceFromLinearSpace(const ConstConfigRcPtr & srcConfig,
//
int getReferenceSpaceFromSRGBSpace(const ConstConfigRcPtr & srcConfig,
const char * srcRefName,
const ConstColorSpaceRcPtr cs,
const ConstColorSpaceRcPtr & cs,
const ConstConfigRcPtr & builtinConfig)
{
// Currently only handling scene-referred spaces in the heuristics.
if (cs->getReferenceSpaceType() == REFERENCE_SPACE_DISPLAY)
{
return -1;
}
// Get a transform in the to-reference direction.
ConstTransformRcPtr toRefTransform;
ConstTransformRcPtr ctransform = cs->getTransform(COLORSPACE_DIR_TO_REFERENCE);
@@ -405,6 +526,18 @@ int getReferenceSpaceFromSRGBSpace(const ConstConfigRcPtr & srcConfig,
ConstProcessorRcPtr proc = srcConfig->getProcessor(toRefTransform, TRANSFORM_DIR_FORWARD);
// Ensure that the color space is not only an sRGB curve, it needs to have a color matrix
// too or else the last step below could succeed by pairing the built-in sRGB space with
// a linear space that cancels out the matrix in the built-in sRGB space.
// NB: This is being done after the getProcessor call rather than simply looking at
// the raw color space transform contents since once it becomes a processor, the complex
// transforms (e.g. File, ColorSpace, Builtins) that could be hiding a matrix are
// converted into ops.
if (!hasNonTrivialMatrixTransform(proc))
{
return -1;
}
ConstCPUProcessorRcPtr cpu = proc->getOptimizedCPUProcessor(OPTIMIZATION_NONE);
// Convert the non-linear values to linear.
cpu->apply(desc, descDst);
@@ -422,6 +555,7 @@ int getReferenceSpaceFromSRGBSpace(const ConstConfigRcPtr & srcConfig,
out[i] = 1.055f * std::pow(out[i], 1.f / 2.4f) - 0.055f;
}
// Compare against the original source values.
// (This assumes equal channel sRGB values remain so in the reference space of src config.)
if (!EqualWithAbsError(vals[i], out[i], 1e-3f))
{
return -1;
@@ -442,6 +576,8 @@ int getReferenceSpaceFromSRGBSpace(const ConstConfigRcPtr & srcConfig,
// sRGB texture space. If the result is an identity, then that tells what the source config
// reference space is.
// At this point, cs has the expected non-linearity and a non-trivial matrix to its reference space.
// Now try to identify the matrix.
for (int i = 0; i < getNumberOfbuiltinLinearSpaces(); i++)
{
ConstProcessorRcPtr proc = Config::GetProcessorFromConfigs(srcConfig,
@@ -511,7 +647,7 @@ void IdentifyInterchangeSpace(const char ** srcInterchange,
// Identify the name of a reference space in the source config.
*srcInterchange = getRefSpaceName(srcConfig);
if (!*srcInterchange)
if (!**srcInterchange)
{
std::ostringstream os;
os << "The supplied config does not have a color space for the reference.";
@@ -531,8 +667,16 @@ void IdentifyInterchangeSpace(const char ** srcInterchange,
for (int i = 0; i < nbCs; i++)
{
ConstColorSpaceRcPtr cs = srcConfig->getColorSpace(srcConfig->getColorSpaceNameByIndex(i));
if (containsSRGB(cs))
{
// Exclude color spaces that may be too expensive to test or otherwise inappropriate.
// Currently only handling scene-referred spaces in the heuristics.
if (excludeColorSpaceFromHeuristics(cs, REFERENCE_SPACE_SCENE, true))
{
continue;
}
refColorSpacePrimsIndex = getReferenceSpaceFromSRGBSpace(srcConfig,
*srcInterchange,
cs,
@@ -549,6 +693,14 @@ void IdentifyInterchangeSpace(const char ** srcInterchange,
for (int i = 0; i < nbCs; i++)
{
ConstColorSpaceRcPtr cs = srcConfig->getColorSpace(srcConfig->getColorSpaceNameByIndex(i));
// Exclude color spaces that may be too expensive to test or otherwise inappropriate.
// Currently only handling scene-referred spaces in the heuristics.
if (excludeColorSpaceFromHeuristics(cs, REFERENCE_SPACE_SCENE, true))
{
continue;
}
if (srcConfig->isColorSpaceLinear(cs->getName(), REFERENCE_SPACE_SCENE))
{
refColorSpacePrimsIndex = getReferenceSpaceFromLinearSpace(srcConfig,
@@ -602,6 +754,18 @@ const char * IdentifyBuiltinColorSpace(const ConstConfigRcPtr & srcConfig,
throw Exception(os.str().c_str());
}
if (builtinColorSpace->isData())
{
const char * dataName = getDataSpaceName(srcConfig);
if (!*dataName)
{
std::ostringstream os;
os << "The requested space is a data space but the supplied config does not have a data space.";
throw Exception(os.str().c_str());
}
return dataName;
}
ReferenceSpaceType builtinRefSpaceType = builtinColorSpace->getReferenceSpaceType();
// Identify interchange spaces. Passing an empty string for the source color space
@@ -633,8 +797,8 @@ const char * IdentifyBuiltinColorSpace(const ConstConfigRcPtr & srcConfig,
0.f, 0.f, 0.f, 0.f,
1.f, 1.f, 1.f, 0.f };
// Loop over each non-data color space in the source config and test if the conversion to
// the specified space in the built-in config is an identity.
// Loop over the active, non-excluded, color spaces in the source config and test if the
// conversion to the specified space in the built-in config is an identity.
//
// Note that there is a possibility that both the source and built-in sides of the
// transform could be an identity (e.g., if the user asks for ACES2065-1 and that is
@@ -646,7 +810,8 @@ const char * IdentifyBuiltinColorSpace(const ConstConfigRcPtr & srcConfig,
for (int i = 0; i < nbCs; i++)
{
ConstColorSpaceRcPtr cs = srcConfig->getColorSpace(srcConfig->getColorSpaceNameByIndex(i));
if (cs->isData() || (cs->getReferenceSpaceType() != builtinRefSpaceType))
if (excludeColorSpaceFromHeuristics(cs, builtinRefSpaceType, false))
{
continue;
}
+2 -1
View File
@@ -7,6 +7,8 @@
#include <sstream>
#include <string>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "ContextVariableUtils.h"
@@ -15,7 +17,6 @@
#include "OCIOZArchive.h"
#include "PathUtils.h"
#include "PrivateTypes.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
namespace OCIO_NAMESPACE
+4 -3
View File
@@ -4,6 +4,8 @@
#include <cstring>
#include <unordered_set>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Display.h"
@@ -19,7 +21,6 @@
#include "ParseUtils.h"
#include "PathUtils.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
#include "ViewingRules.h"
#include "yaml-cpp/yaml.h"
@@ -4737,9 +4738,9 @@ inline void save(YAML::Emitter & out, const Config & config)
out << YAML::Newline;
out << YAML::Newline;
if (configMajorVersion >= 2)
if (configMajorVersion >= 2 || config.getNumEnvironmentVars() > 0)
{
// Print the environment even if empty.
// For v2 configs, write the environment section, even if empty.
out << YAML::Key << "environment";
out << YAML::Value << YAML::BeginMap;
for(int i = 0; i < config.getNumEnvironmentVars(); ++i)
+3 -2
View File
@@ -8,10 +8,12 @@
#include <set>
#include <limits>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Mutex.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
#include "transforms/FileTransform.h"
@@ -24,7 +26,6 @@
#include "mz_strm_mem.h"
#include "mz_strm_os.h"
#include "mz_strm_split.h"
#include "mz_strm_zlib.h"
#include "mz_zip.h"
#include "mz_zip_rw.h"
+2 -1
View File
@@ -4,6 +4,8 @@
#include <cstring>
#include <sstream>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Logging.h"
@@ -20,7 +22,6 @@
#include "ops/lut1d/Lut1DOp.h"
#include "ops/lut3d/Lut3DOp.h"
#include "ops/range/RangeOp.h"
#include "pystring/pystring.h"
namespace OCIO_NAMESPACE
{
+2 -2
View File
@@ -5,12 +5,13 @@
#include <iostream>
#include <map>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Mutex.h"
#include "PathUtils.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
#include "OCIOZArchive.h"
@@ -218,4 +219,3 @@ int ParseColorSpaceFromString(const Config & config, const char * str)
}
} // namespace OCIO_NAMESPACE
+35 -5
View File
@@ -18,8 +18,6 @@
#endif
#endif
#include <stdio.h>
#include <OpenColorIO/OpenColorIO.h>
#include "BitDepthUtils.h"
@@ -76,6 +74,8 @@ static inline void sse2RGBATranspose_4x4(__m128 row0, __m128 row1, __m128 row2,
out_a = _mm_movehl_ps(tmp3, tmp1);
}
#if !OCIO_USE_SSE2NEON
static inline __m128i sse2_blendv(__m128i a, __m128i b, __m128i mask)
{
return _mm_xor_si128(_mm_and_si128(_mm_xor_si128(a, b), mask), a);
@@ -164,6 +164,8 @@ static inline __m128 sse2_cvtph_ps(__m128i a)
return _mm_or_ps(o, sign);
}
#endif
// Note Packing functions perform no 0.0 - 1.0 normalization
// but perform 0 - max value clamping for integer formats
template<BitDepth BD> struct SSE2RGBAPack {};
@@ -290,21 +292,48 @@ struct SSE2RGBAPack<BIT_DEPTH_F16>
__m128i rgba_00_01 = _mm_loadu_si128((const __m128i*)(in + 0));
__m128i rgba_02_03 = _mm_loadu_si128((const __m128i*)(in + 8));
#if OCIO_USE_SSE2NEON
// use neon hardware support for f16 to f32
__m128 rgba0 = vreinterpretq_m128_f32(
vcvt_f32_f16(vget_low_f16(vreinterpretq_f16_s64(vreinterpretq_s64_m128i(rgba_00_01))))
);
__m128 rgba1 = vreinterpretq_m128_f32(
vcvt_f32_f16(vget_high_f16(vreinterpretq_f16_s64(vreinterpretq_s64_m128i(rgba_00_01))))
);
__m128 rgba2 = vreinterpretq_m128_f32(
vcvt_f32_f16(vget_low_f16(vreinterpretq_f16_s64(vreinterpretq_s64_m128i(rgba_02_03))))
);
__m128 rgba3 = vreinterpretq_m128_f32(
vcvt_f32_f16(vget_high_f16(vreinterpretq_f16_s64(vreinterpretq_s64_m128i(rgba_02_03))))
);
#else
__m128 rgba0 = sse2_cvtph_ps(rgba_00_01);
__m128 rgba1 = sse2_cvtph_ps(_mm_shuffle_epi32(rgba_00_01, _MM_SHUFFLE(1,0,3,2)));
__m128 rgba2 = sse2_cvtph_ps(rgba_02_03);
__m128 rgba3 = sse2_cvtph_ps(_mm_shuffle_epi32(rgba_02_03, _MM_SHUFFLE(1,0,3,2)));
#endif
sse2RGBATranspose_4x4(rgba0, rgba1, rgba2, rgba3, r, g, b, a);
}
static inline void Store(half *out, __m128 r, __m128 g, __m128 b, __m128 a)
{
__m128 rgba0, rgba1, rgba2, rgba3;
__m128i rgba;
sse2RGBATranspose_4x4(r, g, b, a, rgba0, rgba1, rgba2, rgba3);
#if OCIO_USE_SSE2NEON
// use neon hardware support for f32 to f16
float16x8_t rgba;
float16x4_t rgba00_01 = vcvt_f16_f32(vreinterpretq_f32_m128(rgba0));
float16x4_t rgba03_03 = vcvt_f16_f32(vreinterpretq_f32_m128(rgba1));
float16x4_t rgba04_05 = vcvt_f16_f32(vreinterpretq_f32_m128(rgba2));
float16x4_t rgba06_07 = vcvt_f16_f32(vreinterpretq_f32_m128(rgba3));
rgba = vcombine_f16(rgba00_01, rgba03_03);
vst1q_f16((float16_t *)(out+0), rgba);
rgba = vcombine_f16(rgba04_05, rgba06_07);
vst1q_f16((float16_t *)(out+8), rgba);
#else
__m128i rgba;
__m128i rgba00_01 = sse2_cvtps_ph(rgba0);
__m128i rgba02_03 = sse2_cvtps_ph(rgba1);
__m128i rgba04_05 = sse2_cvtps_ph(rgba2);
@@ -315,6 +344,7 @@ struct SSE2RGBAPack<BIT_DEPTH_F16>
rgba = _mm_xor_si128(rgba04_05, _mm_shuffle_epi32(rgba06_07, _MM_SHUFFLE(1,0,3,2)));
_mm_storeu_si128((__m128i*)(out+8), rgba);
#endif
}
};
@@ -217,7 +217,7 @@ void LocalFileFormat::buildFileOps(OpRcPtrVec & ops,
{
// Use 0 for empty string.
int cccindex=0;
if (StringToInt(&cccindex, cccid.c_str(), true))
if (cccid.empty() || StringToInt(&cccindex, cccid.c_str(), true))
{
int maxindex = ((int)cachedFile->m_transformVec.size())-1;
if (cccindex<0 || cccindex>maxindex)
@@ -247,7 +247,7 @@ LocalFileFormat::buildFileOps(OpRcPtrVec & ops,
{
// Use 0 for empty string.
int cccindex=0;
if (StringToInt(&cccindex, cccid.c_str(), true))
if (cccid.empty() || StringToInt(&cccindex, cccid.c_str(), true))
{
int maxindex = ((int)cachedFile->m_transformVec.size())-1;
if (cccindex<0 || cccindex>maxindex)
@@ -274,7 +274,7 @@ LocalFileFormat::buildFileOps(OpRcPtrVec & ops,
if (!success)
{
std::ostringstream os;
os << "You must specify a valid cccid to load from the ccc file";
os << "You must specify a valid cccid to load from the cdl file";
os << " (either by name or index). id='" << cccid << "' ";
os << "is not found in the file, and is not parsable as an ";
os << "integer index.";
@@ -6,6 +6,8 @@
#include <fstream>
#include <sstream>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "expat.h"
@@ -23,7 +25,6 @@
#include "OpBuilders.h"
#include "ops/noop/NoOps.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "TransformBuilder.h"
#include "transforms/FileTransform.h"
#include "utils/StringUtils.h"
@@ -8,6 +8,8 @@
#include <sstream>
#include <iostream>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "BitDepthUtils.h"
@@ -16,7 +18,6 @@
#include "ops/lut1d/Lut1DOp.h"
#include "ops/lut3d/Lut3DOp.h"
#include "ParseUtils.h"
#include "pystring/pystring.h"
#include "Platform.h"
#include "transforms/FileTransform.h"
#include "utils/StringUtils.h"
@@ -771,4 +772,3 @@ FileFormat * CreateFileFormatDiscreet1DL()
}
} // namespace OCIO_NAMESPACE
@@ -5,6 +5,8 @@
#include <sstream>
#include <fstream>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Logging.h"
@@ -15,7 +17,6 @@
#include "ops/matrix/MatrixOp.h"
#include "ops/range/RangeOp.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "transforms/FileTransform.h"
@@ -5,6 +5,8 @@
#include <cstring>
#include <iterator>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "expat.h"
@@ -13,7 +15,6 @@
#include "ops/lut3d/Lut3DOp.h"
#include "ParseUtils.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "transforms/FileTransform.h"
#include "utils/StringUtils.h"
#include "utils/NumberUtils.h"
@@ -579,4 +580,3 @@ FileFormat * CreateFileFormatIridasLook()
}
} // namespace OCIO_NAMESPACE
@@ -24,13 +24,23 @@ namespace {
static inline __m128 fmadd_ps_sse2(__m128 a, __m128 b, __m128 c)
{
#if OCIO_USE_SSE2NEON
return vreinterpretq_m128_f32(
vfmaq_f32(vreinterpretq_f32_m128(c), vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))
);
#else
return _mm_add_ps(_mm_mul_ps(a, b), c);
#endif
}
static inline __m128 floor_ps_sse2(__m128 v)
{
#if OCIO_USE_SSE2NEON
return _mm_floor_ps(v);
#else
// NOTE: using truncate cvtt
return _mm_cvtepi32_ps(_mm_cvttps_epi32(v));
#endif
}
@@ -38,18 +38,32 @@ struct rgbavec_sse2 {
static inline __m128 floor_ps_sse2(__m128 v)
{
#if OCIO_USE_SSE2NEON
return _mm_floor_ps(v);
#else
// NOTE: using truncate cvtt
return _mm_cvtepi32_ps(_mm_cvttps_epi32(v));
#endif
}
static inline __m128 blendv_ps_sse2(__m128 a, __m128 b, __m128 mask)
{
#if OCIO_USE_SSE2NEON
return _mm_blendv_ps(a, b, mask);
#else
return _mm_xor_ps(_mm_and_ps(_mm_xor_ps(a, b), mask), a);
#endif
}
static inline __m128 fmadd_ps_sse2(__m128 a, __m128 b, __m128 c)
{
#if OCIO_USE_SSE2NEON
return vreinterpretq_m128_f32(
vfmaq_f32(vreinterpretq_f32_m128(c), vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))
);
#else
return _mm_add_ps(_mm_mul_ps(a, b), c);
#endif
}
static inline rgbavec_sse2 interp_tetrahedral_sse2(const Lut3DContextSSE2 &ctx, __m128 r, __m128 g, __m128 b, __m128 a)
@@ -184,7 +184,7 @@ void BuildColorSpaceOps(OpRcPtrVec & ops,
if (!src)
{
srcNamedTransform = config.getNamedTransform(srcName.c_str());
srcNamedTransform = config.getNamedTransform( context->resolveStringVar(srcName.c_str()) );
if (!srcNamedTransform)
{
ThrowMissingCS(srcName.c_str());
@@ -192,7 +192,7 @@ void BuildColorSpaceOps(OpRcPtrVec & ops,
}
if (!dst)
{
dstNamedTransform = config.getNamedTransform(dstName.c_str());
dstNamedTransform = config.getNamedTransform( context->resolveStringVar(dstName.c_str()) );
if (!dstNamedTransform)
{
ThrowMissingCS(dstName.c_str());
@@ -393,6 +393,31 @@ void BuildReferenceConversionOps(OpRcPtrVec & ops,
}
}
bool CollectContextVariables(const Config & config,
const Context & context,
ConstNamedTransformRcPtr & nt,
ContextRcPtr & usedContextVars)
{
bool foundContextVars = false;
if (nt)
{
ConstTransformRcPtr to = nt->getTransform(TRANSFORM_DIR_FORWARD);
if (to && CollectContextVariables(config, context, to, usedContextVars))
{
foundContextVars = true;
}
ConstTransformRcPtr from = nt->getTransform(TRANSFORM_DIR_INVERSE);
if (from && CollectContextVariables(config, context, from, usedContextVars))
{
foundContextVars = true;
}
}
return foundContextVars;
}
bool CollectContextVariables(const Config & config,
const Context & context,
ConstColorSpaceRcPtr & cs,
@@ -441,15 +466,37 @@ bool CollectContextVariables(const Config & config,
}
ConstColorSpaceRcPtr src = config.getColorSpace(srcName.c_str());
if (CollectContextVariables(config, context, src, usedContextVars))
if (src)
{
foundContextVars = true;
if (CollectContextVariables(config, context, src, usedContextVars))
{
foundContextVars = true;
}
}
else
{
ConstNamedTransformRcPtr nt_src = config.getNamedTransform(srcName.c_str());
if (CollectContextVariables(config, context, nt_src, usedContextVars))
{
foundContextVars = true;
}
}
ConstColorSpaceRcPtr dst = config.getColorSpace(dstName.c_str());
if (CollectContextVariables(config, context, dst, usedContextVars))
if (dst)
{
foundContextVars = true;
if (CollectContextVariables(config, context, dst, usedContextVars))
{
foundContextVars = true;
}
}
else
{
ConstNamedTransformRcPtr nt_dst = config.getNamedTransform(dstName.c_str());
if (CollectContextVariables(config, context, nt_dst, usedContextVars))
{
foundContextVars = true;
}
}
return foundContextVars;
+2 -1
View File
@@ -9,6 +9,8 @@
#include <iostream>
#include <iterator>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Caching.h"
@@ -19,7 +21,6 @@
#include "ops/noop/NoOps.h"
#include "PathUtils.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
namespace OCIO_NAMESPACE
@@ -41,10 +41,10 @@ Dependencies
* PyOpenColorIO
* [OpenImageIO (Python bindings)](https://github.com/OpenImageIO/oiio)
* [Imath (Python bindings)](https://github.com/AcademySoftwareFoundation/Imath)
* ``pip install -r requirements.txt``
* [numpy](https://pypi.org/project/numpy/)
* [Pygments](https://pypi.org/project/Pygments/)
* [PyOpenGL](https://pypi.org/project/PyOpenGL/)
* [PySide2](https://pypi.org/project/PySide2/)
* [PySide6](https://pypi.org/project/PySide6/)
* [QtAwesome](https://pypi.org/project/QtAwesome/)
* [imageio](https://pypi.org/project/imageio/)
+4 -5
View File
@@ -7,7 +7,7 @@ import sys
from pathlib import Path
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets, QtOpenGL
from PySide6 import QtCore, QtGui, QtWidgets, QtOpenGL
import ocioview.log_handlers # Import to initialize logging
from ocioview.main_window import OCIOView
@@ -30,12 +30,11 @@ if __name__ == "__main__":
sys.excepthook = excepthook
# OpenGL core profile needed on macOS to access programmatic pipeline
gl_format = QtOpenGL.QGLFormat()
gl_format.setProfile(QtOpenGL.QGLFormat.CoreProfile)
gl_format.setSampleBuffers(True)
gl_format = QtGui.QSurfaceFormat()
gl_format.setProfile(QtGui.QSurfaceFormat.CoreProfile)
gl_format.setSwapInterval(1)
gl_format.setVersion(4, 0)
QtOpenGL.QGLFormat.setDefaultFormat(gl_format)
QtGui.QSurfaceFormat.setDefaultFormat(gl_format)
# Create app
app = QtWidgets.QApplication(sys.argv)
+1 -1
View File
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from .items import (
ColorSpaceEdit,
+1 -1
View File
@@ -3,7 +3,7 @@
from pathlib import Path
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
# Root application directory
@@ -6,7 +6,7 @@ from typing import Optional
import PyOpenColorIO as ocio
from pygments.formatters import HtmlFormatter
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..message_router import MessageRouter
from ..utils import get_glyph_icon, processor_to_shader_html
@@ -40,9 +40,9 @@ class CodeInspector(QtWidgets.QWidget):
html_css = HtmlFormatter(style="material").get_style_defs()
# Update line number colors to match palette
html_css = html_css.replace("#263238", palette.color(palette.Base).name())
html_css = html_css.replace("#263238", palette.color(palette.ColorRole.Base).name())
html_css = html_css.replace(
"#37474F", palette.color(palette.Text).darker(150).name()
"#37474F", palette.color(palette.ColorRole.Text).darker(150).name()
)
# Widgets
@@ -8,7 +8,7 @@ from typing import Optional
import numpy as np
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..constants import R_COLOR, G_COLOR, B_COLOR, GRAY_COLOR
from ..message_router import MessageRouter
@@ -17,11 +17,22 @@ from ..widgets import EnumComboBox, FloatEditArray, IntEdit
class SampleType(enum.Enum):
"""Enum of curve sampling types for representing OCIO transforms."""
LINEAR = "linear"
"""Linear scale."""
LOG = "log"
"""Log scale with a user-defined base."""
class CurveInspector(QtWidgets.QWidget):
"""
Widget for inspecting OCIO transform tone curves, which updates
asynchronously when visible, to reduce unnecessary background
processing.
"""
@classmethod
def label(cls) -> str:
return "Curve"
@@ -43,11 +54,11 @@ class CurveInspector(QtWidgets.QWidget):
self.input_range_edit.setToolTip(self.input_range_label.toolTip())
self.input_range_edit.value_changed.connect(self._on_input_range_changed)
self.sample_size_label = get_glyph_icon("ph.line-segments", as_widget=True)
self.sample_size_label.setToolTip("Sample size")
self.sample_size_edit = IntEdit(default=CurveView.SAMPLE_SIZE_DEFAULT)
self.sample_size_edit.setToolTip(self.sample_size_label.toolTip())
self.sample_size_edit.value_changed.connect(self._on_sample_size_changed)
self.sample_count_label = get_glyph_icon("ph.line-segments", as_widget=True)
self.sample_count_label.setToolTip("Sample count")
self.sample_count_edit = IntEdit(default=CurveView.SAMPLE_COUNT_DEFAULT)
self.sample_count_edit.setToolTip(self.sample_count_label.toolTip())
self.sample_count_edit.value_changed.connect(self._on_sample_count_changed)
self.sample_type_label = get_glyph_icon("mdi6.function-variant", as_widget=True)
self.sample_type_label.setToolTip("Sample type")
@@ -70,16 +81,16 @@ class CurveInspector(QtWidgets.QWidget):
option_layout = QtWidgets.QHBoxLayout()
option_layout.addWidget(self.input_range_label)
option_layout.addWidget(self.input_range_edit)
option_layout.setStretch(1, 2)
option_layout.addWidget(self.sample_size_label)
option_layout.addWidget(self.sample_size_edit)
option_layout.setStretch(3, 1)
option_layout.setStretch(1, 3)
option_layout.addWidget(self.sample_count_label)
option_layout.addWidget(self.sample_count_edit)
option_layout.setStretch(3, 2)
option_layout.addWidget(self.sample_type_label)
option_layout.addWidget(self.sample_type_combo)
option_layout.setStretch(5, 1)
option_layout.setStretch(5, 3)
option_layout.addWidget(self.log_base_label)
option_layout.addWidget(self.log_base_edit)
option_layout.setStretch(7, 1)
option_layout.setStretch(7, 2)
layout = QtWidgets.QVBoxLayout()
layout.addLayout(option_layout)
@@ -88,83 +99,137 @@ class CurveInspector(QtWidgets.QWidget):
self.setLayout(layout)
def reset(self) -> None:
"""Clear rendered curves."""
self.view.reset()
@QtCore.Slot(str, float)
def _on_input_range_changed(self, label: str, value: float) -> None:
"""
Triggered when the user changes the input range, which defines
the input values to be sampled through the transform.
:param label: Float edit label
:param value: Float edit value
"""
self.view.set_input_range(
self.input_range_edit.component_value("min"),
self.input_range_edit.component_value("max"),
)
@QtCore.Slot(int)
def _on_sample_size_changed(self, sample_size: int) -> None:
if sample_size >= CurveView.SAMPLE_SIZE_MIN:
self.view.set_sample_size(sample_size)
def _on_sample_count_changed(self, sample_count: int) -> None:
"""
Triggered when the user changes the number of samples to be
processed within the input range through the transform.
:param sample_count: Number of samples. Typically, a power of 2
number.
"""
if sample_count >= CurveView.SAMPLE_COUNT_MIN:
self.view.set_sample_count(sample_count)
else:
with SignalsBlocked(self.sample_size_edit):
self.sample_size_edit.set_value(CurveView.SAMPLE_SIZE_MIN)
self.view.set_sample_size(CurveView.SAMPLE_SIZE_MIN)
with SignalsBlocked(self.sample_count_edit):
self.sample_count_edit.set_value(CurveView.SAMPLE_COUNT_MIN)
self.view.set_sample_count(CurveView.SAMPLE_COUNT_MIN)
@QtCore.Slot(int)
def _on_sample_type_changed(self, index: int) -> None:
"""
Triggered when the user changes the sample type, which defines
how samples are distributed within the input range.
:param index: Curve type index
"""
sample_type = self.sample_type_combo.member()
self.log_base_edit.setEnabled(sample_type == SampleType.LOG)
self.view.set_sample_type(sample_type)
@QtCore.Slot(int)
def _on_log_base_changed(self, log_base: int) -> None:
"""
Triggered when the user changes the base for the log sample
type.
:param log_base: Log scale base
"""
self.view.set_log_base(log_base)
class CurveView(QtWidgets.QGraphicsView):
"""
Widget for rendering OCIO transform tone curves.
"""
SAMPLE_SIZE_MIN = 2**8
SAMPLE_SIZE_DEFAULT = 2**10
SAMPLE_COUNT_MIN = 2**8
SAMPLE_COUNT_DEFAULT = 2**10
INPUT_MIN_DEFAULT = 0.0
INPUT_MAX_DEFAULT = 1.0
LOG_BASE_DEFAULT = 2
CURVE_SCALE = 100
FONT_HEIGHT = 4
# The curve viewer only shows 5 digit decimal precision, so this should work fine
# as a minimum when input min is 0.
LOG_EPSILON = 1e-5
LOG_BASE_DEFAULT = 2
EPSILON = 1e-5
def __init__(
self,
input_min: float = INPUT_MIN_DEFAULT,
input_max: float = INPUT_MAX_DEFAULT,
sample_size: int = SAMPLE_SIZE_DEFAULT,
sample_count: int = SAMPLE_COUNT_DEFAULT,
sample_type: SampleType = SampleType.LINEAR,
log_base: int = LOG_BASE_DEFAULT,
parent: Optional[QtWidgets.QWidget] = None,
):
"""
:param input_min: Input range minimum value
:param input_max: Input range maximum value
:param sample_count: Number of samples in the input range,
which will typically be a power of 2 value.
:param sample_type: Sample scale/distribution type
:param log_base: Log scale base when sample_type is
`SampleType.LOG`.
"""
super().__init__(parent=parent)
self.setRenderHint(QtGui.QPainter.Antialiasing, True)
self.setViewportUpdateMode(QtWidgets.QGraphicsView.FullViewportUpdate)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setMouseTracking(True)
self.scale(1, -1)
self.scale(1, -1) # Flip to make origin the bottom-left corner
# Input range
if input_max <= input_min:
input_min = self.INPUT_MIN_DEFAULT
input_max = self.INPUT_MAX_DEFAULT
self._log_base = max(2, log_base)
self._input_min = input_min
self._input_max = input_max
self._sample_size = max(self.SAMPLE_SIZE_MIN, sample_size)
# Sample characteristics
self._sample_count = max(self.SAMPLE_COUNT_MIN, sample_count)
self._sample_type = sample_type
self._log_base = max(2, log_base)
# Cached sample data
self._sample_ellipse: Optional[QtWidgets.QGraphicsEllipseItem] = None
self._sample_text: Optional[QtWidgets.QGraphicsTextItem] = None
self._sample_rect: Optional[QtCore.QRectF] = None
self._samples_x_lin: np.ndarray = None
self._samples_x_log: np.ndarray = None
self._sample_y_min: float = self._input_min
self._sample_y_max: float = self._input_max
self._samples: dict[str, np.ndarray] = {}
self._nearest_samples: dict[str, tuple[float, float, float]] = {}
self._x_lin: np.ndarray = np.array([], dtype=np.float32)
self._x_log: np.ndarray = np.array([], dtype=np.float32)
self._x_min: float = self._input_min
self._x_max: float = self._input_max
self._y_min: float = self._input_min
self._y_max: float = self._input_max
# Cached curve data
self._curve_init = False
self._curve_tf = QtGui.QTransform()
self._curve_tf_inv = QtGui.QTransform()
self._curve_paths: dict[str, QtGui.QPainterPath] = {}
self._curve_items: dict[str, QtWidgets.QGraphicsPathItem] = {}
self._curve_rect = QtCore.QRectF(
@@ -173,10 +238,11 @@ class CurveView(QtWidgets.QGraphicsView):
self._input_max - self._input_min,
self._input_max - self._input_min,
)
self._nearest_samples: dict[str, tuple[float, float, float]] = {}
self._prev_cpu_proc = None
self._curve_init = False
# Cached processor from which the OCIO transform is derived
self._prev_cpu_proc = None
# Graphics scene
self._scene = QtWidgets.QGraphicsScene()
self.setScene(self._scene)
@@ -200,8 +266,8 @@ class CurveView(QtWidgets.QGraphicsView):
msg_router.set_cpu_processor_updates_allowed(False)
def resizeEvent(self, event: QtGui.QResizeEvent) -> None:
"""Re-fit graph on resize, to always be centered."""
super().resizeEvent(event)
self._fit()
def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
@@ -213,37 +279,52 @@ class CurveView(QtWidgets.QGraphicsView):
self._nearest_samples.clear()
pos = self.mapToScene(event.pos()) / self.CURVE_SCALE
pos = self._curve_tf_inv.map(self.mapToScene(event.pos()))
pos_arr = np.array([pos.x(), pos.y()], dtype=np.float32)
for color_name, samples in self._samples.items():
all_dist = np.linalg.norm(samples - pos_arr, axis=2)
all_dist = np.linalg.norm(samples - pos_arr, axis=1)
nearest_dist_index = np.argmin(all_dist)
self._nearest_samples[color_name] = (
(
self._samples_x_lin[nearest_dist_index]
self._x_lin[nearest_dist_index]
if self._sample_type == SampleType.LINEAR
else self._samples_x_log[nearest_dist_index]
else self._x_log[nearest_dist_index]
),
samples[0][nearest_dist_index][0],
samples[0][nearest_dist_index][1],
samples[nearest_dist_index][0],
samples[nearest_dist_index][1],
)
self._invalidate()
def wheelEvent(self, event: QtGui.QWheelEvent) -> None:
"""
Ignore wheel events to prevent scrolling around graphics scene.
"""
event.ignore()
def reset(self) -> None:
"""Clear all curves."""
self._samples.clear()
self._curve_items.clear()
self._curve_paths.clear()
self._nearest_samples.clear()
self._prev_cpu_proc = None
self._curve_init = False
self._curve_paths.clear()
self._curve_items.clear()
self._prev_cpu_proc = None
self._scene.clear()
self._invalidate()
def set_input_range(self, input_min: float, input_max: float) -> None:
"""
Set the input range, which defines the input values to be
sampled through the transform.
:param input_min: Input range minimum value
:param input_max: Input range maximum value
"""
if (
input_min != self._input_min or input_max != self._input_max
) and input_max > input_min:
@@ -252,31 +333,62 @@ class CurveView(QtWidgets.QGraphicsView):
self._update_curves()
def set_input_min(self, input_min: float) -> None:
"""
Set the input minimum, which defines the lowest value to be
sampled through the transform.
:param input_min: Input range minimum value
"""
if input_min != self._input_min and input_min < self._input_max:
self._input_min = input_min
self._update_curves()
def set_input_max(self, input_max: float) -> None:
"""
Set the input maximum, which defines the highest value to be
sampled through the transform.
:param input_max: Input range minimum value
"""
if input_max != self._input_max and input_max > self._input_min:
self._input_max = input_max
self._update_curves()
def set_sample_size(self, sample_size: int) -> None:
if sample_size != self._sample_size and sample_size >= self.SAMPLE_SIZE_MIN:
self._sample_size = sample_size
def set_sample_count(self, sample_count: int) -> None:
"""
Set the number of samples to be processed within the input
range through the transform.
:param sample_count: Number of samples. Typically, a power of 2
number.
"""
if sample_count != self._sample_count and sample_count >= self.SAMPLE_COUNT_MIN:
self._sample_count = sample_count
self._update_curves()
def set_sample_type(self, sample_type: SampleType) -> None:
"""
Set the sample type, which defines how samples are distributed
within the input range.
:param sample_type: Curve type index
"""
if sample_type != self._sample_type:
self._sample_type = sample_type
self._update_curves()
def set_log_base(self, log_base: int) -> None:
"""
Set the base for the log sample type.
:param log_base: Log scale base
"""
if log_base != self._log_base and log_base >= 2:
self._log_base = log_base
self._update_curves()
def drawBackground(self, painter: QtGui.QPainter, rect: QtCore.QRectF) -> None:
"""Draw curve grid and axis values."""
# Flood fill background
painter.setPen(QtCore.Qt.NoPen)
painter.setBrush(QtCore.Qt.black)
@@ -285,101 +397,41 @@ class CurveView(QtWidgets.QGraphicsView):
if not self._curve_init:
return
# Calculate grid rect
curve_t, curve_b, curve_l, curve_r = (
self._curve_rect.top(),
self._curve_rect.bottom(),
self._curve_rect.left(),
self._curve_rect.right(),
)
# Round to nearest 10 for grid bounds
grid_t = curve_t // 10 * 10
if grid_t > math.ceil(curve_t):
grid_t -= 10
grid_b = curve_b // 10 * 10
if grid_b < math.floor(curve_b):
grid_b += 10
grid_l = curve_l // 10 * 10
if grid_l > math.ceil(curve_l):
grid_l -= 10
grid_r = curve_r // 10 * 10
if grid_r < math.floor(curve_r):
grid_r += 10
font = painter.font()
font.setPixelSize(self.FONT_HEIGHT)
painter.setFont(font)
text_pen = QtGui.QPen(GRAY_COLOR)
grid_pen = QtGui.QPen(GRAY_COLOR.darker(200))
grid_pen.setWidthF(0)
font = painter.font()
font.setPixelSize(self.FONT_HEIGHT)
painter.setPen(grid_pen)
painter.setBrush(QtCore.Qt.NoBrush)
painter.setFont(font)
# Calculate samples to display
sample_step = math.ceil(self._sample_size / 10.0)
min_x = max_x = min_y = max_y = None
if self._sample_type == SampleType.LINEAR:
sample_x_values = self._samples_x_lin
else: # SampleType.LOG
sample_x_values = self._samples_x_log
sample_y_data = []
for i, sample_y in enumerate(
np.linspace(self._sample_y_min, self._sample_y_max, 11, dtype=np.float32)
):
pos_y = sample_y * self.CURVE_SCALE
sample_y_data.append((pos_y, sample_y))
if min_y is None or pos_y < min_y:
min_y = pos_y
if max_y is None or pos_y > max_y:
max_y = pos_y
sample_x_data = []
for i, sample_x in enumerate(sample_x_values):
if not (i % sample_step == 0 or i == self._sample_size - 1):
continue
pos_x = self._samples_x_lin[i] * self.CURVE_SCALE
sample_x_data.append((pos_x, sample_x))
if min_x is None or pos_x < min_x:
min_x = pos_x
if max_x is None or pos_x > max_x:
max_x = pos_x
if min_x is None:
min_x = grid_l
if max_x is None:
max_x = grid_r
if min_y is None:
min_y = grid_t
if max_x is None:
max_y = grid_b
self._sample_rect = QtCore.QRectF(
max_x + 5, min_y, 40, len(self._curve_items) * 20
)
# Draw grid border
painter.drawRect(self._curve_rect)
# Draw grid rows
y_text_origin = QtGui.QTextOption(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
y_text_origin.setWrapMode(QtGui.QTextOption.NoWrap)
for pos_y, sample_y in sample_y_data:
painter.setPen(grid_pen)
painter.drawLine(QtCore.QLineF(min_x, pos_y, max_x, pos_y))
for i, y in enumerate(
np.linspace(self._y_min, self._y_max, 11, dtype=np.float32)
):
p1 = self._curve_tf.map(QtCore.QPointF(self._x_min, y))
p2 = self._curve_tf.map(QtCore.QPointF(self._x_max, y))
if pos_y > grid_t:
label_value = round(sample_y, 2)
if self._y_min < y < self._y_max:
painter.setPen(grid_pen)
painter.drawLine(QtCore.QLineF(p1, p2))
if y > self._y_min:
label_value = round(y, 2)
if label_value == 0.0:
label_value = abs(label_value)
painter.save()
painter.translate(QtCore.QPointF(min_x, pos_y))
painter.translate(p1)
painter.scale(1, -1)
painter.setPen(text_pen)
painter.drawText(
@@ -391,28 +443,39 @@ class CurveView(QtWidgets.QGraphicsView):
x_text_origin = QtGui.QTextOption(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
x_text_origin.setWrapMode(QtGui.QTextOption.NoWrap)
for pos_x, sample_x in sample_x_data:
painter.setPen(grid_pen)
painter.drawLine(QtCore.QLineF(pos_x, min_y, pos_x, max_y))
sample_step = math.ceil(self._sample_count / 10.0)
if pos_x > grid_l:
for i, x in enumerate(self._x_lin):
if not (i % sample_step == 0 or i == self._sample_count - 1):
continue
p1 = self._curve_tf.map(QtCore.QPointF(x, self._y_min))
p2 = self._curve_tf.map(QtCore.QPointF(x, self._y_max))
if self._x_min < x < self._x_max:
painter.setPen(grid_pen)
painter.drawLine(QtCore.QLineF(p1, p2))
if x > self._x_min:
label_value = round(
sample_x, 5 if self._sample_type == SampleType.LOG else 2
x if self._sample_type == SampleType.LINEAR else self._x_log[i],
2 if self._sample_type == SampleType.LINEAR else 5,
)
if label_value == 0.0:
label_value = abs(label_value)
painter.save()
painter.translate(QtCore.QPointF(pos_x, min_y))
painter.translate(p1)
painter.scale(1, -1)
painter.rotate(90)
painter.setPen(text_pen)
painter.drawText(
QtCore.QRect(2.5 + 1, -10, 40, 20), str(label_value), x_text_origin
QtCore.QRectF(2.5 + 1, -10, 40, 20), str(label_value), x_text_origin
)
painter.restore()
def drawForeground(self, painter: QtGui.QPainter, rect: QtCore.QRectF) -> None:
"""Draw nearest sample point and coordinates."""
if not self._curve_init:
return
@@ -436,16 +499,18 @@ class CurveView(QtWidgets.QGraphicsView):
painter.setBrush(QtGui.QColor(color_name))
painter.drawEllipse(
QtCore.QPointF(
nearest_sample[1] * self.CURVE_SCALE,
nearest_sample[2] * self.CURVE_SCALE,
self._curve_tf.map(
QtCore.QPointF(
nearest_sample[1],
nearest_sample[2],
)
),
1.25,
1.25,
1.5,
1.5,
)
# Draw sample values
if sample_l is not None:
# Draw sample values
painter.setBrush(QtCore.Qt.NoBrush)
x_label_value = f"{nearest_sample[0]:.05f}"
@@ -461,27 +526,56 @@ class CurveView(QtWidgets.QGraphicsView):
if color_name == GRAY_COLOR.name():
palette = self.palette()
painter.setPen(palette.color(palette.Text))
painter.setPen(palette.color(palette.ColorRole.Text))
else:
painter.setPen(QtGui.QColor(color_name))
painter.drawText(
QtCore.QRectF(5, -20, 35, 10), x_label_value, text_origin
)
painter.drawText(
QtCore.QRectF(5, -10, 35, 10), y_label_value, text_origin
)
painter.restore()
def _invalidate(self) -> None:
"""Force repaint of visible region of graphics scene."""
self._scene.invalidate(QtCore.QRectF(self.visibleRegion().boundingRect()))
def _update_curves(self) -> None:
"""
Update X-axis samples and rebuild curves from any cached
processor.
"""
self._update_x_samples()
if self._prev_cpu_proc is not None:
self._on_cpu_processor_ready(self._prev_cpu_proc)
def _update_x_samples(self):
"""
Update linear and log X-axis samples from input and sample
parameters.
"""
self._x_lin = np.linspace(
self._input_min, self._input_max, self._sample_count, dtype=np.float32
)
log_min = math.log(max(self.EPSILON, self._input_min))
log_max = max(log_min + 0.00001, math.log(self._input_max, self._log_base))
self._x_log = np.logspace(
log_min, log_max, self._sample_count, base=self._log_base, dtype=np.float32
)
self._x_min = self._x_lin.min()
self._x_max = self._x_lin.max()
def _fit(self) -> None:
"""Fit and center graph."""
if not self._curve_init:
return
# Use font metrics to calculate text padding, based on estimated maximum
# number lengths.
font = self.font()
font.setPixelSize(self.FONT_HEIGHT)
fm = QtGui.QFontMetrics(font)
@@ -503,29 +597,15 @@ class CurveView(QtWidgets.QGraphicsView):
fit_rect = self._curve_rect.adjusted(-pad_l, -pad_t, pad_r, pad_b)
# Fit and center on calculated rectangle
self.fitInView(fit_rect, QtCore.Qt.KeepAspectRatio)
self.centerOn(fit_rect.center())
self.update()
def _invalidate(self) -> None:
self._scene.invalidate(QtCore.QRectF(self.visibleRegion().boundingRect()))
def _update_x_samples(self):
self._samples_x_lin = np.linspace(
self._input_min, self._input_max, self._sample_size, dtype=np.float32
)
self._samples_x_log = np.logspace(
math.log(max(self.LOG_EPSILON, self._input_min)),
math.log(max(self.LOG_EPSILON, self._input_max)),
self._sample_size,
base=self._log_base,
dtype=np.float32,
)
@QtCore.Slot(ocio.CPUProcessor)
def _on_cpu_processor_ready(self, cpu_proc: ocio.CPUProcessor) -> None:
"""
Update curves from OCIO CPU processor.
Update curves from sampled OCIO CPU processor.
:param cpu_proc: CPU processor of currently viewed transform
"""
@@ -535,12 +615,12 @@ class CurveView(QtWidgets.QGraphicsView):
# Get input samples
if self._sample_type == SampleType.LOG:
samples = self._samples_x_log
x_samples = self._x_log
else: # LINEAR
samples = self._samples_x_lin
x_samples = self._x_lin
# Interleave samples per channel
rgb_samples = np.repeat(samples, 3)
rgb_samples = np.repeat(x_samples, 3)
# Apply processor to samples
cpu_proc.applyRGB(rgb_samples)
@@ -550,28 +630,21 @@ class CurveView(QtWidgets.QGraphicsView):
g_samples = rgb_samples[1::3]
b_samples = rgb_samples[2::3]
# Build painter path from sample data
if np.array_equal(r_samples, g_samples) and np.array_equal(
r_samples, b_samples
# Collect sample pairs and min/max Y sample values
if np.allclose(r_samples, g_samples, atol=self.EPSILON) and np.allclose(
r_samples, b_samples, atol=self.EPSILON
):
palette = self.palette()
color_name = palette.color(palette.Text).name()
color_name = palette.color(palette.ColorRole.Text).name()
self._samples[color_name] = np.dstack((self._samples_x_lin, r_samples))
self._sample_y_min = r_samples.min()
self._sample_y_max = r_samples.max()
self._samples[color_name] = np.stack((self._x_lin, r_samples), axis=-1)
curve = QtGui.QPainterPath(
QtCore.QPointF(self._samples_x_lin[0], r_samples[0])
)
curve.reserve(samples.size)
for i in range(1, samples.size):
curve.lineTo(QtCore.QPointF(self._samples_x_lin[i], r_samples[i]))
self._curve_paths[color_name] = curve
self._y_min = r_samples.min()
self._y_max = r_samples.max()
else:
sample_y_min = None
sample_y_max = None
y_min = None
y_max = None
for i, (color, channel_samples) in enumerate(
[
@@ -582,43 +655,71 @@ class CurveView(QtWidgets.QGraphicsView):
):
color_name = color.name()
self._samples[color_name] = np.dstack(
(self._samples_x_lin, channel_samples)
self._samples[color_name] = np.stack(
(self._x_lin, channel_samples), axis=-1
)
channel_sample_y_min = channel_samples.min()
if sample_y_min is None or channel_sample_y_min < sample_y_min:
sample_y_min = channel_sample_y_min
channel_sample_y_max = channel_samples.max()
if sample_y_max is None or channel_sample_y_max > sample_y_max:
sample_y_max = channel_sample_y_max
channel_y_min = channel_samples.min()
if y_min is None or channel_y_min < y_min:
y_min = channel_y_min
channel_y_max = channel_samples.max()
if y_max is None or channel_y_max > y_max:
y_max = channel_y_max
curve = QtGui.QPainterPath(
QtCore.QPointF(self._samples_x_lin[0], channel_samples[0])
self._y_min = y_min
self._y_max = y_max
# Transform to scale/translate curve so that it fits in a square and
# has its origin at (0, 0).
curve_tf = QtGui.QTransform()
curve_tf.translate(-self._x_min, -self._y_min)
curve_tf.scale(
self.CURVE_SCALE / (self._x_max - self._x_min),
self.CURVE_SCALE / (self._y_max - self._y_min),
)
self._curve_tf = curve_tf
self._curve_tf_inv, ok = curve_tf.inverted()
# Curve square
self._curve_rect = QtCore.QRectF(
self._curve_tf.map(QtCore.QPointF(self._x_min, self._y_min)),
self._curve_tf.map(QtCore.QPointF(self._x_max, self._y_max)),
)
# Sample box rect
self._sample_rect = QtCore.QRectF(
self._curve_rect.right() + 5,
self._curve_rect.top(),
40,
len(self._samples) * 20,
)
# Build painter paths that fit in square from sample data
for color_name, channel_samples in self._samples.items():
curve = QtGui.QPainterPath(
self._curve_tf.map(
QtCore.QPointF(channel_samples[0][0], channel_samples[0][1])
)
curve.reserve(samples.size)
for j in range(1, samples.size):
curve.lineTo(
QtCore.QPointF(self._samples_x_lin[j], channel_samples[j])
)
curve.reserve(channel_samples.shape[0])
for i in range(1, channel_samples.shape[0]):
curve.lineTo(
self._curve_tf.map(
QtCore.QPointF(channel_samples[i][0], channel_samples[i][1])
)
self._curve_paths[color_name] = curve
self._sample_y_min = sample_y_min
self._sample_y_max = sample_y_max
)
self._curve_paths[color_name] = curve
# Add curve(s) to scene
self._curve_rect = QtCore.QRectF()
for color_name, curve in self._curve_paths.items():
pen = QtGui.QPen()
pen.setColor(QtGui.QColor(color_name))
pen.setWidthF(0)
pen.setWidthF(0.5)
curve_item = self._scene.addPath(
curve, pen, QtGui.QBrush(QtCore.Qt.NoBrush)
)
curve_item.setScale(self.CURVE_SCALE)
self._curve_items[color_name] = curve_item
self._curve_rect = self._curve_rect.united(curve_item.sceneBoundingRect())
self._curve_init = True
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..log_handlers import set_logging_level
from ..message_router import MessageRouter
+1 -1
View File
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from .inspect.curve_inspector import CurveInspector
from .inspect import LogInspector, CodeInspector
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..widgets import ItemModelListWidget
from ..utils import get_glyph_icon
@@ -5,7 +5,7 @@ from dataclasses import dataclass
from typing import Any, Callable, Optional, Type
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..undo import ConfigSnapshotUndoCommand
@@ -87,7 +87,7 @@ class BaseActiveDisplayViewModel(BaseConfigItemModel):
def _get_undo_command_type(
self, column_desc: ColumnDesc
) -> Type[QtWidgets.QUndoCommand]:
) -> Type[QtGui.QUndoCommand]:
if column_desc == self.ACTIVE:
# Changing check state of the ACTIVE column has side effects related to
# display/view order, so a config snapshot is needed to revert the change.
@@ -4,7 +4,7 @@
from functools import partial
from typing import Optional
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
import PyOpenColorIO as ocio
from ..config_cache import ConfigCache
@@ -5,7 +5,7 @@ import copy
from typing import Any, Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..ref_space_manager import ReferenceSpaceManager
@@ -4,7 +4,7 @@
from functools import partial
from typing import Optional
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..constants import MARGIN_WIDTH
from ..transform_manager import TransformManager
@@ -47,7 +47,7 @@ class BaseConfigItemParamEdit(QtWidgets.QWidget):
if self.__has_transforms__:
self.__has_tabs__ = True
no_tf_color = palette.color(palette.Disabled, palette.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
@@ -6,7 +6,7 @@ from dataclasses import dataclass
from typing import Any, Optional, Type, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..config_cache import ConfigCache
from ..transform_manager import TransformManager, TransformAgent
@@ -587,7 +587,7 @@ class BaseConfigItemModel(QtCore.QAbstractTableModel):
def _get_undo_command_type(
self, column_desc: ColumnDesc
) -> Type[QtWidgets.QUndoCommand]:
) -> Type[QtGui.QUndoCommand]:
"""
Support overriding the undo command type used to
track data changes, per column.
@@ -5,7 +5,7 @@ from pathlib import Path
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtWidgets
from PySide6 import QtWidgets
from ..constants import RGB
from ..widgets import (
@@ -5,7 +5,7 @@ import logging
from pathlib import Path
from typing import Any, Optional
from PySide2 import QtCore
from PySide6 import QtCore
import PyOpenColorIO as ocio
from .config_item_model import ColumnDesc, BaseConfigItemModel
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..config_cache import ConfigCache
from ..widgets import CallbackComboBox
@@ -34,7 +34,6 @@ class ColorSpaceDelegate(QtWidgets.QStyledItemDelegate):
editor = CallbackComboBox(
get_items=ConfigCache.get_color_space_names, editable=True, parent=parent
)
editor.setAutoCompletion(True)
editor.completer().setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
return editor
@@ -119,7 +118,6 @@ class RoleDelegate(QtWidgets.QStyledItemDelegate):
raise NotImplementedError
widget = CallbackComboBox(get_items=get_items, editable=True, parent=parent)
widget.setAutoCompletion(True)
widget.completer().setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
return widget
@@ -5,7 +5,7 @@ from dataclasses import dataclass, field
from typing import Any, Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..config_cache import ConfigCache
from ..utils import next_name
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..utils import get_glyph_icon
from .active_display_view_edit import ActiveDisplayViewEdit
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..config_cache import ConfigCache
from ..utils import get_glyph_icon
@@ -6,7 +6,7 @@ from dataclasses import dataclass, field
from typing import Any, Optional, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..undo import ConfigSnapshotUndoCommand
@@ -5,7 +5,7 @@ from functools import partial
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtWidgets
from PySide6 import QtWidgets
from ..config_cache import ConfigCache
from ..widgets import CallbackComboBox, TextEdit
@@ -5,7 +5,7 @@ import copy
from typing import Any, Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..ref_space_manager import ReferenceSpaceManager
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtWidgets
from PySide6 import QtWidgets
from ..config_cache import ConfigCache
from ..utils import get_glyph_icon
@@ -5,7 +5,7 @@ import copy
from typing import Any, Optional, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..utils import get_glyph_icon
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtGui, QtWidgets
from PySide6 import QtGui, QtWidgets
from ..widgets import ItemModelTableWidget
from .delegates import RoleDelegate
@@ -5,7 +5,7 @@ from dataclasses import dataclass
from typing import Any
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..config_cache import ConfigCache
from .config_item_model import ColumnDesc, BaseConfigItemModel
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..utils import get_glyph_icon
from .file_rule_edit import FileRuleEdit
@@ -5,7 +5,7 @@ from functools import partial
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtWidgets
from PySide6 import QtWidgets
from ..config_cache import ConfigCache
from ..widgets import CallbackComboBox, LineEdit
@@ -6,7 +6,7 @@ from dataclasses import dataclass, field
from typing import Any, Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from .config_item_model import ColumnDesc, BaseConfigItemModel
@@ -5,7 +5,7 @@ from functools import partial
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..config_cache import ConfigCache
from ..transform_manager import TransformManager
@@ -4,7 +4,7 @@
from typing import Any, Optional, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..ref_space_manager import ReferenceSpaceManager
@@ -4,7 +4,7 @@
from functools import partial
from typing import Optional
from PySide2 import QtWidgets
from PySide6 import QtWidgets
import PyOpenColorIO as ocio
from ..config_cache import ConfigCache
@@ -5,7 +5,7 @@ import copy
from typing import Any, Optional, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..utils import get_enum_member, get_glyph_icon
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..config_cache import ConfigCache
from ..utils import get_glyph_icon
@@ -7,7 +7,7 @@ from dataclasses import dataclass, field
from typing import Any, Optional, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..undo import ConfigSnapshotUndoCommand
+1 -1
View File
@@ -7,7 +7,7 @@ from pathlib import Path
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from .config_cache import ConfigCache
from .config_dock import ConfigDock
+1 -1
View File
@@ -10,7 +10,7 @@ from typing import Any, Optional
from queue import Empty, SimpleQueue
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from .utils import config_to_html, processor_to_ctf_html, processor_to_shader_html
+1 -1
View File
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenColorIO Project.
from PySide2 import QtCore
from PySide6 import QtCore
settings = QtCore.QSettings(
+1 -1
View File
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtGui, QtWidgets
from PySide6 import QtGui, QtWidgets
from .constants import (
BORDER_COLOR_ROLE,
@@ -7,7 +7,7 @@ from functools import partial
from typing import Callable, Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from .utils import get_glyph_icon
@@ -99,12 +99,15 @@ class TransformManager:
tf_agent.item_tf_changed.connect(partial(cls._on_item_tf_changed, slot))
cls._tf_subscriptions[slot] = tf_subscription
# Trigger immediate update to subscribers
# Inform menu subscribers of the menu change
cls._update_menu_items()
cls._on_item_tf_changed(
slot,
*item_model.get_item_transforms(item_name),
)
# Inform init subscribers of the new subscription
for init_callback in cls._tf_subscribers.get(-1, []):
init_callback(slot)
# Trigger immediate update to subscribers of this slot
cls._on_item_tf_changed(slot, *item_model.get_item_transforms(item_name))
# Repaint views for previous and new model
if prev_item_model is not None:
@@ -206,10 +209,27 @@ class TransformManager:
menu_callback(cls.get_subscription_menu_items())
@classmethod
def subscribe_to_transforms(cls, slot: int, tf_callback: Callable) -> None:
def subscribe_to_transform_subscription_init(cls, init_callback: Callable) -> None:
"""
Subscribe to transform and item name updates at the given slot
number.
Subscribe to transform subscription initialization on all slots.
:param init_callback: Transform subscription initialization
callback, which will be called whenever a new transform
subscription is initialized with the subscription slot
number.
"""
cls._tf_subscribers[-1].append(init_callback)
# Trigger immediate update to init subscriber if a transform subscription
# exists.
for slot, tf_subscription in cls._tf_subscriptions.items():
init_callback(slot)
break
@classmethod
def subscribe_to_transforms_at(cls, slot: int, tf_callback: Callable) -> None:
"""
Subscribe to transform updates at the given slot number.
:param slot: Subscription slot number
:param tf_callback: Transform callback, which will be called
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..widgets import EnumComboBox, FloatEdit, FloatEditArray
from .transform_edit import BaseTransformEdit
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..widgets import ComboBox
from .transform_edit import BaseTransformEdit
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..constants import RGB
from ..widgets import EnumComboBox, FloatEdit, FloatEditArray
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..config_cache import ConfigCache
from ..widgets import CheckBox, CallbackComboBox
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..config_cache import ConfigCache
from ..utils import SignalsBlocked
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..constants import RGBA
from ..widgets import EnumComboBox, FloatEditArray
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..constants import RGBA
from ..widgets import EnumComboBox, FloatEditArray
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..widgets import EnumComboBox, FloatEdit
from .transform_edit import BaseTransformEdit
@@ -5,7 +5,7 @@ import os
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..widgets import EnumComboBox, LineEdit
from .transform_edit import BaseTransformEdit
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..widgets import EnumComboBox, FloatEditArray, ExpandingStackedWidget
from .transform_edit import BaseTransformEdit
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..constants import RGB
from ..widgets import FloatEditArray
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..constants import RGB
from ..widgets import FloatEdit, FloatEditArray

Some files were not shown because too many files have changed in this diff Show More