├── .build_env.example ├── .gitignore ├── BUILDING ├── CMakeLists.txt ├── LICENSE ├── README.md ├── build.sh ├── build_tools ├── conan_profile_linux_gcc4.8 ├── conan_profile_linux_gcc9.3 ├── conan_profile_windows_vs2015 ├── conan_profile_windows_vs2019 ├── installer.py └── linux │ ├── build-conan.sh │ ├── docker_14plus │ └── Dockerfile │ ├── docker_9_13 │ ├── Dockerfile │ ├── bootstrap.sh │ ├── cmake-bootstrap.sh │ ├── conan-bootstrap.sh │ ├── conan_profile_linux_gcc_4.8 │ ├── entrypoint.sh │ ├── extra-bootstrap.sh │ ├── gcc-4.1.2.sh │ ├── gcc-4.8.2.sh │ └── get-pip.py │ └── linux-docker-build.sh ├── cmake ├── Modules │ ├── FindNuke111.cmake │ ├── FindNuke112.cmake │ ├── FindNuke113.cmake │ ├── FindNuke120.cmake │ ├── FindNuke121.cmake │ ├── FindNuke122.cmake │ ├── FindNuke130.cmake │ ├── FindNuke132.cmake │ ├── FindNuke140.cmake │ ├── FindNuke151.cmake │ ├── FindNuke160.cmake │ ├── FindOFX.cmake │ └── FindOpenImageIO.cmake ├── compile_definitions.cmake ├── output_folders.cmake └── precompiled_headers.cmake ├── conanfile.py ├── data ├── openexrid.abc ├── sample_motionblur_transparency.exr └── sample_motionblur_transparency.png ├── nuke ├── DeepOpenEXRId.cpp ├── DeepOpenEXRId.h ├── OSL │ ├── accum.cpp │ ├── automata.cpp │ ├── closure.cpp │ ├── include │ │ └── OSL │ │ │ ├── accum.h │ │ │ ├── automata.h │ │ │ ├── constantpool.h │ │ │ ├── export.h │ │ │ ├── genclosure.h │ │ │ ├── lpeparse.h │ │ │ ├── lpexp.h │ │ │ ├── matrix22.h │ │ │ ├── optautomata.h │ │ │ ├── osl_pvt.h │ │ │ ├── oslclosure.h │ │ │ ├── oslconfig.h │ │ │ ├── oslexec.h │ │ │ ├── oslexec_pvt.h │ │ │ ├── oslversion.h │ │ │ ├── rendererservices.h │ │ │ └── shaderglobals.h │ ├── lpeparse.cpp │ └── lpexp.cpp ├── PickingKnob.cpp ├── PickingKnob.h ├── b64.cpp ├── md5.cpp ├── md5.h ├── menu.py ├── nuke.cmake └── zlib.cpp ├── nuke11.1 └── CMakeLists.txt ├── nuke11.2 └── CMakeLists.txt ├── nuke11.3 └── CMakeLists.txt ├── nuke12.0 └── CMakeLists.txt ├── nuke12.1 └── CMakeLists.txt ├── nuke12.2 └── CMakeLists.txt ├── nuke13.0 └── CMakeLists.txt ├── nuke13.2 └── CMakeLists.txt ├── nuke14.0 └── CMakeLists.txt ├── nuke15.1 └── CMakeLists.txt ├── nuke16.0 └── CMakeLists.txt ├── openexrid ├── Builder.cpp ├── Builder.h ├── CMakeLists.txt ├── Mask.cpp ├── Mask.h ├── Query.h ├── Sample.h ├── Slice.h ├── Version.h ├── b64.cpp └── zlib.cpp ├── openfx ├── CMakeLists.txt ├── dir.cpp ├── dir.h ├── file_range.cpp ├── instance.h ├── interact.cpp ├── ofxUtilities.h ├── openfx.cpp └── openfx.vcxproj └── test ├── makefile ├── test.cpp └── test.vcxproj /.build_env.example: -------------------------------------------------------------------------------- 1 | ################################ 2 | ### Python environment 3 | ################################ 4 | 5 | #export PYTHON_38=/x/Tools/Python38 6 | #export PYTHONHOME=$PYTHON_38 7 | #export PYTHONPATH=$PYTHON_38 8 | #export PATH=$PYTHON_38:$PYTHON_38/Scripts:$PATH 9 | 10 | ################################ 11 | ### Conan environment 12 | ################################ 13 | 14 | #alias conan="/x/Tools/Python38/Scripts/conan.exe" 15 | 16 | # Where to store out conan packages ? 17 | #export CONAN_USER_HOME="C:/.conan" 18 | 19 | # Use a different conan folder when building from docker ? 20 | #export CONAN_DOCKER_HOME="C:/.conan_docker" 21 | 22 | # Required conan repository 23 | #conan remote add mercenaries http://c3dcoodq1.mercs-eng.com:8081/artifactory/api/conan/conan_packages --insert 0 --force 24 | #conan remote add guerilla_legacy http://c3dcoodq1.mercs-eng.com:8081/artifactory/api/conan/guerilla_legacy --insert 1 --force 25 | 26 | # Would you like to update conan everytime you run .build.sh ? ("full"/"fast"/"skip") 27 | #export conan_update="full" 28 | 29 | ################################ 30 | ### Nuke Environment 31 | ################################ 32 | 33 | #export NUKE111_DIR="D:\\Nuke\\Nuke11.1v6" 34 | #export NUKE112_DIR="D:\\Nuke\\Nuke11.2v7" 35 | #export NUKE113_DIR="D:\\Nuke\\Nuke11.3v6" 36 | #export NUKE120_DIR="D:\\Nuke\\Nuke12.0v3" 37 | #export NUKE121_DIR="D:\\Nuke\\Nuke12.1v2" 38 | #export NUKE122_DIR="D:\\Nuke\\Nuke12.2v4" 39 | #export NUKE130_DIR="D:\\Nuke\\Nuke13.0v5" 40 | #export NUKE132_DIR="D:\\Nuke\\Nuke13.2v7" 41 | #export NUKE140_DIR="D:\\Nuke\\Nuke14.0v4" 42 | #export NUKE151_DIR="D:\\Nuke\\Nuke15.1v3" 43 | #export NUKE160_DIR="D:\\Nuke\\Nuke16.0v2" 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | x64 2 | Debug 3 | debug 4 | relwithdebinfo 5 | Conan/* 6 | build/ 7 | *.filters 8 | *.sdf 9 | .vs 10 | *.opensdf 11 | *.user 12 | release 13 | *.zip 14 | *.tar.gz 15 | build4.8/ 16 | .build_env 17 | -------------------------------------------------------------------------------- /BUILDING: -------------------------------------------------------------------------------- 1 | *************************** 2 | * Compilation under linux * 3 | *************************** 4 | 5 | Prerequisites: 6 | -------------- 7 | 8 | - CMake 3.10. We provide a CMake solution to build the lib and plugins for Nuke and OFX. You can work your way out of CMake, though ... 9 | - gcc 4.8.2. Although you can use any c++11 capable compiler to build the OpenEXRId lib, compiling the Nuke plugins might not be pratical. 10 | - OpenEXR 2.5.1 11 | - re2 ; We use the 2019-06-01 release, but we may have success with earlier versions 12 | - OpenImageIO 2.1.15 13 | - zlib 1.2.11 14 | 15 | To build Nuke 9 plugins, an older toolchain is required : 16 | - gcc 4.1.2 17 | - OpenEXR and IlmBase 2.2.0 18 | - re2 2016-02-01 19 | - OpenImageIO 1.6.18 20 | - zlib 1.2.11 21 | 22 | We handle these dependencies automatically handled through Conan and Docker. 23 | - install Conan and Docker 24 | - While updating Conan dependencies, the whole .conan/data are stored in the conan_data folder. This to avoid 25 | polluting your own .conan/data with our stuff. Chances are, you probably won't use gcc-4.8 anytime soon :) 26 | You can however control this destination on the host by setting the envionment variable $CONAN_DATA (e.g. "export CONAN_DATA=~/.conan/data"). 27 | - install the nuke versions you wish to support. Note that we've fixed the path to the NDK in the linux-docker-build.sh file. Feel free to suit your own installation. 28 | - run ./linux-docker-build.sh (in build_scripts/linux folder), which: 29 | * builds the docker image based on Centos6.6 (and also compiles gcc-4.8 and 4.1 and fetches all necessary dependencies) 30 | * updates the dependencies using Conan 31 | * and build all libs and plugins 32 | 33 | The resulting files are located in build/release. 34 | 35 | 36 | Alternatively, building with CMake: 37 | -------------------- 38 | 39 | In this "manual" mode, it is up to you to use conan or manually set your dependencies. From the openexrid root: 40 | 41 | $ mkdir -p build/release 42 | $ cd build/release 43 | $ cmake -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Release -D CMAKE_C_COMPILER=gcc-4.8 -D CMAKE_CXX_COMPILER=g++-4.8 ../../ 44 | $ make 45 | 46 | 47 | ***************************** 48 | * Compilation under Windows * 49 | ***************************** 50 | 51 | The build system is similar under windows. You need Visual Studio 2015 (and Visual Studio 2010 if you want to build Nuke plugins before Nuke 11). 52 | You need CMake 3.10, and Conan. 53 | For Nuke plugins building, Nuke installations should be accessible through environment variables 54 | "$NUKE111_DIR", "$NUKE112_DIR", "$NUKE113_DIR", "$NUKE120_DIR", "$NUKE121_DIR". 55 | In a shell such as git bash, run the script "build_scripts/build_windows.sh", which will grab the dependencies through Conan, and build libs and plugins with the appropriate compiler. 56 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | CMAKE_MINIMUM_REQUIRED(VERSION 3.10) 3 | PROJECT(openexrid) 4 | 5 | IF(NOT DEFINED BUILD_LIB) 6 | SET(BUILD_LIB 1) 7 | ENDIF() 8 | 9 | IF(NOT DEFINED BUILD_PLUGINS) 10 | SET(BUILD_PLUGINS 1) 11 | ENDIF() 12 | 13 | SET(OPENEXRID_ROOT "${CMAKE_CURRENT_LIST_DIR}") 14 | INCLUDE(cmake/compile_definitions.cmake) 15 | INCLUDE(cmake/output_folders.cmake) 16 | 17 | IF(USE_CONAN) 18 | IF(NOT DEFINED CONAN_BUILD_INFO_DIR) 19 | SET(CONAN_BUILD_INFO_DIR ${CMAKE_BINARY_DIR}) 20 | ENDIF() 21 | INCLUDE(${CONAN_BUILD_INFO_DIR}/conanbuildinfo.cmake) 22 | CONAN_BASIC_SETUP() 23 | SET(OPENEXR_LOCATION ${CONAN_OPENEXR_ROOT}) 24 | SET(OPENIMAGEIO_ROOT ${CONAN_OPENIMAGEIO_ROOT}) 25 | SET(BOOST_LIBRARIES ${CONAN_LIBS_BOOST}) 26 | SET(OFX_DIR ${CONAN_OPENFX_ROOT}) 27 | ENDIF() 28 | 29 | SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules) 30 | FIND_PACKAGE ( IlmBase REQUIRED ) 31 | FIND_PACKAGE ( OpenEXR REQUIRED ) 32 | FIND_PACKAGE ( ZLIB REQUIRED ) 33 | FIND_PACKAGE ( OpenGL REQUIRED ) 34 | 35 | IF(BUILD_PLUGINS) 36 | FIND_PACKAGE ( re2 REQUIRED ) 37 | FIND_PACKAGE ( OpenImageIO REQUIRED ) 38 | FIND_PACKAGE ( Threads REQUIRED ) 39 | FIND_PACKAGE ( Nuke111 ) 40 | FIND_PACKAGE ( Nuke112 ) 41 | FIND_PACKAGE ( Nuke113 ) 42 | FIND_PACKAGE ( Nuke120 ) 43 | FIND_PACKAGE ( Nuke121 ) 44 | FIND_PACKAGE ( Nuke122 ) 45 | FIND_PACKAGE ( Nuke130 ) 46 | FIND_PACKAGE ( Nuke132 ) 47 | FIND_PACKAGE ( Nuke140 ) 48 | FIND_PACKAGE ( Nuke151 ) 49 | FIND_PACKAGE ( Nuke160 ) 50 | FIND_PACKAGE ( OFX ) 51 | ENDIF() 52 | 53 | SET(CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo;Debug") 54 | 55 | 56 | message("CMAKE_CXX_STANDARD ${CMAKE_CXX_STANDARD}") 57 | 58 | #Use solution folders. 59 | SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON) 60 | 61 | # Compilation flags 62 | IF(WIN32) 63 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /MP") 64 | SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG /Zi") 65 | SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF") 66 | SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF") 67 | SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Ob0") 68 | SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG") 69 | ADD_COMPILE_DEFINITIONS(OPENEXRID_CONFIG=$(Configuration)) 70 | ELSEIF(UNIX) 71 | SET(CMAKE_POSITION_INDEPENDENT_CODE ON) 72 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC -MD -msse2 -fno-strict-aliasing -fno-omit-frame-pointer -Wno-deprecated") 73 | SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG -ggdb") 74 | SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O2 -DNDEBUG -ggdb") 75 | SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -D_DEBUG -ggdb") 76 | ADD_COMPILE_DEFINITIONS(OPENEXRID_CONFIG=${CMAKE_BUILD_TYPE}) 77 | ADD_COMPILE_DEFINITIONS(_FILE_OFFSET_BITS=64) 78 | ADD_COMPILE_DEFINITIONS(_LARGE_FILES) 79 | ADD_COMPILE_DEFINITIONS(linux) 80 | SET(CMAKE_SKIP_RPATH TRUE) 81 | ENDIF(WIN32) 82 | 83 | ##################### 84 | # Projects to compile 85 | 86 | IF(BUILD_LIB) 87 | ADD_SUBDIRECTORY (openexrid) 88 | ENDIF() 89 | 90 | IF(BUILD_PLUGINS) 91 | IF(OFX_FOUND) 92 | ADD_SUBDIRECTORY (openfx) 93 | ENDIF() 94 | IF(Nuke111_FOUND) 95 | ADD_SUBDIRECTORY (nuke11.1) 96 | ENDIF() 97 | IF(Nuke112_FOUND) 98 | ADD_SUBDIRECTORY (nuke11.2) 99 | ENDIF() 100 | IF(Nuke113_FOUND) 101 | ADD_SUBDIRECTORY (nuke11.3) 102 | ENDIF() 103 | IF(Nuke120_FOUND) 104 | ADD_SUBDIRECTORY (nuke12.0) 105 | ENDIF() 106 | IF(Nuke121_FOUND) 107 | ADD_SUBDIRECTORY (nuke12.1) 108 | ENDIF() 109 | IF(Nuke122_FOUND) 110 | ADD_SUBDIRECTORY (nuke12.2) 111 | ENDIF() 112 | IF(Nuke130_FOUND) 113 | ADD_SUBDIRECTORY (nuke13.0) 114 | ENDIF() 115 | IF(Nuke132_FOUND) 116 | ADD_SUBDIRECTORY (nuke13.2) 117 | ENDIF() 118 | IF(Nuke140_FOUND) 119 | ADD_SUBDIRECTORY (nuke14.0) 120 | ENDIF() 121 | IF(Nuke151_FOUND) 122 | ADD_SUBDIRECTORY (nuke15.1) 123 | ENDIF() 124 | IF(Nuke160_FOUND) 125 | ADD_SUBDIRECTORY (nuke16.0) 126 | ENDIF() 127 | ENDIF() 128 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2106 Mercenaries Engineering SARL 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MercenariesEngineering/openexrid/1ec6dff08714876f1a6f15added25d26f49270ac/README.md -------------------------------------------------------------------------------- /build_tools/conan_profile_linux_gcc4.8: -------------------------------------------------------------------------------- 1 | [settings] 2 | os=Linux 3 | os_build=Linux 4 | arch=x86_64 5 | arch_build=x86_64 6 | compiler=gcc 7 | compiler.version=4.8 8 | compiler.libcxx=libstdc++11 9 | compiler.cppstd=11 10 | build_type=Release 11 | [options] 12 | [build_requires] 13 | [env] 14 | CC=gcc-4.8 15 | CXX=g++-4.8 16 | -------------------------------------------------------------------------------- /build_tools/conan_profile_linux_gcc9.3: -------------------------------------------------------------------------------- 1 | [settings] 2 | os=Linux 3 | os_build=Linux 4 | arch=x86_64 5 | arch_build=x86_64 6 | compiler=gcc 7 | compiler.version=9 8 | compiler.libcxx=libstdc++ 9 | build_type=Release 10 | [options] 11 | [build_requires] 12 | cmake/3.17.3@mercseng/v0 13 | [env] 14 | CC=/usr/local/bin/gcc 15 | CXX=/usr/local/bin/g++ 16 | -------------------------------------------------------------------------------- /build_tools/conan_profile_windows_vs2015: -------------------------------------------------------------------------------- 1 | [settings] 2 | os=Windows 3 | os_build=Windows 4 | arch=x86_64 5 | arch_build=x86_64 6 | compiler=Visual Studio 7 | compiler.version=14 8 | build_type=Release 9 | [options] 10 | [build_requires] 11 | [env] 12 | MSVC_VER="Visual Studio 14 2015" 13 | MSVC_ARCH="x64" 14 | -------------------------------------------------------------------------------- /build_tools/conan_profile_windows_vs2019: -------------------------------------------------------------------------------- 1 | [settings] 2 | os=Windows 3 | os_build=Windows 4 | arch=x86_64 5 | arch_build=x86_64 6 | compiler=Visual Studio 7 | compiler.version=16 8 | build_type=Release 9 | [options] 10 | [build_requires] 11 | [env] 12 | MSVC_VER="Visual Studio 16 2019" 13 | MSVC_ARCH="x64" 14 | -------------------------------------------------------------------------------- /build_tools/installer.py: -------------------------------------------------------------------------------- 1 | import tempfile, shutil, os, re, platform, zipfile 2 | 3 | def get_version (): 4 | file = open("openexrid/Version.h", "r") 5 | for line in file: 6 | version = re.search("Version\s*=\s*\"([^\"]+)", line) 7 | if version: 8 | return version.group(1) 9 | 10 | def strip (path): 11 | if platform.system() == "Linux": 12 | print ("strip " + path) 13 | os.system ("strip " + path) 14 | 15 | version = get_version () 16 | ofx_plateform = "Win64" if platform.system() == "Windows" else "Linux-x86-64" 17 | ofx_dst = "openfx/openexrid.ofx.bundle/Contents/" + ofx_plateform 18 | zipfile_platform = "win64" if platform.system() == "Windows" else "linux" 19 | so_ext = ".dll" if platform.system() == "Windows" else ".so" 20 | archive_type = "zip" if platform.system() == "Windows" else "gztar" 21 | 22 | nuke_versions = [] 23 | for x in os.listdir("build/release/lib"): 24 | if re.match("nuke[0-9.]+", x): 25 | nuke_versions.append (x) 26 | 27 | cwd = os.getcwd() 28 | tmpdir = tempfile.mkdtemp () 29 | os.chdir (tmpdir) 30 | zip_filename = cwd + "/openexrid-" + version + "-" + zipfile_platform 31 | print ("Archiving in "+tmpdir+", output file is "+zip_filename) 32 | 33 | try: 34 | os.mkdir ("openexrid") 35 | 36 | if os.path.exists(cwd + "/build/release/lib/openexrid.ofx"): 37 | os.makedirs ("openexrid/"+ofx_dst) 38 | shutil.copy (cwd + "/build/release/lib/openexrid.ofx", "openexrid/"+ofx_dst) 39 | strip ("openexrid/" + ofx_dst + "/openexrid.ofx") 40 | else: 41 | if os.path.exists(cwd + "/build/release/lib/OFX/openexrid.ofx"): 42 | os.makedirs ("openexrid/OFX/"+ofx_dst) 43 | shutil.copy (cwd + "/build/release/lib/OFX/openexrid.ofx", "openexrid/OFX/"+ofx_dst) 44 | strip ("openexrid/OFX/" + ofx_dst + "/openexrid.ofx") 45 | 46 | shutil.copy (cwd + "/LICENSE", "openexrid/") 47 | 48 | for nuke in nuke_versions: 49 | if os.path.exists(cwd + "/build/release/lib/" + nuke + "/DeepOpenEXRId" + so_ext): 50 | os.mkdir ("openexrid/"+nuke) 51 | shutil.copy (cwd + "/build/release/lib/" + nuke + "/DeepOpenEXRId" + so_ext, "openexrid/"+nuke) 52 | strip ("openexrid/"+nuke + "/DeepOpenEXRId" + so_ext) 53 | shutil.copy (cwd + "/nuke/menu.py", "openexrid/"+nuke) 54 | 55 | shutil.make_archive (zip_filename, archive_type, ".", "openexrid") 56 | 57 | finally: 58 | os.chdir (cwd) 59 | shutil.rmtree (tmpdir) 60 | -------------------------------------------------------------------------------- /build_tools/linux/build-conan.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | THIS_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | BUILD_ROOT=${THIS_DIRECTORY}/../.. 7 | cd ${BUILD_ROOT} 8 | 9 | conan remote add mercenaries http://c3dcoodq1.mercs-eng.com:8081/artifactory/api/conan/conan_packages --insert 0 --force 10 | conan remote add guerilla_legacy http://c3dcoodq1.mercs-eng.com:8081/artifactory/api/conan/guerilla_legacy --insert 1 --force 11 | ./build.sh --installer 12 | -------------------------------------------------------------------------------- /build_tools/linux/docker_14plus/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mercenaries/mercseng:1.1 2 | ENV CONAN_USER_HOME=/builder 3 | 4 | RUN yum -y install mesa-libGL-devel mesa-libGLU-devel 5 | 6 | #setup a conan installation every user can use 7 | RUN rm -rf /root/.conan && mkdir -p /builder/.conan/profiles \ 8 | && printf "[settings]\nos=Linux\nos_build=Linux\narch=x86_64\narch_build=x86_64\ncompiler=gcc\ncompiler.version=9\ncompiler.libcxx=libstdc++\nbuild_type=Release\n" > /builder/.conan/profiles/default \ 9 | && chmod 777 -R /builder 10 | -------------------------------------------------------------------------------- /build_tools/linux/docker_9_13/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:6.6 2 | 3 | # Initial bootstrapping 4 | COPY bootstrap.sh /build/ 5 | RUN /build/bootstrap.sh 6 | 7 | COPY get-pip.py /build/ 8 | COPY extra-bootstrap.sh /build/ 9 | RUN /build/extra-bootstrap.sh 10 | ENV PATH=/usr/local/patch-2.7.6/bin:${PATH} 11 | ENV PATH=/usr/local/binutils-2.30/bin:${PATH} 12 | 13 | COPY cmake-bootstrap.sh /build/ 14 | RUN /build/cmake-bootstrap.sh 15 | ENV CMAKE_ROOT=/usr/local/cmake-3.16.8 16 | ENV CMAKE_MODULE_PATH=${CMAKE_ROOT}/share/cmake-3.16/Modules 17 | ENV PATH=${CMAKE_ROOT}/bin:${PATH} 18 | 19 | ENV CONAN_USER_HOME=/conan 20 | COPY conan_profile_linux_gcc_4.8 ${CONAN_USER_HOME}/.conan/profiles/default 21 | COPY conan-bootstrap.sh /build/ 22 | RUN /build/conan-bootstrap.sh 23 | 24 | COPY entrypoint.sh /build/ 25 | ENTRYPOINT [ "/build/entrypoint.sh" ] 26 | -------------------------------------------------------------------------------- /build_tools/linux/docker_9_13/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | this_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | 4 | set -e 5 | 6 | # load keys to avoid annoying messages 7 | rpm --import http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-6 8 | rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6 9 | # grant access to EPEL 10 | yum -y install http://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm 11 | # make sure we do not use https for EPEL since it is not correctly handled 12 | sed -i 's/mirrorlist=https/mirrorlist=http/' /etc/yum.repos.d/epel.repo 13 | # update trusted root certificates 14 | yum -y update ca-certificates --disablerepo=epel 15 | # install vim 16 | yum -y install vim 17 | # install SCL 18 | yum -y install centos-release-scl 19 | # install new linux headers 20 | yum -y install kernel-headers 21 | # install new glibc (this is the first release that works for every dependences) 22 | #rpm -Uvh $sources_dir/glibc-2.17-55.el6.x86_64.rpm $sources_dir/glibc-common-2.17-55.el6.x86_64.rpm $sources_dir/glibc-devel-2.17-55.el6.x86_64.rpm $sources_dir/glibc-headers-2.17-55.el6.x86_64.rpm && 23 | # install any required tool from repositories 24 | yum -y install cmake3 bison flex tar bzip2 file wget patch nasm 25 | # update SSL stuff 26 | yum update -y nss curl libcurl 27 | 28 | yum -y install gcc-c++.x86_64 29 | g++ --version 30 | 31 | # Download gcc 4.1.2 and 4.8.2 32 | mkdir -p /build 33 | cd /build 34 | 35 | wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/releases/gcc-4.1.2/gcc-4.1.2.tar.gz 36 | tar zxf gcc-4.1.2.tar.gz 37 | 38 | # build custom gcc-4.8.2 39 | wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/releases/gcc-4.8.2/gcc-4.8.2.tar.gz 40 | tar zxf gcc-4.8.2.tar.gz 41 | 42 | wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/infrastructure/gmp-4.3.2.tar.bz2 43 | tar jxf gmp-4.3.2.tar.bz2 44 | mv gmp-4.3.2 gcc-4.8.2/gmp 45 | 46 | wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/infrastructure/mpc-0.8.1.tar.gz 47 | tar zxf mpc-0.8.1.tar.gz 48 | mv mpc-0.8.1 gcc-4.8.2/mpc 49 | 50 | wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/infrastructure/mpfr-2.4.2.tar.bz2 51 | tar jxf mpfr-2.4.2.tar.bz2 52 | mv mpfr-2.4.2 gcc-4.8.2/mpfr 53 | 54 | export CC=gcc 55 | export CXX=g++ 56 | 57 | # build custom gcc-4.8.2 58 | mkdir -p /build/gcc-4.8.2-build 59 | cd /build/gcc-4.8.2-build 60 | ../gcc-4.8.2/configure --prefix=/usr/local/gcc-4.8.2 --enable-languages=c,c++ --disable-multilib 61 | make -j`nproc` 62 | make install 63 | 64 | # build custom gcc-4.1.2 (nuke9) 65 | mkdir -p /build/gcc-4.1.2-build 66 | cd /build/gcc-4.1.2-build 67 | ../gcc-4.1.2/configure --prefix=/usr/local/gcc-4.1.2 --enable-languages=c,c++ --disable-multilib 68 | make -j`nproc` 69 | make install 70 | 71 | # clean up 72 | cd /build 73 | rm -rf gcc-4.8.2 gcc-4.1.2 gcc-4.8.2-build gcc-4.1.2-build 74 | -------------------------------------------------------------------------------- /build_tools/linux/docker_9_13/cmake-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | this_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | 4 | set -e 5 | 6 | # Download cmake 3.16.8 binaries 7 | cd /tmp 8 | wget https://github.com/Kitware/CMake/releases/download/v3.16.8/cmake-3.16.8-Linux-x86_64.tar.gz 9 | tar zxf cmake-3.16.8-Linux-x86_64.tar.gz 10 | mv cmake-3.16.8-Linux-x86_64 /usr/local/cmake-3.16.8 11 | rm -rf cmake-3.16.8-Linux-x86_64.tar.gz 12 | -------------------------------------------------------------------------------- /build_tools/linux/docker_9_13/conan-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | this_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | 4 | set -e 5 | 6 | # install conan 7 | scl enable rh-python35 "pip install conan==1.27.1" 8 | 9 | chmod -R 777 ${CONAN_USER_HOME} 10 | -------------------------------------------------------------------------------- /build_tools/linux/docker_9_13/conan_profile_linux_gcc_4.8: -------------------------------------------------------------------------------- 1 | [settings] 2 | os=Linux 3 | os_build=Linux 4 | arch=x86_64 5 | arch_build=x86_64 6 | compiler=gcc 7 | compiler.version=4.8 8 | compiler.libcxx=libstdc++11 9 | compiler.cppstd=11 10 | build_type=Release 11 | [options] 12 | [build_requires] 13 | [env] 14 | CC=gcc-4.8 15 | CXX=g++-4.8 16 | -------------------------------------------------------------------------------- /build_tools/linux/docker_9_13/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | cd /openexrid 4 | scl enable rh-python35 "exec $@" 5 | -------------------------------------------------------------------------------- /build_tools/linux/docker_9_13/extra-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | this_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | 4 | set -e 5 | 6 | ln -s /usr/local/gcc-4.1.2/bin/gcc /usr/bin/gcc-4.1 7 | ln -s /usr/local/gcc-4.1.2/bin/g++ /usr/bin/g++-4.1 8 | ln -s /usr/local/gcc-4.8.2/bin/gcc /usr/bin/gcc-4.8 9 | ln -s /usr/local/gcc-4.8.2/bin/g++ /usr/bin/g++-4.8 10 | 11 | yum -y install mesa-libGL-devel mesa-libGLU-devel rh-python35 sclo-git212 12 | 13 | # grab a fresh version of pip for python 3.5 14 | scl enable rh-python35 "python $this_directory/get-pip.py" 15 | scl enable rh-python35 "python -m pip install --upgrade setuptools" 16 | 17 | # Download patch 2.7.6 and compile 18 | cd /tmp 19 | wget http://ftp.gnu.org/gnu/patch/patch-2.7.6.tar.gz 20 | tar zxf patch-2.7.6.tar.gz 21 | rm -rf patch-2.7.6.tar.gz 22 | mkdir build 23 | ls -la /tmp/patch-2.7.6 24 | /tmp/patch-2.7.6/configure --prefix=/usr/local/patch-2.7.6 25 | make 26 | make install 27 | cd /tmp 28 | rm -rf build patch-2.7.6 29 | 30 | # Download binutils 2.30 and compile 31 | cd /tmp 32 | wget http://ftp.gnu.org/gnu/binutils/binutils-2.30.tar.gz 33 | tar zxf binutils-2.30.tar.gz 34 | rm -rf binutils-2.30.tar.gz 35 | mkdir build 36 | cd build 37 | /tmp/binutils-2.30/configure --prefix=/usr/local/binutils-2.30 38 | make 39 | make install 40 | cd /tmp 41 | rm -rf build binutils-2.30 42 | 43 | -------------------------------------------------------------------------------- /build_tools/linux/docker_9_13/gcc-4.1.2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | this_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | 4 | set -e 5 | 6 | export build_dir=/tmp/gcc-4.8.2 7 | 8 | # Download gcc 4.1.2 9 | mkdir -p $build_dir 10 | cd $build_dir 11 | 12 | wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/releases/gcc-4.1.2/gcc-4.1.2.tar.gz 13 | tar zxf gcc-4.1.2.tar.gz 14 | 15 | export CC=gcc 16 | export CXX=g++ 17 | 18 | # build custom gcc-4.1.2 (nuke9) 19 | mkdir -p $build_dir/build 20 | cd $build_dir/build 21 | ../gcc-4.1.2/configure --prefix=/usr/local/gcc-4.1.2 --enable-languages=c,c++ --disable-multilib 22 | make -j`nproc` 23 | make install 24 | 25 | # clean up 26 | cd / 27 | rm -rf $build_dir 28 | 29 | ln -s /usr/local/gcc-4.1.2/bin/gcc /usr/bin/gcc-4.1 30 | ln -s /usr/local/gcc-4.1.2/bin/g++ /usr/bin/g++-4.1 31 | -------------------------------------------------------------------------------- /build_tools/linux/docker_9_13/gcc-4.8.2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | this_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | 4 | set -e 5 | 6 | export build_dir=/tmp/gcc-4.8.2 7 | 8 | # Download gcc 4.8.2 9 | mkdir -p $build_dir 10 | cd $build_dir 11 | 12 | # build custom gcc-4.8.2 13 | wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/releases/gcc-4.8.2/gcc-4.8.2.tar.gz 14 | tar zxf gcc-4.8.2.tar.gz 15 | 16 | wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/infrastructure/gmp-4.3.2.tar.bz2 17 | tar jxf gmp-4.3.2.tar.bz2 18 | mv gmp-4.3.2 gcc-4.8.2/gmp 19 | 20 | wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/infrastructure/mpc-0.8.1.tar.gz 21 | tar zxf mpc-0.8.1.tar.gz 22 | mv mpc-0.8.1 gcc-4.8.2/mpc 23 | 24 | wget ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/infrastructure/mpfr-2.4.2.tar.bz2 25 | tar jxf mpfr-2.4.2.tar.bz2 26 | mv mpfr-2.4.2 gcc-4.8.2/mpfr 27 | 28 | export CC=gcc 29 | export CXX=g++ 30 | 31 | # build custom gcc-4.8.2 32 | mkdir -p $build_dir/build 33 | cd $build_dir/build 34 | ../gcc-4.8.2/configure --prefix=/usr/local/gcc-4.8.2 --enable-languages=c,c++ --disable-multilib 35 | make -j`nproc` 36 | make install 37 | 38 | # clean up 39 | cd / 40 | rm -rf $build_dir 41 | 42 | ln -s /usr/local/gcc-4.8.2/bin/gcc /usr/bin/gcc-4.8 43 | ln -s /usr/local/gcc-4.8.2/bin/g++ /usr/bin/g++-4.8 44 | -------------------------------------------------------------------------------- /build_tools/linux/linux-docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # MANDATORY ENV VARS: 4 | # OPENFX: the folder to the openfx libs and includes 5 | 6 | # Note: run the docker as root with 7 | # docker run --rm -it "linux-openexrid-builder" bash 8 | set -e 9 | 10 | this_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 11 | 12 | # Build the docker images 13 | docker build -t "openexrid-9-13-builder" "${this_directory}/docker_9_13" --rm 14 | 15 | docker build -t "openexrid-14plus-builder" "${this_directory}/docker_14plus" --rm 16 | 17 | nukes="" 18 | for nuke in `ls -d /usr/local/Nuke*` ; do 19 | nukes="$nukes -v $nuke:$nuke" 20 | done 21 | 22 | docker run --rm -it \ 23 | -u $(id -u):$(id -g) \ 24 | -v "${this_directory}/../..:/openexrid" \ 25 | -v "$CONAN_USER_HOME/.conan/data:/conan/.conan/data" \ 26 | -e build48=1 \ 27 | $nukes \ 28 | "openexrid-9-13-builder" "scl enable sclo-git212 /openexrid/build_tools/linux/build-conan.sh" 29 | 30 | docker run --rm -it \ 31 | -u $(id -u):$(id -g) \ 32 | -v "${this_directory}/../..:/openexrid" \ 33 | -v "$CONAN_USER_HOME/.conan/data:/builder/.conan/data" \ 34 | -e build93=1 \ 35 | $nukes \ 36 | "openexrid-14plus-builder" "/openexrid/build_tools/linux/build-conan.sh" 37 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke111.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE111_LIBRARY DDImage 5 | ${NUKE111_DIR} 6 | $ENV{NUKE111_DIR} 7 | "C:/Program\ Files/Nuke\ 11.1v1" 8 | "C:/Program\ Files/Nuke\ 11.1v2" 9 | "C:/Program\ Files/Nuke\ 11.1v3" 10 | "C:/Program\ Files/Nuke\ 11.1v4" 11 | "C:/Program\ Files/Nuke\ 11.1v5" 12 | "C:/Program\ Files/Nuke\ 11.1v6" 13 | "C:/Program\ Files/Nuke\ 11.1v7" 14 | "C:/Program\ Files/Nuke\ 11.1v8" 15 | ) 16 | 17 | ELSEIF(UNIX) 18 | 19 | find_library (DDIMAGE111_LIBRARY DDImage 20 | ${NUKE111_DIR} 21 | $ENV{NUKE111_DIR} 22 | "/usr/local/Nuke11.1v1" 23 | "/usr/local/Nuke11.1v2" 24 | "/usr/local/Nuke11.1v3" 25 | "/usr/local/Nuke11.1v4" 26 | "/usr/local/Nuke11.1v5" 27 | "/usr/local/Nuke11.1v6" 28 | "/usr/local/Nuke11.1v7" 29 | "/usr/local/Nuke11.1v8" 30 | ) 31 | 32 | ENDIF() 33 | 34 | get_filename_component (NUKE111_LIBRARY_DIR ${DDIMAGE111_LIBRARY} DIRECTORY) 35 | find_path (NUKE111_INCLUDE_DIR DDImage/Op.h ${NUKE111_LIBRARY_DIR}/include) 36 | 37 | INCLUDE(FindPackageHandleStandardArgs) 38 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke111 DEFAULT_MSG 39 | DDIMAGE111_LIBRARY NUKE111_LIBRARY_DIR NUKE111_INCLUDE_DIR 40 | ) 41 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke112.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE112_LIBRARY DDImage 5 | ${NUKE112_DIR} 6 | $ENV{NUKE112_DIR} 7 | "C:/Program\ Files/Nuke\ 11.2v1" 8 | "C:/Program\ Files/Nuke\ 11.2v2" 9 | "C:/Program\ Files/Nuke\ 11.2v3" 10 | "C:/Program\ Files/Nuke\ 11.2v4" 11 | "C:/Program\ Files/Nuke\ 11.2v5" 12 | "C:/Program\ Files/Nuke\ 11.2v6" 13 | "C:/Program\ Files/Nuke\ 11.2v7" 14 | "C:/Program\ Files/Nuke\ 11.2v8" 15 | ) 16 | 17 | ELSEIF(UNIX) 18 | 19 | find_library (DDIMAGE112_LIBRARY DDImage 20 | ${NUKE112_DIR} 21 | $ENV{NUKE112_DIR} 22 | "/usr/local/Nuke11.2v1" 23 | "/usr/local/Nuke11.2v2" 24 | "/usr/local/Nuke11.2v3" 25 | "/usr/local/Nuke11.2v4" 26 | "/usr/local/Nuke11.2v5" 27 | "/usr/local/Nuke11.2v6" 28 | "/usr/local/Nuke11.2v7" 29 | "/usr/local/Nuke11.2v8" 30 | ) 31 | 32 | ENDIF() 33 | 34 | get_filename_component (NUKE112_LIBRARY_DIR ${DDIMAGE112_LIBRARY} DIRECTORY) 35 | find_path (NUKE112_INCLUDE_DIR DDImage/Op.h ${NUKE112_LIBRARY_DIR}/include) 36 | 37 | INCLUDE(FindPackageHandleStandardArgs) 38 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke112 DEFAULT_MSG 39 | DDIMAGE112_LIBRARY NUKE112_LIBRARY_DIR NUKE112_INCLUDE_DIR 40 | ) 41 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke113.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE113_LIBRARY DDImage 5 | ${NUKE113_DIR} 6 | $ENV{NUKE113_DIR} 7 | "C:/Program\ Files/Nuke\ 11.3v1" 8 | "C:/Program\ Files/Nuke\ 11.3v2" 9 | "C:/Program\ Files/Nuke\ 11.3v3" 10 | "C:/Program\ Files/Nuke\ 11.3v4" 11 | "C:/Program\ Files/Nuke\ 11.3v5" 12 | "C:/Program\ Files/Nuke\ 11.3v6" 13 | "C:/Program\ Files/Nuke\ 11.3v7" 14 | "C:/Program\ Files/Nuke\ 11.3v8" 15 | ) 16 | 17 | ELSEIF(UNIX) 18 | 19 | find_library (DDIMAGE113_LIBRARY DDImage 20 | ${NUKE113_DIR} 21 | $ENV{NUKE113_DIR} 22 | "/usr/local/Nuke11.3v1" 23 | "/usr/local/Nuke11.3v2" 24 | "/usr/local/Nuke11.3v3" 25 | "/usr/local/Nuke11.3v4" 26 | "/usr/local/Nuke11.3v5" 27 | "/usr/local/Nuke11.3v6" 28 | "/usr/local/Nuke11.3v7" 29 | "/usr/local/Nuke11.3v8" 30 | ) 31 | 32 | ENDIF() 33 | 34 | get_filename_component (NUKE113_LIBRARY_DIR ${DDIMAGE113_LIBRARY} DIRECTORY) 35 | find_path (NUKE113_INCLUDE_DIR DDImage/Op.h ${NUKE113_LIBRARY_DIR}/include) 36 | 37 | INCLUDE(FindPackageHandleStandardArgs) 38 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke113 DEFAULT_MSG 39 | DDIMAGE113_LIBRARY NUKE113_LIBRARY_DIR NUKE113_INCLUDE_DIR 40 | ) 41 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke120.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE120_LIBRARY DDImage 5 | ${NUKE120_DIR} 6 | $ENV{NUKE120_DIR} 7 | "C:/Program\ Files/Nuke\ 12.0v1" 8 | "C:/Program\ Files/Nuke\ 12.0v2" 9 | "C:/Program\ Files/Nuke\ 12.0v3" 10 | "C:/Program\ Files/Nuke\ 12.0v4" 11 | "C:/Program\ Files/Nuke\ 12.0v5" 12 | "C:/Program\ Files/Nuke\ 12.0v6" 13 | "C:/Program\ Files/Nuke\ 12.0v7" 14 | "C:/Program\ Files/Nuke\ 12.0v8" 15 | ) 16 | 17 | ELSEIF(UNIX) 18 | 19 | find_library (DDIMAGE120_LIBRARY DDImage 20 | ${NUKE120_DIR} 21 | $ENV{NUKE120_DIR} 22 | "/usr/local/Nuke12.0v1" 23 | "/usr/local/Nuke12.0v2" 24 | "/usr/local/Nuke12.0v3" 25 | "/usr/local/Nuke12.0v4" 26 | "/usr/local/Nuke12.0v5" 27 | "/usr/local/Nuke12.0v6" 28 | "/usr/local/Nuke12.0v7" 29 | "/usr/local/Nuke12.0v8" 30 | ) 31 | 32 | ENDIF() 33 | 34 | get_filename_component (NUKE120_LIBRARY_DIR ${DDIMAGE120_LIBRARY} DIRECTORY) 35 | find_path (NUKE120_INCLUDE_DIR DDImage/Op.h ${NUKE120_LIBRARY_DIR}/include) 36 | 37 | INCLUDE(FindPackageHandleStandardArgs) 38 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke120 DEFAULT_MSG 39 | DDIMAGE120_LIBRARY NUKE120_LIBRARY_DIR NUKE120_INCLUDE_DIR 40 | ) 41 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke121.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE121_LIBRARY DDImage 5 | ${NUKE121_DIR} 6 | $ENV{NUKE121_DIR} 7 | "C:/Program\ Files/Nuke\ 12.1v1" 8 | "C:/Program\ Files/Nuke\ 12.1v2" 9 | "C:/Program\ Files/Nuke\ 12.1v3" 10 | "C:/Program\ Files/Nuke\ 12.1v4" 11 | "C:/Program\ Files/Nuke\ 12.1v5" 12 | "C:/Program\ Files/Nuke\ 12.1v6" 13 | "C:/Program\ Files/Nuke\ 12.1v7" 14 | "C:/Program\ Files/Nuke\ 12.1v8" 15 | ) 16 | 17 | ELSEIF(UNIX) 18 | 19 | find_library (DDIMAGE121_LIBRARY DDImage 20 | ${NUKE121_DIR} 21 | $ENV{NUKE121_DIR} 22 | "/usr/local/Nuke12.1v1" 23 | "/usr/local/Nuke12.1v2" 24 | "/usr/local/Nuke12.1v3" 25 | "/usr/local/Nuke12.1v4" 26 | "/usr/local/Nuke12.1v5" 27 | "/usr/local/Nuke12.1v6" 28 | "/usr/local/Nuke12.1v7" 29 | "/usr/local/Nuke12.1v8" 30 | ) 31 | 32 | ENDIF() 33 | 34 | get_filename_component (NUKE121_LIBRARY_DIR ${DDIMAGE121_LIBRARY} DIRECTORY) 35 | find_path (NUKE121_INCLUDE_DIR DDImage/Op.h ${NUKE121_LIBRARY_DIR}/include) 36 | 37 | INCLUDE(FindPackageHandleStandardArgs) 38 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke121 DEFAULT_MSG 39 | DDIMAGE121_LIBRARY NUKE121_LIBRARY_DIR NUKE121_INCLUDE_DIR 40 | ) 41 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke122.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE122_LIBRARY DDImage 5 | ${NUKE122_DIR} 6 | $ENV{NUKE122_DIR} 7 | "C:/Program\ Files/Nuke\ 12.2v1" 8 | "C:/Program\ Files/Nuke\ 12.2v2" 9 | "C:/Program\ Files/Nuke\ 12.2v3" 10 | "C:/Program\ Files/Nuke\ 12.2v4" 11 | "C:/Program\ Files/Nuke\ 12.2v5" 12 | "C:/Program\ Files/Nuke\ 12.2v6" 13 | "C:/Program\ Files/Nuke\ 12.2v7" 14 | "C:/Program\ Files/Nuke\ 12.2v8" 15 | "C:/Program\ Files/Nuke\ 12.2v9" 16 | ) 17 | 18 | ELSEIF(UNIX) 19 | 20 | find_library (DDIMAGE122_LIBRARY DDImage 21 | ${NUKE122_DIR} 22 | $ENV{NUKE122_DIR} 23 | "/usr/local/Nuke12.2v1" 24 | "/usr/local/Nuke12.2v2" 25 | "/usr/local/Nuke12.2v3" 26 | "/usr/local/Nuke12.2v4" 27 | "/usr/local/Nuke12.2v5" 28 | "/usr/local/Nuke12.2v6" 29 | "/usr/local/Nuke12.2v7" 30 | "/usr/local/Nuke12.2v8" 31 | "/usr/local/Nuke12.2v9" 32 | ) 33 | 34 | ENDIF() 35 | 36 | get_filename_component (NUKE122_LIBRARY_DIR ${DDIMAGE122_LIBRARY} DIRECTORY) 37 | find_path (NUKE122_INCLUDE_DIR DDImage/Op.h ${NUKE122_LIBRARY_DIR}/include) 38 | 39 | INCLUDE(FindPackageHandleStandardArgs) 40 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke122 DEFAULT_MSG 41 | DDIMAGE122_LIBRARY NUKE122_LIBRARY_DIR NUKE122_INCLUDE_DIR 42 | ) 43 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke130.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE130_LIBRARY DDImage 5 | ${NUKE130_DIR} 6 | $ENV{NUKE130_DIR} 7 | "C:/Program\ Files/Nuke\ 13.0v1" 8 | "C:/Program\ Files/Nuke\ 13.0v2" 9 | "C:/Program\ Files/Nuke\ 13.0v3" 10 | "C:/Program\ Files/Nuke\ 13.0v4" 11 | "C:/Program\ Files/Nuke\ 13.0v5" 12 | "C:/Program\ Files/Nuke\ 13.0v6" 13 | "C:/Program\ Files/Nuke\ 13.0v7" 14 | "C:/Program\ Files/Nuke\ 13.0v8" 15 | "C:/Program\ Files/Nuke\ 13.0v9" 16 | ) 17 | 18 | ELSEIF(UNIX) 19 | 20 | find_library (DDIMAGE130_LIBRARY DDImage 21 | ${NUKE130_DIR} 22 | $ENV{NUKE130_DIR} 23 | "/usr/local/Nuke13.0v1" 24 | "/usr/local/Nuke13.0v2" 25 | "/usr/local/Nuke13.0v3" 26 | "/usr/local/Nuke13.0v4" 27 | "/usr/local/Nuke13.0v5" 28 | "/usr/local/Nuke13.0v6" 29 | "/usr/local/Nuke13.0v7" 30 | "/usr/local/Nuke13.0v8" 31 | "/usr/local/Nuke13.0v9" 32 | ) 33 | 34 | ENDIF() 35 | 36 | get_filename_component (NUKE130_LIBRARY_DIR ${DDIMAGE130_LIBRARY} DIRECTORY) 37 | find_path (NUKE130_INCLUDE_DIR DDImage/Op.h ${NUKE130_LIBRARY_DIR}/include) 38 | 39 | INCLUDE(FindPackageHandleStandardArgs) 40 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke130 DEFAULT_MSG 41 | DDIMAGE130_LIBRARY NUKE130_LIBRARY_DIR NUKE130_INCLUDE_DIR 42 | ) 43 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke132.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE132_LIBRARY DDImage 5 | ${NUKE132_DIR} 6 | $ENV{NUKE132_DIR} 7 | "C:/Program\ Files/Nuke\ 13.2v1" 8 | "C:/Program\ Files/Nuke\ 13.2v2" 9 | "C:/Program\ Files/Nuke\ 13.2v3" 10 | "C:/Program\ Files/Nuke\ 13.2v4" 11 | "C:/Program\ Files/Nuke\ 13.2v5" 12 | "C:/Program\ Files/Nuke\ 13.2v6" 13 | "C:/Program\ Files/Nuke\ 13.2v7" 14 | "C:/Program\ Files/Nuke\ 13.2v8" 15 | "C:/Program\ Files/Nuke\ 13.2v9" 16 | ) 17 | 18 | ELSEIF(UNIX) 19 | 20 | find_library (DDIMAGE132_LIBRARY DDImage 21 | ${NUKE132_DIR} 22 | $ENV{NUKE132_DIR} 23 | "/usr/local/Nuke13.2v1" 24 | "/usr/local/Nuke13.2v2" 25 | "/usr/local/Nuke13.2v3" 26 | "/usr/local/Nuke13.2v4" 27 | "/usr/local/Nuke13.2v5" 28 | "/usr/local/Nuke13.2v6" 29 | "/usr/local/Nuke13.2v7" 30 | "/usr/local/Nuke13.2v8" 31 | "/usr/local/Nuke13.2v9" 32 | ) 33 | 34 | ENDIF() 35 | 36 | get_filename_component (NUKE132_LIBRARY_DIR ${DDIMAGE132_LIBRARY} DIRECTORY) 37 | find_path (NUKE132_INCLUDE_DIR DDImage/Op.h ${NUKE132_LIBRARY_DIR}/include) 38 | 39 | INCLUDE(FindPackageHandleStandardArgs) 40 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke132 DEFAULT_MSG 41 | DDIMAGE132_LIBRARY NUKE132_LIBRARY_DIR NUKE132_INCLUDE_DIR 42 | ) 43 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke140.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE140_LIBRARY DDImage 5 | ${NUKE140_DIR} 6 | $ENV{NUKE140_DIR} 7 | "C:/Program\ Files/Nuke\ 14.0v1" 8 | "C:/Program\ Files/Nuke\ 14.0v2" 9 | "C:/Program\ Files/Nuke\ 14.0v3" 10 | "C:/Program\ Files/Nuke\ 14.0v4" 11 | "C:/Program\ Files/Nuke\ 14.0v5" 12 | "C:/Program\ Files/Nuke\ 14.0v6" 13 | "C:/Program\ Files/Nuke\ 14.0v7" 14 | "C:/Program\ Files/Nuke\ 14.0v8" 15 | "C:/Program\ Files/Nuke\ 14.0v9" 16 | ) 17 | 18 | ELSEIF(UNIX) 19 | 20 | find_library (DDIMAGE140_LIBRARY DDImage 21 | ${NUKE140_DIR} 22 | $ENV{NUKE140_DIR} 23 | "/usr/local/Nuke14.0v1" 24 | "/usr/local/Nuke14.0v2" 25 | "/usr/local/Nuke14.0v3" 26 | "/usr/local/Nuke14.0v4" 27 | "/usr/local/Nuke14.0v5" 28 | "/usr/local/Nuke14.0v6" 29 | "/usr/local/Nuke14.0v7" 30 | "/usr/local/Nuke14.0v8" 31 | "/usr/local/Nuke14.0v9" 32 | ) 33 | 34 | ENDIF() 35 | 36 | get_filename_component (NUKE140_LIBRARY_DIR ${DDIMAGE140_LIBRARY} DIRECTORY) 37 | find_path (NUKE140_INCLUDE_DIR DDImage/Op.h ${NUKE140_LIBRARY_DIR}/include) 38 | 39 | INCLUDE(FindPackageHandleStandardArgs) 40 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke140 DEFAULT_MSG 41 | DDIMAGE140_LIBRARY NUKE140_LIBRARY_DIR NUKE140_INCLUDE_DIR 42 | ) 43 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke151.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE151_LIBRARY DDImage 5 | ${NUKE151_DIR} 6 | $ENV{NUKE151_DIR} 7 | "C:/Program\ Files/Nuke\ 15.1v1" 8 | "C:/Program\ Files/Nuke\ 15.1v2" 9 | "C:/Program\ Files/Nuke\ 15.1v3" 10 | "C:/Program\ Files/Nuke\ 15.1v4" 11 | "C:/Program\ Files/Nuke\ 15.1v5" 12 | "C:/Program\ Files/Nuke\ 15.1v6" 13 | "C:/Program\ Files/Nuke\ 15.1v7" 14 | "C:/Program\ Files/Nuke\ 15.1v8" 15 | "C:/Program\ Files/Nuke\ 15.1v9" 16 | ) 17 | 18 | ELSEIF(UNIX) 19 | 20 | find_library (DDIMAGE151_LIBRARY DDImage 21 | ${NUKE151_DIR} 22 | $ENV{NUKE151_DIR} 23 | "/usr/local/Nuke15.1v1" 24 | "/usr/local/Nuke15.1v2" 25 | "/usr/local/Nuke15.1v3" 26 | "/usr/local/Nuke15.1v4" 27 | "/usr/local/Nuke15.1v5" 28 | "/usr/local/Nuke15.1v6" 29 | "/usr/local/Nuke15.1v7" 30 | "/usr/local/Nuke15.1v8" 31 | "/usr/local/Nuke15.1v9" 32 | ) 33 | 34 | ENDIF() 35 | 36 | get_filename_component (NUKE151_LIBRARY_DIR ${DDIMAGE151_LIBRARY} DIRECTORY) 37 | find_path (NUKE151_INCLUDE_DIR DDImage/Op.h ${NUKE151_LIBRARY_DIR}/include) 38 | 39 | INCLUDE(FindPackageHandleStandardArgs) 40 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke151 DEFAULT_MSG 41 | DDIMAGE151_LIBRARY NUKE151_LIBRARY_DIR NUKE151_INCLUDE_DIR 42 | ) 43 | -------------------------------------------------------------------------------- /cmake/Modules/FindNuke160.cmake: -------------------------------------------------------------------------------- 1 | 2 | IF(WIN32) 3 | 4 | find_library (DDIMAGE160_LIBRARY DDImage 5 | ${NUKE160_DIR} 6 | $ENV{NUKE160_DIR} 7 | "C:/Program\ Files/Nuke\ 16.0v1" 8 | "C:/Program\ Files/Nuke\ 16.0v2" 9 | "C:/Program\ Files/Nuke\ 16.0v3" 10 | "C:/Program\ Files/Nuke\ 16.0v4" 11 | "C:/Program\ Files/Nuke\ 16.0v5" 12 | "C:/Program\ Files/Nuke\ 16.0v6" 13 | "C:/Program\ Files/Nuke\ 16.0v7" 14 | "C:/Program\ Files/Nuke\ 16.0v8" 15 | "C:/Program\ Files/Nuke\ 16.0v9" 16 | ) 17 | 18 | ELSEIF(UNIX) 19 | 20 | find_library (DDIMAGE160_LIBRARY DDImage 21 | ${NUKE160_DIR} 22 | $ENV{NUKE160_DIR} 23 | "/usr/local/Nuke16.0v1" 24 | "/usr/local/Nuke16.0v2" 25 | "/usr/local/Nuke16.0v3" 26 | "/usr/local/Nuke16.0v4" 27 | "/usr/local/Nuke16.0v5" 28 | "/usr/local/Nuke16.0v6" 29 | "/usr/local/Nuke16.0v7" 30 | "/usr/local/Nuke16.0v8" 31 | "/usr/local/Nuke16.0v9" 32 | ) 33 | 34 | ENDIF() 35 | 36 | get_filename_component (NUKE160_LIBRARY_DIR ${DDIMAGE160_LIBRARY} DIRECTORY) 37 | find_path (NUKE160_INCLUDE_DIR DDImage/Op.h ${NUKE160_LIBRARY_DIR}/include) 38 | 39 | INCLUDE(FindPackageHandleStandardArgs) 40 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Nuke160 DEFAULT_MSG 41 | DDIMAGE160_LIBRARY NUKE160_LIBRARY_DIR NUKE160_INCLUDE_DIR 42 | ) 43 | -------------------------------------------------------------------------------- /cmake/Modules/FindOFX.cmake: -------------------------------------------------------------------------------- 1 | 2 | find_path (OFX_ROOT_DIR 3 | include/ofxCore.h 4 | PATHS 5 | ${OFX_DIR} 6 | $ENV{OFX_DIR} 7 | "/usr/local/openfx" 8 | ) 9 | 10 | FIND_PATH(OFX_INCLUDE_DIR ofxCore.h PATHS ${OFX_ROOT_DIR}/include NO_DEFAULT_PATH) 11 | 12 | INCLUDE(FindPackageHandleStandardArgs) 13 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(OFX DEFAULT_MSG 14 | OFX_INCLUDE_DIR 15 | ) 16 | -------------------------------------------------------------------------------- /cmake/Modules/FindOpenImageIO.cmake: -------------------------------------------------------------------------------- 1 | ## ======================================================================== ## 2 | ## Copyright 2009-2018 Intel Corporation ## 3 | ## ## 4 | ## Licensed under the Apache License, Version 2.0 (the "License"); ## 5 | ## you may not use this file except in compliance with the License. ## 6 | ## You may obtain a copy of the License at ## 7 | ## ## 8 | ## http://www.apache.org/licenses/LICENSE-2.0 ## 9 | ## ## 10 | ## Unless required by applicable law or agreed to in writing, software ## 11 | ## distributed under the License is distributed on an "AS IS" BASIS, ## 12 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ## 13 | ## See the License for the specific language governing permissions and ## 14 | ## limitations under the License. ## 15 | ## ======================================================================== ## 16 | 17 | IF (NOT OPENIMAGEIO_ROOT) 18 | SET(OPENIMAGEIO_ROOT $ENV{OPENIMAGEIO_ROOT}) 19 | ENDIF() 20 | IF (NOT OPENIMAGEIO_ROOT) 21 | SET(OPENIMAGEIO_ROOT $ENV{OPENIMAGEIOROOT}) 22 | ENDIF() 23 | 24 | # detect changed OPENIMAGEIO_ROOT 25 | IF (NOT OPENIMAGEIO_ROOT STREQUAL OPENIMAGEIO_ROOT_LAST) 26 | UNSET(OPENIMAGEIO_INCLUDE_DIR CACHE) 27 | UNSET(OPENIMAGEIO_LIBRARY CACHE) 28 | ENDIF() 29 | 30 | set(OPENIMAGEIO_LIB_SUFFIX "") 31 | IF (WIN32) 32 | IF (MSVC14) 33 | SET(OPENIMAGEIO_LIB_SUFFIX "vc2015") 34 | ELSEIF (MSVC12) 35 | SET(OPENIMAGEIO_LIB_SUFFIX "vc2013") 36 | ELSEIF (MSVC11) 37 | SET(OPENIMAGEIO_LIB_SUFFIX "vc2012") 38 | ELSEIF (MINGW) 39 | IF (X64) 40 | SET(OPENIMAGEIO_LIB_SUFFIX "mingw-w64") 41 | # Who's ever going to build for 32bit?? 42 | ELSE () 43 | SET(OPENIMAGEIO_LIB_SUFFIX "mingw-w64") 44 | ENDIF() 45 | ENDIF() 46 | ENDIF () 47 | 48 | FIND_PATH(OPENIMAGEIO_ROOT include/OpenImageIO/imageio.h 49 | DOC "Root of OpenImageIO installation" 50 | HINTS ${OPENIMAGEIO_ROOT} 51 | PATHS 52 | ${PROJECT_SOURCE_DIR}/oiio 53 | /usr/local 54 | /usr 55 | / 56 | ) 57 | 58 | FIND_PATH(OPENIMAGEIO_INCLUDE_DIR OpenImageIO/imageio.h PATHS ${OPENIMAGEIO_ROOT}/include NO_DEFAULT_PATH) 59 | SET(OPENIMAGEIO_HINTS 60 | HINTS 61 | ${OPENIMAGEIO_ROOT} 62 | PATH_SUFFIXES 63 | /lib 64 | /lib64 65 | /lib-${OPENIMAGEIO_LIB_SUFFIX} 66 | ) 67 | SET(OPENIMAGEIO_PATHS PATHS /usr/lib /usr/lib64 /lib /lib64) 68 | FIND_LIBRARY(OPENIMAGEIO_LIBRARY OpenImageIO ${OPENIMAGEIO_HINTS} ${OPENIMAGEIO_PATHS}) 69 | 70 | SET(OPENIMAGEIO_ROOT_LAST ${OPENIMAGEIO_ROOT} CACHE INTERNAL "Last value of OPENIMAGEIO_ROOT to detect changes") 71 | 72 | SET(OPENIMAGEIO_ERROR_MESSAGE "OpenImageIO not found in your environment. You can 1) install 73 | via your OS package manager, or 2) install it 74 | somewhere on your machine and point OPENIMAGEIO_ROOT to it.") 75 | 76 | INCLUDE(FindPackageHandleStandardArgs) 77 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenImageIO 78 | ${OPENIMAGEIO_ERROR_MESSAGE} 79 | OPENIMAGEIO_INCLUDE_DIR OPENIMAGEIO_LIBRARY 80 | ) 81 | 82 | IF (OPENIMAGEIO_FOUND) 83 | SET(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO_INCLUDE_DIR}) 84 | SET(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARY}) 85 | ENDIF() 86 | 87 | MARK_AS_ADVANCED(OPENIMAGEIO_INCLUDE_DIR) 88 | MARK_AS_ADVANCED(OPENIMAGEIO_LIBRARY) 89 | -------------------------------------------------------------------------------- /cmake/compile_definitions.cmake: -------------------------------------------------------------------------------- 1 | IF (CMAKE_VERSION VERSION_LESS 3.12) 2 | MACRO(ADD_COMPILE_DEFINITIONS Def) 3 | ADD_DEFINITIONS(-D${Def}) 4 | ENDMACRO(ADD_COMPILE_DEFINITIONS) 5 | ENDIF() 6 | -------------------------------------------------------------------------------- /cmake/output_folders.cmake: -------------------------------------------------------------------------------- 1 | 2 | MACRO(SET_VS_FOLDER folder) 3 | SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${folder}) 4 | ENDMACRO(SET_VS_FOLDER) 5 | -------------------------------------------------------------------------------- /cmake/precompiled_headers.cmake: -------------------------------------------------------------------------------- 1 | MACRO(ADD_MSVC_PRECOMPILED_HEADER_IN_FOLDER SourcesVar Folder) 2 | IF(MSVC) 3 | SET(PrecompiledBasename "stdafx") 4 | SET(PrecompiledHeader "${PrecompiledBasename}.h") 5 | SET(PrecompiledSource "${Folder}/${PrecompiledBasename}.cpp") 6 | SET(PrecompiledBinary "$(IntDir)${PROJECT_NAME}.pch") 7 | FOREACH(_source ${SourcesVar}) 8 | SET_SOURCE_FILES_PROPERTIES(${_source} PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\"" OBJECT_DEPENDS "${PrecompiledBinary}") 9 | ENDFOREACH() 10 | SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource} PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\"" OBJECT_OUTPUTS "${PrecompiledBinary}") 11 | ENDIF(MSVC) 12 | ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER_IN_FOLDER) 13 | 14 | MACRO(ADD_MSVC_PRECOMPILED_HEADER SourcesVar) 15 | IF(MSVC) 16 | SET(PrecompiledBasename "stdafx") 17 | SET(PrecompiledHeader "${PrecompiledBasename}.h") 18 | SET(PrecompiledSource "${CMAKE_CURRENT_LIST_DIR}/${PrecompiledBasename}.cpp") 19 | SET(PrecompiledBinary "$(IntDir)${PROJECT_NAME}.pch") 20 | FOREACH(_source ${SourcesVar}) 21 | SET_SOURCE_FILES_PROPERTIES(${_source} PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\"" OBJECT_DEPENDS "${PrecompiledBinary}") 22 | ENDFOREACH() 23 | SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource} PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\"" OBJECT_OUTPUTS "${PrecompiledBinary}") 24 | ENDIF(MSVC) 25 | ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER) 26 | -------------------------------------------------------------------------------- /conanfile.py: -------------------------------------------------------------------------------- 1 | from conans import ConanFile, CMake, tools 2 | import os, shutil 3 | 4 | #conan remote add conan-transit https://api.bintray.com/conan/conan/conan-transit 5 | #conan remote add hulud https://api.bintray.com/conan/hulud/libs 6 | #conan remote add pierousseau https://api.bintray.com/conan/pierousseau/libs 7 | 8 | class OpenEXRIdConan(ConanFile): 9 | name = "OpenExrId" 10 | version = "1.0-beta.30" 11 | license = "MIT" 12 | url = "https://github.com/MercenariesEngineering/openexrid" 13 | description = "OpenEXR files able to isolate any object of a CG image with a perfect antialiazing " 14 | settings = "os", "compiler", "build_type", "arch" 15 | options = {"shared": [True, False], "fPIC": [True, False], "build_lib": [True, False], "build_plugins": [True, False] } 16 | default_options = "shared=False","*:shared=False","fPIC=True","build_lib=True","build_plugins=False" 17 | generators = "cmake" 18 | 19 | def requirements(self): 20 | self.requires("zlib/1.2.11@mercseng/v0") 21 | self.requires("bzip2/1.0.8@mercseng/v0") 22 | self.requires("OpenFx/1.4@pierousseau/stable") 23 | 24 | if self.settings.os == "Linux" and self.settings.compiler == "gcc": 25 | if self.settings.compiler.version == 4.8: 26 | # Nukes 11-13 27 | self.requires("OpenImageIO/2.1.15.0@mercseng/stable") 28 | self.requires("OpenEXR/2.5.1@mercseng/stable") 29 | self.requires("re2/2019-06-01@pierousseau/stable") 30 | self.requires("libpng/1.6.37@mercseng/v0") 31 | self.requires("boost/1.64.0@guerilla_legacy/v0") 32 | elif self.settings.compiler.version == 9: 33 | # Nuke 14+ 34 | self.requires("OpenImageIO/2.1.15.0@mercseng/v2") 35 | self.requires("OpenEXR/2.5.1@mercseng/v0") 36 | self.requires("re2/2019-06-01@mercseng/v1") 37 | self.requires("libpng/1.6.37@mercseng/v0") 38 | self.requires("boost/1.73.0@mercseng/v6") 39 | self.requires("tbb/2020.02@mercseng/v3") 40 | elif self.settings.compiler == "Visual Studio": 41 | if self.settings.compiler.version == 14: 42 | # Nukes 11-13 43 | self.requires("OpenImageIO/2.1.15.0@mercseng/v2") 44 | self.requires("OpenEXR/2.5.1@mercseng/v0") 45 | self.requires("re2/2019-06-01@mercseng/v0") 46 | self.requires("libpng/1.6.37@mercseng/v0") 47 | self.requires("boost/1.73.0@mercseng/v2") 48 | self.requires("tbb/2020.02@mercseng/v3") 49 | elif self.settings.compiler.version == 16: 50 | # Nuke 14+ 51 | self.requires("OpenImageIO/2.1.15.0@mercseng/v4") 52 | self.requires("OpenEXR/2.5.1@mercseng/v0") 53 | self.requires("re2/2019-06-01@mercseng/v1") 54 | self.requires("libpng/1.6.37@mercseng/v0") 55 | self.requires("boost/1.73.0@mercseng/v6") 56 | self.requires("tbb/2020.02@mercseng/v3") 57 | 58 | def configure(self): 59 | if self.settings.os == "Linux": 60 | # fPIC option exists only on linux 61 | self.options["boost"].fPIC=True 62 | if self.settings.compiler == "gcc" and self.settings.compiler.version == 4.1: 63 | self.options["IlmBase"].fPIC=True 64 | self.options["OpenEXR"].fPIC=True 65 | #self.options["OpenFx"].fPIC=True 66 | self.options["OpenImageIO"].fPIC=True 67 | self.options["re2"].fPIC=True 68 | self.options["zlib"].fPIC=True 69 | if self.settings.compiler == "gcc" and self.settings.compiler.version == 9: 70 | self.options["tbb"].shared=True 71 | else: 72 | self.options["boost"].i18n_backend = "iconv" 73 | self.options["boost"].zstd = True 74 | self.options["boost"].lzma = True 75 | self.options["boost"].without_python = False 76 | self.options["cpython"].shared=True 77 | 78 | def source(self): 79 | self.run("git clone http://github.com/MercenariesEngineering/openexrid.git --branch %s" % self.version) 80 | 81 | def build(self): 82 | cmake = CMake(self) 83 | #cmake.verbose = True 84 | cmake.definitions["USE_CONAN"] = True 85 | cmake.definitions["BUILD_LIB"] = self.options.build_lib 86 | cmake.definitions["BUILD_PLUGINS"] = self.options.build_plugins 87 | cmake.definitions["CONAN_BUILD_INFO_DIR"] = os.path.join(self.build_folder, "..", "Conan") 88 | 89 | if (self.settings.compiler == "Visual Studio" and self.settings.compiler.version == 16) or (self.settings.compiler == "gcc" and self.settings.compiler.version == 9): 90 | # Visual 2019 / gcc 9, Nuke 14+ 91 | cmake.definitions["CMAKE_CXX_STANDARD"] = 17 92 | cmake.definitions["CMAKE_CXX_STANDARD_REQUIRED"] = True 93 | else: 94 | # Visual 2015 / gcc 4.8, Nukes 11-13 95 | cmake.definitions["CMAKE_CXX_STANDARD"] = 11 96 | cmake.definitions["CMAKE_CXX_STANDARD_REQUIRED"] = True 97 | 98 | source_dir="%s/openexrid" % self.source_folder 99 | if os.path.isdir(source_dir+"/openexrid"): 100 | cmake.configure(source_dir=source_dir) 101 | else: 102 | cmake.configure() 103 | 104 | targets = [] 105 | if self.settings.compiler == "Visual Studio": 106 | if self.settings.compiler.version == 14: 107 | # Visual 2015, Nukes 11-13 108 | if self.options.build_plugins: 109 | targets.extend(["OpenEXRIdOFX", "OpenEXRIdForNuke11.1", "OpenEXRIdForNuke11.2", "OpenEXRIdForNuke11.3", "OpenEXRIdForNuke12.0", "OpenEXRIdForNuke12.1", "OpenEXRIdForNuke12.2", "OpenEXRIdForNuke13.0", "OpenEXRIdForNuke13.2"]) 110 | elif self.settings.compiler.version == 16: 111 | # Visual 2019, Nuke 14+ 112 | if self.options.build_lib: 113 | targets.extend(["LibOpenEXRId"]) 114 | if self.options.build_plugins: 115 | targets.extend(["OpenEXRIdForNuke14.0", "OpenEXRIdForNuke15.1", "OpenEXRIdForNuke16.0"]) 116 | elif self.settings.compiler == "gcc": 117 | if self.settings.compiler.version == 4.8: 118 | # gcc 4.8, Nuke 11-13 119 | if self.options.build_plugins: 120 | targets.extend(["OpenEXRIdOFX", "OpenEXRIdForNuke11.1", "OpenEXRIdForNuke11.2", "OpenEXRIdForNuke11.3", "OpenEXRIdForNuke12.0", "OpenEXRIdForNuke12.1", "OpenEXRIdForNuke12.2", "OpenEXRIdForNuke13.0", "OpenEXRIdForNuke13.2"]) 121 | elif self.settings.compiler.version == 9: 122 | # gcc 9, Nuke 14+ 123 | if self.options.build_lib: 124 | targets.extend(["LibOpenEXRId"]) 125 | if self.options.build_plugins: 126 | targets.extend(["OpenEXRIdOFX", "OpenEXRIdForNuke14.0", "OpenEXRIdForNuke15.1", "OpenEXRIdForNuke16.0"]) 127 | 128 | for t in targets: 129 | cmake.build(target=t) 130 | 131 | def package(self): 132 | self.copy("*.h", dst="include/openexrid", src="openexrid/openexrid") 133 | self.copy("*.lib", dst="lib", keep_path=False) 134 | self.copy("*.a", dst="lib", keep_path=False) 135 | 136 | def package_info(self): 137 | self.cpp_info.libs = tools.collect_libs(self) 138 | -------------------------------------------------------------------------------- /data/openexrid.abc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MercenariesEngineering/openexrid/1ec6dff08714876f1a6f15added25d26f49270ac/data/openexrid.abc -------------------------------------------------------------------------------- /data/sample_motionblur_transparency.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MercenariesEngineering/openexrid/1ec6dff08714876f1a6f15added25d26f49270ac/data/sample_motionblur_transparency.exr -------------------------------------------------------------------------------- /data/sample_motionblur_transparency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MercenariesEngineering/openexrid/1ec6dff08714876f1a6f15added25d26f49270ac/data/sample_motionblur_transparency.png -------------------------------------------------------------------------------- /nuke/DeepOpenEXRId.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | 20 | #if defined(_MSC_VER) && (_MSC_VER > 1600) 21 | #define USE_MODERN_APIS 22 | #endif 23 | 24 | #ifdef USE_MODERN_APIS 25 | 26 | #include 27 | namespace OpenEXRId 28 | { 29 | using std::mutex; 30 | using std::lock_guard; 31 | using std::shared_ptr; 32 | using std::make_shared; 33 | } 34 | 35 | #else 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | namespace OpenEXRId 42 | { 43 | using boost::mutex; 44 | using boost::lock_guard; 45 | using boost::shared_ptr; 46 | using boost::make_shared; 47 | } 48 | 49 | #endif 50 | 51 | #include "DDImage/DeepFilterOp.h" 52 | #include "DDImage/Knobs.h" 53 | 54 | #ifdef WIN32 55 | #pragma warning(push, 0) 56 | #endif 57 | 58 | #if defined(_MSC_VER) && (_MSC_VER <= 1600) 59 | #include 60 | #undef rintf 61 | #undef expm1f 62 | #endif 63 | 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | #ifdef WIN32 71 | #pragma warning(pop) 72 | #endif 73 | // Defined by oiio 74 | #undef copysign 75 | 76 | 77 | // The DeepOpenEXRId plugin 78 | class DeepOpenEXRId : public DD::Image::DeepFilterOp 79 | { 80 | const char *_patterns; 81 | const char *_LPEs; 82 | bool _colors, _invert, _alpha, _keepVis; 83 | const char *_version; 84 | int _mode; 85 | 86 | public: 87 | 88 | struct LPEEvent 89 | { 90 | OIIO::ustring Type; 91 | OIIO::ustring Scattering; 92 | OIIO::ustring Label; 93 | }; 94 | 95 | typedef std::vector LightPath; 96 | 97 | DeepOpenEXRId(Node* node) : DeepFilterOp(node) 98 | { 99 | _patterns = NULL; 100 | _LPEs = NULL; 101 | _colors = false; 102 | _invert = false; 103 | _alpha = false; 104 | _keepVis = true; 105 | _version = NULL; 106 | _mode = 0; 107 | } 108 | 109 | const char* node_help() const; 110 | 111 | const char* Class() const; 112 | 113 | virtual Op* op(); 114 | 115 | void knobs(DD::Image::Knob_Callback f); 116 | 117 | int knob_changed(DD::Image::Knob* k); 118 | 119 | void _validate(bool for_real); 120 | 121 | bool doDeepEngine(DD::Image::Box box, const DD::Image::ChannelSet& channels, DD::Image::DeepOutputPlane& plane); 122 | 123 | void select (float x0, float y0, float x1, float y1, bool invert); 124 | 125 | static const Description d; 126 | 127 | 128 | private: 129 | 130 | // A single entry hashed cache 131 | template 132 | struct HashCache 133 | { 134 | OpenEXRId::mutex Mutex; 135 | H Hash; 136 | T Value; 137 | 138 | T get (const H &hash, const void * build_data, DeepOpenEXRId * notifier) 139 | { 140 | OpenEXRId::lock_guard guard (Mutex); 141 | if (hash != Hash) 142 | { 143 | Value = build (hash, build_data, notifier); 144 | Hash = hash; 145 | } 146 | return Value; 147 | } 148 | 149 | T build(const H &hash, const void * build_data, DeepOpenEXRId * notifier); 150 | }; 151 | 152 | // This is the metadata we grabd from the input exrid 153 | struct ExrIdData 154 | { 155 | std::string Hash; 156 | std::vector Names; 157 | std::vector LightPaths; 158 | }; 159 | 160 | typedef OpenEXRId::shared_ptr ExrIdDataPtr; 161 | typedef HashCache ExrIdDataCacheType; 162 | ExrIdDataCacheType ExrIdDataCache; 163 | 164 | // get the cached metadata (or build it if anything has changed) 165 | ExrIdDataPtr _getExrIdData (); 166 | 167 | // This is the regex matching automaton for names 168 | class NameAutomaton 169 | { 170 | public: 171 | NameAutomaton (); 172 | std::string Hash; 173 | std::vector Patterns; 174 | re2::RE2::Set RegEx; 175 | 176 | bool match (const std::string &name, std::vector &tmp) const; 177 | }; 178 | 179 | typedef OpenEXRId::shared_ptr NameAutomatonPtr; 180 | typedef HashCache NameAutomatonCacheType; 181 | NameAutomatonCacheType NameAutomatonCache; 182 | 183 | // get the cached name matcing automaton 184 | NameAutomatonPtr _getNamesAutomaton (); 185 | 186 | // This is the lpe matching automaton for light paths 187 | class LPEAutomaton 188 | { 189 | public: 190 | std::string Hash; 191 | std::vector Patterns; 192 | OSL::DfOptimizedAutomata LPEx; 193 | 194 | bool match (const LightPath &lightpath) const; 195 | }; 196 | 197 | typedef OpenEXRId::shared_ptr LPEAutomatonPtr; 198 | typedef HashCache LPEAutomatonCacheType; 199 | LPEAutomatonCacheType LPEAutomatonCache; 200 | 201 | // get the cached lpe matching automaton 202 | LPEAutomatonPtr _getLPEAutomaton (); 203 | 204 | // This is the activation states for names and light paths 205 | class State 206 | { 207 | public: 208 | std::vector IdStates; 209 | std::vector LPEIdStates; 210 | 211 | bool idSelected (size_t id, bool invert) const 212 | { return id < IdStates.size () && IdStates[id] != invert; } 213 | bool lpeidSelected (size_t id) const 214 | { return id < LPEIdStates.size () && LPEIdStates[id]; } 215 | 216 | struct BuildData 217 | { 218 | const DeepOpenEXRId::ExrIdDataPtr &exrid; 219 | const DeepOpenEXRId::NameAutomatonPtr &namesregex; 220 | const DeepOpenEXRId::LPEAutomatonPtr &lperegex; 221 | }; 222 | }; 223 | 224 | typedef OpenEXRId::shared_ptr StatePtr; 225 | typedef HashCache StateCacheType; 226 | StateCacheType StateCache; 227 | 228 | // get the result activate names and light paths 229 | StatePtr _getState ( 230 | const ExrIdDataPtr &data, 231 | const NameAutomatonPtr &names, 232 | const LPEAutomatonPtr &lpes); 233 | }; 234 | -------------------------------------------------------------------------------- /nuke/OSL/accum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "OSL/accum.h" 30 | #include "OSL/oslclosure.h" 31 | #include "OSL/lpeparse.h" 32 | #include 33 | 34 | 35 | OSL_NAMESPACE_ENTER 36 | 37 | 38 | 39 | void 40 | AovOutput::flush(void *flush_data) 41 | { 42 | if (!aov) 43 | return; 44 | if (neg_color) { 45 | color.setValue(1.0f - color.x, 1.0f - color.y, 1.0f - color.z); 46 | has_color = true; 47 | } 48 | if (neg_alpha) { 49 | alpha = 1.0f - alpha; 50 | has_alpha = true; 51 | } 52 | 53 | aov->write(flush_data, color, alpha, has_color, has_alpha); 54 | } 55 | 56 | 57 | 58 | void 59 | AccumRule::accum(const Color3 &color, std::vector &outputs)const 60 | { 61 | if (m_save_to_alpha) { 62 | outputs[m_outidx].alpha += (color.x + color.y + color.z) * 1.0f/3.0f; 63 | outputs[m_outidx].has_alpha = true; 64 | } else { 65 | outputs[m_outidx].color += color; 66 | outputs[m_outidx].has_color = true; 67 | } 68 | } 69 | 70 | 71 | 72 | 73 | AccumAutomata::~AccumAutomata() 74 | { 75 | for (std::list::iterator i = m_rules.begin(); i != m_rules.end(); ++i) 76 | delete *i; 77 | } 78 | 79 | 80 | 81 | AccumRule * 82 | AccumAutomata::addRule(const char *pattern, int outidx, bool toalpha) 83 | { 84 | // First parse the lpexp and see if it fails 85 | Parser parser(&m_user_events, &m_user_scatterings); 86 | LPexp *e = parser.parse(pattern); 87 | if (parser.error()) { 88 | std::cerr << "[pathexp] Parse error" << parser.getErrorMsg() << " at char " << parser.getErrorPos() << std::endl; 89 | delete e; 90 | return NULL; 91 | } 92 | m_accumrules.push_back (AccumRule (outidx, toalpha)); 93 | // it is a list, so as long as we don't remove it from there, the pointer is valid 94 | void *rule = (void *)&(m_accumrules.back()); 95 | m_rules.push_back (new lpexp::Rule (e, rule)); 96 | return &(m_accumrules.back()); 97 | } 98 | 99 | 100 | 101 | void 102 | AccumAutomata::compile() 103 | { 104 | NdfAutomata ndfautomata; 105 | for (std::list::const_iterator i = m_rules.begin(); i != m_rules.end(); ++i) { 106 | (*i)->genAuto(ndfautomata); 107 | delete *i; 108 | } 109 | // Nuke the compiled regexps, we don't need them anymore 110 | m_rules.clear(); 111 | DfAutomata dfautomata; 112 | ndfautoToDfauto(ndfautomata, dfautomata); 113 | m_dfoptautomata.compileFrom(dfautomata); 114 | } 115 | 116 | 117 | 118 | void 119 | AccumAutomata::accum(int state, const Color3 &color, std::vector &outputs)const 120 | { 121 | // get the rules field, the underlying type is a std::vector 122 | int nrules = 0; 123 | void * const * rules = getRulesInState(state, nrules); 124 | // Iterate the vector 125 | for (int i = 0; i < nrules; ++i) 126 | // Let the accumulator rule do its job 127 | ((AccumRule *)(rules[i]))->accum(color, outputs); 128 | } 129 | 130 | 131 | 132 | Accumulator::Accumulator(const AccumAutomata *accauto):m_accum_automata(accauto) 133 | { 134 | const std::list &rules = m_accum_automata->getRuleList(); 135 | // Make sure we have as many outputs as the rules need 136 | int maxouts = 0; 137 | for (std::list::const_iterator i = rules.begin(); i != rules.end(); ++i) 138 | maxouts = i->getOutputIndex() > maxouts ? i->getOutputIndex() : maxouts; 139 | m_outputs.resize(maxouts+1); 140 | 141 | // 0 is our initial state always 142 | m_state = 0; 143 | } 144 | 145 | 146 | 147 | void 148 | Accumulator::setAov(int outidx, Aov *aov, bool neg_color, bool neg_alpha) 149 | { 150 | ASSERT (0 <= outidx && outidx < (int) m_outputs.size()); 151 | m_outputs[outidx].aov = aov; 152 | m_outputs[outidx].neg_color = neg_color; 153 | m_outputs[outidx].neg_alpha = neg_alpha; 154 | } 155 | 156 | 157 | 158 | void 159 | Accumulator::pushState() 160 | { 161 | ASSERT (m_state >= 0); 162 | m_stack.push(m_state); 163 | } 164 | 165 | 166 | 167 | void 168 | Accumulator::popState() 169 | { 170 | ASSERT (m_stack.size()); 171 | m_state = m_stack.top(); 172 | m_stack.pop(); 173 | } 174 | 175 | 176 | 177 | void 178 | Accumulator::move(ustring symbol) 179 | { 180 | if (m_state >= 0) 181 | m_state = m_accum_automata->getTransition(m_state, symbol); 182 | } 183 | 184 | 185 | 186 | void 187 | Accumulator::move(const ustring *symbols) 188 | { 189 | while (m_state >= 0 && symbols && *symbols != Labels::NONE) 190 | m_state = m_accum_automata->getTransition(m_state, *(symbols++)); 191 | } 192 | 193 | 194 | 195 | void 196 | Accumulator::move(ustring event, ustring scatt, const ustring *custom, ustring stop) 197 | { 198 | if (m_state >= 0) 199 | m_state = m_accum_automata->getTransition(m_state, event); 200 | if (m_state >= 0) 201 | m_state = m_accum_automata->getTransition(m_state, scatt); 202 | while (m_state >= 0 && custom && *custom != Labels::NONE) 203 | m_state = m_accum_automata->getTransition(m_state, *(custom++)); 204 | if (m_state >= 0) 205 | m_state = m_accum_automata->getTransition(m_state, stop); 206 | } 207 | 208 | 209 | 210 | void 211 | Accumulator::begin() 212 | { 213 | for (size_t i = 0; i < m_outputs.size(); ++i) 214 | m_outputs[i].reset(); 215 | } 216 | 217 | 218 | 219 | void 220 | Accumulator::end(void *flush_data) 221 | { 222 | for (size_t i = 0; i < m_outputs.size(); ++i) 223 | m_outputs[i].flush(flush_data); 224 | } 225 | 226 | OSL_NAMESPACE_EXIT 227 | -------------------------------------------------------------------------------- /nuke/OSL/closure.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | 36 | #include "OSL/oslconfig.h" 37 | #include "OSL/oslclosure.h" 38 | #include "OSL/genclosure.h" 39 | #include "OSL/oslexec_pvt.h" 40 | 41 | 42 | 43 | OSL_NAMESPACE_ENTER 44 | 45 | const ustring Labels::NONE = ustring(NULL); 46 | const ustring Labels::CAMERA = ustring("C"); 47 | const ustring Labels::LIGHT = ustring("L"); 48 | const ustring Labels::BACKGROUND = ustring("B"); 49 | const ustring Labels::VOLUME = ustring("V"); 50 | const ustring Labels::OBJECT = ustring("O"); 51 | const ustring Labels::TRANSMIT = ustring("T"); 52 | const ustring Labels::REFLECT = ustring("R"); 53 | const ustring Labels::DIFFUSE = ustring("D"); 54 | const ustring Labels::GLOSSY = ustring("G"); 55 | const ustring Labels::SINGULAR = ustring("S"); 56 | const ustring Labels::STRAIGHT = ustring("s"); 57 | const ustring Labels::STOP = ustring("__stop__"); 58 | 59 | 60 | 61 | namespace pvt { 62 | 63 | 64 | 65 | static void 66 | print_component_value(std::ostream &out, ShadingSystemImpl *ss, 67 | TypeDesc type, const void *data) 68 | 69 | { 70 | if (type == TypeDesc::TypeInt) 71 | out << *(int *)data; 72 | else if (type == TypeDesc::TypeFloat) 73 | out << *(float *)data; 74 | else if (type == TypeDesc::TypeColor) 75 | out << "(" << ((Color3 *)data)->x << ", " << ((Color3 *)data)->y << ", " << ((Color3 *)data)->z << ")"; 76 | else if (type == TypeDesc::TypeVector) 77 | out << "(" << ((Vec3 *)data)->x << ", " << ((Vec3 *)data)->y << ", " << ((Vec3 *)data)->z << ")"; 78 | else if (type == TypeDesc::TypeString) 79 | out << "\"" << *((ustring *)data) << "\""; 80 | else if (type == TypeDesc::PTR) // this only happens for closures 81 | print_closure (out, *(const ClosureColor **)data, ss); 82 | } 83 | 84 | 85 | 86 | static void 87 | print_component (std::ostream &out, const ClosureComponent *comp, ShadingSystemImpl *ss, const Color3 &weight) 88 | { 89 | out << "(" << weight[0]*comp->w[0] << ", " << weight[1]*comp->w[1] << ", " << weight[2]*comp->w[2] << ") * "; 90 | const ClosureRegistry::ClosureEntry *clentry = ss->find_closure(comp->id); 91 | ASSERT(clentry); 92 | out << clentry->name.c_str() << " ("; 93 | for (int i = 0, nparams = clentry->params.size() - 1; i < nparams; ++i) { 94 | if (i) out << ", "; 95 | const ClosureParam& param = clentry->params[i]; 96 | if (param.key != 0) 97 | out << "\"" << param.key << "\", "; 98 | if (param.type.numelements() > 1) out << "["; 99 | for (size_t j = 0; j < param.type.numelements(); ++j) { 100 | if (j) out << ", "; 101 | print_component_value(out, ss, param.type.elementtype(), 102 | (const char *)comp->data() + param.offset 103 | + param.type.elementsize() * j); 104 | } 105 | if (clentry->params[i].type.numelements() > 1) out << "]"; 106 | } 107 | out << ")"; 108 | } 109 | 110 | 111 | 112 | static void 113 | print_closure (std::ostream &out, const ClosureColor *closure, ShadingSystemImpl *ss, const Color3 &w, bool &first) 114 | { 115 | if (closure == NULL) 116 | return; 117 | 118 | switch (closure->id) { 119 | case ClosureColor::MUL: 120 | print_closure(out, closure->as_mul()->closure, ss, closure->as_mul()->weight * w, first); 121 | break; 122 | case ClosureColor::ADD: 123 | print_closure(out, closure->as_add()->closureA, ss, w, first); 124 | print_closure(out, closure->as_add()->closureB, ss, w, first); 125 | break; 126 | default: 127 | if (!first) 128 | out << "\n\t+ "; 129 | print_component (out, closure->as_comp(), ss, w); 130 | first = false; 131 | break; 132 | } 133 | } 134 | 135 | 136 | 137 | void 138 | print_closure (std::ostream &out, const ClosureColor *closure, ShadingSystemImpl *ss) 139 | { 140 | bool first = true; 141 | print_closure(out, closure, ss, Color3(1, 1, 1), first); 142 | } 143 | 144 | 145 | 146 | } // namespace pvt 147 | 148 | 149 | 150 | OSL_NAMESPACE_EXIT 151 | -------------------------------------------------------------------------------- /nuke/OSL/include/OSL/constantpool.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | using namespace OSL; 38 | using namespace OSL::pvt; 39 | 40 | 41 | OSL_NAMESPACE_ENTER 42 | 43 | namespace pvt { 44 | 45 | 46 | /// A ConstantPool is a way to allocate room for a small number of 47 | /// T's at a time, such that the memory allocated will NEVER change its 48 | /// address or be deallocated until the entire ConstantPool is 49 | /// destroyed. Allocating from the pool is completely thread-safe. 50 | /// 51 | /// It is implemented as a linked list of memory blocks. A request for 52 | /// a new allocation tries to fit it in one of the allocated blocks, but 53 | /// if it won't fit anywhere, it makes a new block and adds it to the 54 | /// head of the list. 55 | template 56 | class ConstantPool { 57 | public: 58 | /// Allocate a new pool of T's. The quanta, if supplied, is the 59 | /// number of T's to malloc at a time. 60 | ConstantPool (size_t quanta = 1000000) : m_quanta(quanta), m_total(0) { } 61 | 62 | ~ConstantPool () { } 63 | 64 | /// Allocate space enough for n T's, and return a pointer to the 65 | /// start of that space. 66 | T * alloc (size_t n) { 67 | OIIO::lock_guard lock (m_mutex); 68 | // Check each block in the block list to see if it has enough space 69 | BOOST_FOREACH (block_t &block, m_block_list) { 70 | size_t s = block.size(); 71 | if ((s+n) <= block.capacity()) { 72 | // Enough space in this block. Use it. 73 | block.resize (s+n); 74 | return &block[s]; 75 | } 76 | } 77 | // If we got here, there were no mini-blocks in the list with enough 78 | // space. Make a new one. 79 | m_block_list.push_front (block_t()); 80 | block_t &block (m_block_list.front()); 81 | size_t s = std::max (m_quanta, n); 82 | block.reserve (s); 83 | m_total += s * sizeof(T); 84 | block.resize (n); 85 | return &block[0]; 86 | } 87 | 88 | private: 89 | typedef std::vector block_t; ///< Type of block 90 | std::list m_block_list; ///< List of memory blocks 91 | size_t m_quanta; ///< How big each memory block is (in T's, not bytes) 92 | size_t m_total; ///< Total memory allocated (bytes!) 93 | OIIO::mutex m_mutex; ///< Thread-safe lock 94 | }; 95 | 96 | 97 | 98 | }; // namespace OSL::pvt 99 | OSL_NAMESPACE_EXIT 100 | -------------------------------------------------------------------------------- /nuke/OSL/include/OSL/export.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2008-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | 30 | #pragma once 31 | 32 | /// \file 33 | /// OSLPUBLIC and OSLEXPORT macros that are necessary for proper symbol 34 | /// export when doing multi-platform development. 35 | 36 | 37 | /// 38 | /// On Windows, when compiling code that will end up in a DLL, symbols 39 | /// must be marked as 'exported' (i.e. __declspec(dllexport)) or they 40 | /// won't be visible to programs linking against the DLL. 41 | /// 42 | /// In addition, when compiling the application code that calls the DLL, 43 | /// if a routine is marked as 'imported' (i.e. __declspec(dllimport)), 44 | /// the compiler can be smart about eliminating a level of calling 45 | /// indirection. But you DON'T want to use __declspec(dllimport) when 46 | /// calling a function from within its own DLL (it will still compile 47 | /// correctly, just not with maximal efficiency). Which is quite the 48 | /// dilemma since the same header file is used by both the library and 49 | /// its clients. Sheesh! 50 | /// 51 | /// But on Linux/OSX as well, we want to only have the DSO export the 52 | /// symbols we designate as the public interface. So we link with 53 | /// -fvisibility=hidden to default to hiding the symbols. See 54 | /// http://gcc.gnu.org/wiki/Visibility 55 | /// 56 | /// We solve this awful mess by defining these macros: 57 | /// 58 | /// OSL*PUBLIC - normally, assumes that it's being seen by a client 59 | /// of the library, and therefore declare as 'imported'. 60 | /// But if OSL_EXPORT_PUBLIC is defined, change the declaration 61 | /// to 'exported' -- you want to define this macro when 62 | /// compiling the module that actually defines the class. 63 | /// 64 | /// There is a separate define for each library, because there inter- 65 | /// dependencies, and so what is exported for one may be imported for 66 | /// another. 67 | 68 | #if defined(_MSC_VER) || defined(__CYGWIN__) 69 | #if defined(OSL_STATIC_LIBRARY) 70 | #define OSL_DLL_IMPORT 71 | #define OSL_DLL_EXPORT 72 | #define OSL_DLL_LOCAL 73 | #else 74 | #define OSL_DLL_IMPORT __declspec(dllimport) 75 | #define OSL_DLL_EXPORT __declspec(dllexport) 76 | #define OSL_DLL_LOCAL 77 | #endif 78 | //#define OSL_LLVM_EXPORT __declspec(dllexport) 79 | #define OSL_LLVM_EXPORT OSL_DLL_LOCAL 80 | #else 81 | #if (10000*__GNUC__ + 100*__GNUC_MINOR__ + __GNUC_PATCHLEVEL__) > 40102 82 | #define OSL_DLL_IMPORT __attribute__ ((visibility ("default"))) 83 | #define OSL_DLL_EXPORT __attribute__ ((visibility ("default"))) 84 | #define OSL_DLL_LOCAL __attribute__ ((visibility ("hidden"))) 85 | #else 86 | #define OSL_DLL_IMPORT 87 | #define OSL_DLL_EXPORT 88 | #define OSL_DLL_LOCAL 89 | #endif 90 | #define OSL_LLVM_EXPORT OSL_DLL_LOCAL 91 | #endif 92 | 93 | 94 | 95 | #if defined(oslcomp_EXPORTS) 96 | # define OSLCOMPPUBLIC OSL_DLL_EXPORT 97 | #else 98 | # define OSLCOMPPUBLIC OSL_DLL_IMPORT 99 | #endif 100 | 101 | #if defined(oslexec_EXPORTS) 102 | # define OSLEXECPUBLIC OSL_DLL_EXPORT 103 | #else 104 | # define OSLEXECPUBLIC OSL_DLL_IMPORT 105 | #endif 106 | 107 | #if defined(oslquery_EXPORTS) || defined(oslexec_EXPORTS) 108 | # define OSLQUERYPUBLIC OSL_DLL_EXPORT 109 | #else 110 | # define OSLQUERYPUBLIC OSL_DLL_IMPORT 111 | #endif 112 | -------------------------------------------------------------------------------- /nuke/OSL/include/OSL/genclosure.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include "oslconfig.h" 33 | 34 | OSL_NAMESPACE_ENTER 35 | 36 | 37 | struct ClosureParam { 38 | TypeDesc type; 39 | int offset; 40 | const char *key; 41 | // This is only for sanity checks 42 | int field_size; 43 | }; 44 | 45 | #define reckless_offsetof(st, fld) (((char *)&(((st *)16)->fld)) - (char *)16) 46 | #define fieldsize(st, fld) sizeof(((st *)0)->fld) 47 | 48 | #define CLOSURE_INT_PARAM(st, fld) \ 49 | { TypeDesc::TypeInt, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 50 | #define CLOSURE_FLOAT_PARAM(st, fld) \ 51 | { TypeDesc::TypeFloat, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 52 | #define CLOSURE_COLOR_PARAM(st, fld) \ 53 | { TypeDesc::TypeColor, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 54 | #define CLOSURE_VECTOR_PARAM(st, fld) \ 55 | { TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 56 | #define CLOSURE_STRING_PARAM(st, fld) \ 57 | { TypeDesc::TypeString, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 58 | #define CLOSURE_CLOSURE_PARAM(st, fld) \ 59 | { TypeDesc::PTR, (int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 60 | 61 | #define CLOSURE_INT_ARRAY_PARAM(st, fld, n) \ 62 | { TypeDesc(TypeDesc::INT, TypeDesc::SCALAR, TypeDesc::NOXFORM, n),(int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 63 | #define CLOSURE_VECTOR_ARRAY_PARAM(st,fld,n) \ 64 | { TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::VECTOR, n),(int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 65 | #define CLOSURE_COLOR_ARRAY_PARAM(st,fld,n) \ 66 | { TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::COLOR, n),(int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 67 | #define CLOSURE_FLOAT_ARRAY_PARAM(st,fld,n) \ 68 | { TypeDesc(TypeDesc::FLOAT, TypeDesc::SCALAR, TypeDesc::NOXFORM, n),(int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 69 | #define CLOSURE_STRING_ARRAY_PARAM(st,fld,n) \ 70 | { TypeDesc(TypeDesc::STRING, TypeDesc::SCALAR, TypeDesc::NOXFORM, n),(int)reckless_offsetof(st, fld), NULL, fieldsize(st, fld) } 71 | 72 | // NOTE: this keyword args have to be always at the end of the list 73 | #define CLOSURE_INT_KEYPARAM(st, fld, key) \ 74 | { TypeDesc::TypeInt, (int)reckless_offsetof(st, fld), key, fieldsize(st, fld) } 75 | #define CLOSURE_FLOAT_KEYPARAM(st, fld, key) \ 76 | { TypeDesc::TypeFloat, (int)reckless_offsetof(st, fld), key, fieldsize(st, fld) } 77 | #define CLOSURE_COLOR_KEYPARAM(st, fld, key) \ 78 | { TypeDesc::TypeColor, (int)reckless_offsetof(st, fld), key, fieldsize(st, fld) } 79 | #define CLOSURE_VECTOR_KEYPARAM(st, fld, key) \ 80 | { TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), key, fieldsize(st, fld) } 81 | #define CLOSURE_STRING_KEYPARAM(st, fld, key) \ 82 | { TypeDesc::TypeString, (int)reckless_offsetof(st, fld), key, fieldsize(st, fld) } 83 | 84 | #define CLOSURE_FINISH_PARAM(st) { TypeDesc(), sizeof(st), NULL, 0 } 85 | 86 | OSL_NAMESPACE_EXIT 87 | -------------------------------------------------------------------------------- /nuke/OSL/include/OSL/lpeparse.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include "lpexp.h" 32 | 33 | 34 | OSL_NAMESPACE_ENTER 35 | 36 | 37 | 38 | using lpexp::LPexp; 39 | 40 | 41 | /// Light path expression parser 42 | /// 43 | /// As most hand written descendant parsers, it is a bit messy in the implementation. 44 | /// But the interface more or less resembles the grammar of the language: 45 | /// 46 | /// symbol := | 'string' 47 | /// listsym := | listsym sym 48 | /// listexp := | listexp exp 49 | /// group := '<' exp exp exp listexp '>' 50 | /// catexp := ( listexp ) 51 | /// sorexp := exp '|' exp 52 | /// borexp := [ listsym ] 53 | /// wildexp := . | [^ listsym ] 54 | /// repeat := exp * 55 | /// repeat+ := exp + 56 | /// mnrepeat := exp {} | exp {,} | exp {,} 57 | /// exp := wildexp | borexp | sorexp | catexp | group | repeat | repeat+ | mnrepeat 58 | /// topexp := exp | topexp exp 59 | /// 60 | class Parser 61 | { 62 | public: 63 | 64 | Parser(const std::vector *user_events = NULL, 65 | const std::vector *user_scatterings = NULL); 66 | 67 | /// Parse a string and return the resulting light path expression tree or NULL if failed 68 | LPexp *parse(const char *text); 69 | 70 | /// Check for error in the last parsed string 71 | bool error()const { return m_error.size() > 0; }; 72 | /// Get the error string 73 | const char *getErrorMsg()const { return m_error.c_str(); }; 74 | /// Get the position of the string where the error appeared 75 | int getErrorPos()const { return m_pos; }; 76 | 77 | private: 78 | 79 | /// Current char being parsed 80 | char head()const { return m_text[m_pos]; }; 81 | /// Any input (including head) left? 82 | bool hasInput()const { return m_text.size() > m_pos; }; 83 | /// Go to the next char in the string 84 | void next() { m_pos++; }; 85 | 86 | /// build the complete pattern for a pathtracing stop 87 | /// 88 | /// That means the three basic label match expressions, plus those for the custom labels (if any), 89 | /// plus an additional wildcard to eat extra custom labels at the end, and finally the stop mark. 90 | /// So you provide the regexps for the basic three labels: 91 | /// 92 | /// \param etype Event type (CFVL) 93 | /// \param dir Direction (RD) 94 | /// \param scatter Scattering type (DGSs) 95 | /// 96 | /// That of course can be wildcards or any other expression willing to match them. And then you can 97 | /// provide extra expressions to match the custom labels: 98 | /// 99 | /// \param custom Custom label regexps 100 | /// 101 | /// And the function will automatically add a "[^stop_mark]*stop_mark" at the end. 102 | /// 103 | LPexp *buildStop(LPexp *etype, LPexp *scatter, const std::list &custom); 104 | /// Gicen that a symbol is ready in head() to parse, parse it 105 | LPexp *parseSymbol(); 106 | /// Gicen that a symbol is ready in head() to parse, parse it as a ustring 107 | /// and report it was a custom symbol in the iscustom flag 108 | ustring parseRawSymbol(bool &iscustom); 109 | /// Given that the begining of a concatenation of regexps is ready to parse, parse it 110 | /// and it can be optionally be enclosed in parentheis () 111 | LPexp *parseCat(); 112 | /// Given that a fully qualified group like <.RD'custom'> is ready to parse, parse it 113 | LPexp *parseGroup(); 114 | /// Given that a ^abcde] (note missing [) is ready to parse, parse it 115 | LPexp *parseNegor(); 116 | /// Given that [abcde] is ready to parse, parse it, but if it finds that it was actually 117 | /// [^abcd], fall back to parseNegor 118 | LPexp *parseOrlist(); 119 | /// Given that a range like {5,7} or {2,} or {3} is ready to parse, parse it and return 120 | /// the range. Second number being -1 if if was {2,} and equals the first if it was {3} 121 | std::pair parseRange(); 122 | /// Take an already parsed lpexp and parse its possible modifier (*={}) if present and 123 | /// return the new lpexp 124 | LPexp *parseModifier(LPexp *e); 125 | /// Generic parse whatever comes next (just one item) 126 | LPexp *_parse(); 127 | 128 | // error string 129 | std::string m_error; 130 | // True if we are actually parsing a group <>, since otherwise everything gets 131 | // automatically converted to a group, this prevents that happening 132 | bool m_ingroup; 133 | // maps each basic label to its expected possition in the appearance order, for instance 134 | // the direction label can't be in the fisrt pos of a group. This way we know where to put the 135 | // expression when the user writes just S, which translates to <..S> 136 | SymbolToInt m_label_position; 137 | // The set of the basic labels 138 | SymbolSet m_basic_labels; 139 | // The black list for our wildcards, that have to exclude always the stop mark 140 | SymbolSet m_minus_stop; 141 | 142 | // Current text being parsed 143 | std::string m_text; 144 | // Current position in the text for head() 145 | size_t m_pos; 146 | }; 147 | 148 | 149 | OSL_NAMESPACE_EXIT 150 | -------------------------------------------------------------------------------- /nuke/OSL/include/OSL/lpexp.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include "automata.h" 32 | 33 | OSL_NAMESPACE_ENTER 34 | 35 | 36 | namespace lpexp { 37 | 38 | // This is just a pair of states, see the use of the function genAuto in LPexp 39 | // for a justification of this type that we use throughout all the regexp code 40 | typedef std::pair FirstLast; 41 | 42 | /// LPexp atom type for the getType method 43 | typedef enum { 44 | CAT, 45 | OR, 46 | SYMBOL, 47 | WILDCARD, 48 | REPEAT, 49 | NREPEAT 50 | }Regtype; 51 | 52 | 53 | 54 | /// Base class for a light path expression 55 | // 56 | /// Light path expressions are arranged as an abstract syntax tree. All the 57 | /// nodes in that tree satisfy this interface that basicaly makes the automate 58 | /// generation easy and clear. 59 | /// 60 | /// The node types for this tree are: 61 | /// CAT: Concatenation of regexps like abcde or (abcde) 62 | /// OR: Ored union of two or more expressions like a|b|c|d 63 | /// SYMBOL Just a symbol like G or 'customlabel' 64 | /// WILDCARD The wildcard regexp for . or [^GS] 65 | /// REPEAT Generic unlimited repetition of the child expression (exp)* 66 | /// NREPEAT Bounded repetition of the child expression like (exp){n,m} 67 | /// 68 | class LPexp { 69 | public: 70 | virtual ~LPexp() {}; 71 | 72 | /// Generate automata states for this subtree 73 | /// 74 | /// This method recursively builds all the needed automata states of 75 | /// the tree rooted by this node and returns the begin and end states 76 | /// for it. That means that if it were the only thing in the automata, 77 | /// making retvalue.first initial state and retvalue.second final state, 78 | /// would be the right thing to do. 79 | /// 80 | virtual FirstLast genAuto(NdfAutomata &automata)const = 0; 81 | /// Get the type for this node 82 | virtual Regtype getType()const = 0; 83 | /// For the parser's convenience. It is easy to implement things like a+ 84 | /// as aa*. So the amount of regexp classes gets reduced. For doing that 85 | /// it needs an abstract clone function 86 | virtual LPexp * clone()const = 0; 87 | }; 88 | 89 | 90 | 91 | /// LPexp concatenation 92 | class Cat : public LPexp { 93 | public: 94 | virtual ~Cat(); 95 | void append(LPexp *regexp); 96 | virtual FirstLast genAuto(NdfAutomata &automata)const; 97 | virtual Regtype getType()const { return CAT; }; 98 | virtual LPexp * clone()const; 99 | 100 | protected: 101 | std::list m_children; 102 | }; 103 | 104 | 105 | 106 | /// Basic symbol like G or 'customlabel' 107 | class Symbol : public LPexp { 108 | public: 109 | Symbol(ustring sym) { m_sym = sym; }; 110 | virtual ~Symbol() {}; 111 | 112 | virtual FirstLast genAuto(NdfAutomata &automata)const; 113 | virtual Regtype getType()const { return SYMBOL; }; 114 | virtual LPexp * clone()const { return new Symbol(*this); }; 115 | 116 | protected: 117 | // All symbols are unique ustrings 118 | ustring m_sym; 119 | }; 120 | 121 | 122 | 123 | /// Wildcard regexp 124 | /// 125 | /// Named like this to avoid confusion with the automata Wildcard class 126 | class Wildexp : public LPexp { 127 | public: 128 | Wildexp(SymbolSet &minus):m_wildcard(minus) {}; 129 | virtual ~Wildexp() {}; 130 | 131 | virtual FirstLast genAuto(NdfAutomata &automata)const; 132 | virtual Regtype getType()const { return WILDCARD; }; 133 | virtual LPexp * clone()const { return new Wildexp(*this); }; 134 | 135 | protected: 136 | // And internally we use the automata's Wildcard type 137 | Wildcard m_wildcard; 138 | }; 139 | 140 | 141 | 142 | /// Ored list of expressions 143 | class Orlist : public LPexp { 144 | public: 145 | virtual ~Orlist(); 146 | void append(LPexp *regexp); 147 | virtual FirstLast genAuto(NdfAutomata &automata)const; 148 | virtual Regtype getType()const { return OR; }; 149 | virtual LPexp * clone()const; 150 | 151 | protected: 152 | std::list m_children; 153 | }; 154 | 155 | 156 | 157 | // Unlimited repeat: (exp)* 158 | class Repeat : public LPexp { 159 | public: 160 | Repeat(LPexp *child):m_child(child) {}; 161 | virtual ~Repeat() { delete m_child; }; 162 | virtual FirstLast genAuto(NdfAutomata &automata)const; 163 | virtual Regtype getType()const { return REPEAT; }; 164 | virtual LPexp * clone()const { return new Repeat(m_child->clone()); }; 165 | 166 | protected: 167 | LPexp *m_child; 168 | }; 169 | 170 | 171 | 172 | // Bounded repeat: (exp){m,n} 173 | class NRepeat : public LPexp { 174 | public: 175 | NRepeat(LPexp *child, int min, int max):m_child(child),m_min(min),m_max(max) {}; 176 | virtual ~NRepeat() { delete m_child; }; 177 | virtual FirstLast genAuto(NdfAutomata &automata)const; 178 | virtual Regtype getType()const { return NREPEAT; }; 179 | virtual LPexp * clone()const { return new NRepeat(m_child->clone(), m_min, m_max); }; 180 | 181 | protected: 182 | LPexp *m_child; 183 | int m_min, m_max; 184 | }; 185 | 186 | 187 | 188 | /// Toplevel rule definition 189 | /// 190 | /// Note that although it has almost the same interface, this is not 191 | /// a LPexp. It actually binds a light path expression to a certain rule. 192 | /// Making the begin state initial and the end state final. It can't be 193 | /// nested in other light path expressions, it is the root of the tree. 194 | class Rule 195 | { 196 | public: 197 | Rule(LPexp *child, void *rule):m_child(child), m_rule(rule) {}; 198 | virtual ~Rule() { delete m_child; }; 199 | void genAuto(NdfAutomata &automata)const; 200 | 201 | protected: 202 | LPexp *m_child; 203 | // Anonymous pointer to the associated object for this rule 204 | void *m_rule; 205 | }; 206 | 207 | } // namespace regexp 208 | 209 | OSL_NAMESPACE_EXIT 210 | -------------------------------------------------------------------------------- /nuke/OSL/include/OSL/optautomata.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | 33 | #include 34 | 35 | OSL_NAMESPACE_ENTER 36 | 37 | class DfAutomata; 38 | 39 | 40 | /// Optimized compact version of DfAutomata 41 | /// 42 | /// Apparently hash maps suck in speed for our transition tables. This 43 | /// is a fast compact equivalent of the DfAutomata designed for read 44 | /// only operations. 45 | /// 46 | class DfOptimizedAutomata 47 | { 48 | public: 49 | 50 | void compileFrom(const DfAutomata &dfautomata); 51 | 52 | int getTransition(int state, ustring symbol)const 53 | { 54 | const State &mystate = m_states[state]; 55 | const Transition *begin = &m_trans[mystate.begin_trans]; 56 | const Transition *end = begin + mystate.ntrans; 57 | while (begin < end) { // binary search 58 | const Transition *middle = begin + ((end - begin)>>1); 59 | if (symbol.data() < middle->symbol.data()) 60 | end = middle; 61 | else if (middle->symbol.data() < symbol.data()) 62 | begin = middle + 1; 63 | else // match 64 | return middle->state; 65 | } 66 | return mystate.wildcard_trans; 67 | } 68 | 69 | void * const * getRules(int state, int &count)const 70 | { 71 | count = m_states[state].nrules; 72 | return &m_rules[m_states[state].begin_rules]; 73 | } 74 | 75 | bool empty() const 76 | { 77 | return (m_states.size() == 0) || (m_rules.size() == 0); 78 | } 79 | 80 | protected: 81 | struct State 82 | { 83 | unsigned int begin_trans; 84 | unsigned int ntrans; 85 | unsigned int begin_rules; 86 | unsigned int nrules; 87 | int wildcard_trans; 88 | }; 89 | struct Transition 90 | { 91 | // we use this only for sorting 92 | static bool trans_comp (const Transition &a, const Transition &b); 93 | ustring symbol; 94 | int state; 95 | }; 96 | std::vector m_trans; 97 | std::vector m_rules; 98 | std::vector m_states; 99 | }; 100 | 101 | OSL_NAMESPACE_EXIT 102 | -------------------------------------------------------------------------------- /nuke/OSL/include/OSL/oslclosure.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | #include "oslconfig.h" 34 | 35 | OSL_NAMESPACE_ENTER 36 | 37 | /// Labels for light walks 38 | /// 39 | /// This is the leftover of a class which used to hold all the labels 40 | /// Now just acts as a little namespace for the basic definitions 41 | /// 42 | /// NOTE: you still can assign these labels as keyword arguments to 43 | /// closures. But we have removed the old labels array in the 44 | /// primitives. 45 | class OSLEXECPUBLIC Labels { 46 | public: 47 | 48 | static const ustring NONE; 49 | // Event type 50 | static const ustring CAMERA; 51 | static const ustring LIGHT; 52 | static const ustring BACKGROUND; 53 | static const ustring TRANSMIT; 54 | static const ustring REFLECT; 55 | static const ustring VOLUME; 56 | static const ustring OBJECT; 57 | // Scattering 58 | static const ustring DIFFUSE; // typical 2PI hemisphere 59 | static const ustring GLOSSY; // blurry reflections and transmissions 60 | static const ustring SINGULAR; // perfect mirrors and glass 61 | static const ustring STRAIGHT; // Special case for transparent shadows 62 | 63 | static const ustring STOP; // end of a surface description 64 | 65 | }; 66 | 67 | // Forward declarations 68 | struct ClosureComponent; 69 | struct ClosureMul; 70 | struct ClosureAdd; 71 | 72 | /// ClosureColor is the base class for a lightweight tree representation 73 | /// of OSL closures for the sake of the executing OSL shader. 74 | /// 75 | /// Remember that a closure color really just boils down to a flat list 76 | /// of weighted closure primitive components (such as diffuse, 77 | /// transparent, etc.). But it's expensive to construct these 78 | /// dynamically as we execute the shader, so instead of maintaining a 79 | /// properly flattened list as we go, we just manipulate a very 80 | /// lightweight data structure that looks like a tree, where leaf nodes 81 | /// are a single primitive component, and internal nodes of the tree are 82 | /// are either 'add' (two closures) or 'mul' (of a closure with a 83 | /// weight) and just reference their operands by pointers. 84 | /// 85 | /// We are extremely careful to make these classes resemble POD (plain 86 | /// old data) so they can be easily "placed" anywhere, including a memory 87 | /// pool. So no virtual functions! 88 | /// 89 | /// The base class ClosureColor just provides the type, and it's 90 | /// definitely one of the three kinds of subclasses: ClosureComponent, 91 | /// ClosureMul, ClosureAdd. 92 | struct OSLEXECPUBLIC ClosureColor { 93 | enum ClosureID { COMPONENT_BASE_ID = 0, MUL = -1, ADD = -2 }; 94 | 95 | int id; 96 | 97 | const ClosureComponent* as_comp() const { 98 | DASSERT(id >= COMPONENT_BASE_ID); 99 | return reinterpret_cast(this); 100 | } 101 | 102 | const ClosureMul* as_mul() const { 103 | DASSERT(id == MUL); 104 | return reinterpret_cast(this); 105 | } 106 | 107 | const ClosureAdd* as_add() const { 108 | DASSERT(id == ADD); 109 | return reinterpret_cast(this); 110 | } 111 | }; 112 | 113 | 114 | 115 | /// ClosureComponent is a subclass of ClosureColor that holds the ID and 116 | /// parameter data for a single primitive closure component (such as 117 | /// diffuse, translucent, etc.). The declaration leaves 4 bytes for 118 | /// parameter data (mem), but it's expected that the structure be 119 | /// allocated with enough space to house all the parameter data for 120 | /// whatever type of custom primitive component it actually is. 121 | struct OSLEXECPUBLIC ClosureComponent : public ClosureColor 122 | { 123 | Vec3 w; ///< Weight of this component 124 | char mem[4]; ///< Memory for the primitive 125 | /// 4 is the minimum, allocation 126 | /// will be scaled to requirements 127 | /// of the primitive 128 | 129 | /// Handy method for getting the parameter memory as a void*. 130 | /// 131 | void *data () { return &mem; } 132 | const void *data () const { return &mem; } 133 | 134 | /// Handy methods for extracting the underlying parameters as a struct 135 | template 136 | const T* as() const { return reinterpret_cast(mem); } 137 | 138 | template 139 | T* as() { return reinterpret_cast(mem); } 140 | }; 141 | 142 | 143 | /// ClosureMul is a subclass of ClosureColor that provides a lightweight 144 | /// way to represent a closure multiplied by a scalar or color weight. 145 | struct OSLEXECPUBLIC ClosureMul : public ClosureColor 146 | { 147 | Color3 weight; 148 | const ClosureColor *closure; 149 | }; 150 | 151 | 152 | /// ClosureAdd is a subclass of ClosureColor that provides a lightweight 153 | /// way to represent a closure that is a sum of two other closures. 154 | struct OSLEXECPUBLIC ClosureAdd : public ClosureColor 155 | { 156 | const ClosureColor *closureA; 157 | const ClosureColor *closureB; 158 | }; 159 | 160 | OSL_NAMESPACE_EXIT 161 | -------------------------------------------------------------------------------- /nuke/OSL/include/OSL/oslconfig.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | ///////////////////////////////////////////////////////////////////////// 32 | /// \file 33 | /// Various compile-time defaults are defined here that could, in 34 | /// principle, be redefined if you are using OSL in some particular 35 | /// renderer that wanted things a different way. 36 | ///////////////////////////////////////////////////////////////////////// 37 | 38 | // Detect if we're C++11. 39 | // 40 | // Note: oslversion.h defined OSL_BUILD_CPP11 to be 1 if OSL was built 41 | // using C++11. In contrast, OSL_CPLUSPLUS_VERSION defined below will be set 42 | // to the right number for the C++ standard being compiled RIGHT NOW. These 43 | // two things may be the same when compiling OSL, but they may not be the 44 | // same if another packages is compiling against OSL and using these headers 45 | // (OSL may be C++11 but the client package may be older, or vice versa -- 46 | // use these two symbols to differentiate these cases, when important). 47 | #if (__cplusplus >= 201402L) 48 | # define OSL_CPLUSPLUS_VERSION 14 49 | #elif (__cplusplus >= 201103L) 50 | # define OSL_CPLUSPLUS_VERSION 11 51 | #else 52 | # define OSL_CPLUSPLUS_VERSION 3 /* presume C++03 */ 53 | #endif 54 | 55 | // Symbol export defines 56 | #include "export.h" 57 | 58 | // All the things we need from Imath 59 | #include 60 | #include 61 | #include 62 | 63 | // All the things we need from OpenImageIO 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | 71 | // Sort out smart pointers 72 | #if OSL_CPLUSPLUS_VERSION >= 11 73 | # include 74 | #else /* FIXME(C++11): remove this after making C++11 the baseline */ 75 | # include 76 | #endif 77 | 78 | // Extensions to Imath 79 | #include "matrix22.h" 80 | 81 | #include "oslversion.h" 82 | 83 | OSL_NAMESPACE_ENTER 84 | 85 | 86 | /// By default, we operate with single precision float. Change this 87 | /// definition to make a shading system that fundamentally operates 88 | /// on doubles. 89 | /// FIXME: it's very likely that all sorts of other things will break 90 | /// if you do this, but eventually we should make sure it works. 91 | typedef float Float; 92 | 93 | /// By default, use the excellent Imath vector, matrix, and color types 94 | /// from the IlmBase package from: http://www.openexr.com 95 | /// 96 | /// It's permissible to override these types with the vector, matrix, 97 | /// and color classes of your choice, provided that (a) your vectors 98 | /// have the same data layout as a simple Float[n]; (b) your 99 | /// matrices have the same data layout as Float[n][n]; and (c) your 100 | /// classes have most of the obvious constructors and overloaded 101 | /// operators one would expect from a C++ vector/matrix/color class. 102 | typedef Imath::Vec3 Vec3; 103 | typedef Imath::Matrix33 Matrix33; 104 | typedef Imath::Matrix44 Matrix44; 105 | typedef Imath::Color3 Color3; 106 | typedef Imath::Vec2 Vec2; 107 | 108 | typedef Imathx::Matrix22 Matrix22; 109 | 110 | /// Assume that we are dealing with OpenImageIO's texture system. It 111 | /// doesn't literally have to be OIIO's... it just needs to have the 112 | /// same API as OIIO's TextureSystem class, it's a purely abstract class 113 | /// anyway. 114 | using OIIO::TextureSystem; 115 | using OIIO::TextureOpt; 116 | 117 | // And some other things we borrow from OIIO... 118 | using OIIO::ErrorHandler; 119 | using OIIO::TypeDesc; 120 | using OIIO::ustring; 121 | using OIIO::ustringHash; 122 | using OIIO::string_view; 123 | 124 | // Sort out smart pointers 125 | #if OSL_CPLUSPLUS_VERSION >= 11 126 | using std::shared_ptr; 127 | using std::weak_ptr; 128 | #else /* FIXME(C++11): remove this after making C++11 the baseline */ 129 | using boost::shared_ptr; 130 | using boost::weak_ptr; 131 | #endif 132 | 133 | #ifndef __has_attribute 134 | # define __has_attribute(x) 0 135 | #endif 136 | 137 | #if OSL_CPLUSPLUS_VERSION >= 14 && __has_attribute(deprecated) 138 | # define OSL_DEPRECATED(msg) [[deprecated(msg)]] 139 | #elif (defined(__GNUC__) && OIIO_GNUC_VERSION >= 40600) || defined(__clang__) 140 | # define OSL_DEPRECATED(msg) __attribute__((deprecated(msg))) 141 | #elif defined(__GNUC__) /* older gcc -- only the one with no message */ 142 | # define OSL_DEPRECATED(msg) __attribute__((deprecated)) 143 | #elif defined(_MSC_VER) 144 | # define OSL_DEPRECATED(msg) __declspec(deprecated(msg)) 145 | #else 146 | # define OSL_DEPRECATED(msg) 147 | #endif 148 | 149 | OSL_NAMESPACE_EXIT 150 | -------------------------------------------------------------------------------- /nuke/OSL/include/OSL/oslversion.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2011 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | 30 | #ifndef OSLVERSION_H 31 | #define OSLVERSION_H 32 | 33 | 34 | // Versions. There are three different sets of version numbers: 35 | // (a) The version of the OSL language specification itself, i.e., 36 | // what is OSL syntax, semantics, and standard library. 37 | // (b) The version of the OSL library, i.e., this very software whose 38 | // source code you are reading. 39 | // (c) The version of the .oso file format that this library uses 40 | // for compiled shaders. 41 | // These are all independent, though loosely coupled. 42 | 43 | // Version of the language: 44 | #define OSL_VERSION_MAJOR 1 45 | #define OSL_VERSION_MINOR 8 46 | #define OSL_VERSION_PATCH 8 47 | #define OSL_VERSION (10000 * OSL_VERSION_MAJOR + \ 48 | 100 * OSL_VERSION_MINOR + \ 49 | OSL_VERSION_PATCH) 50 | 51 | // Version of this library: 52 | #define OSL_LIBRARY_VERSION_MAJOR 1 53 | #define OSL_LIBRARY_VERSION_MINOR 8 54 | #define OSL_LIBRARY_VERSION_PATCH 8 55 | #define OSL_LIBRARY_VERSION_RELEASE_TYPE 56 | 57 | #define OSL_LIBRARY_VERSION_CODE (10000 * OSL_LIBRARY_VERSION_MAJOR + \ 58 | 100 * OSL_LIBRARY_VERSION_MINOR + \ 59 | OSL_LIBRARY_VERSION_PATCH) 60 | 61 | // Magic macros to make OSL_LIBRARY_VERSION_STRING that looks like "1.2.3" 62 | #define OSL_MAKE_VERSION_STRING2(a,b,c,d) #a "." #b "." #c #d 63 | #define OSL_MAKE_VERSION_STRING(a,b,c,d) OSL_MAKE_VERSION_STRING2(a,b,c,d) 64 | #define OSL_LIBRARY_VERSION_STRING \ 65 | OSL_MAKE_VERSION_STRING(OSL_LIBRARY_VERSION_MAJOR, \ 66 | OSL_LIBRARY_VERSION_MINOR, \ 67 | OSL_LIBRARY_VERSION_PATCH, \ 68 | OSL_LIBRARY_VERSION_RELEASE_TYPE) 69 | #define OSL_INTRO_STRING "OpenShadingLanguage " OSL_LIBRARY_VERSION_STRING 70 | #define OSL_COPYRIGHT_STRING "(c) Copyright 2009-2014 Sony Pictures Imageworks, et al. All rights reserved." 71 | 72 | 73 | // Version numbers for the compiled shader format. The major number 74 | // should only be changed if old .oso files should not be expected to 75 | // work with current versions of the library (this should be EXTREMELY 76 | // rare, hopefully never). The minor number may be changed if newly 77 | // compiled shaders won't work for old libraries, which sometimes 78 | // happens but still should not be often. Adding a new hint or a new 79 | // shader instruction is not considered a change to the file format! 80 | #define OSO_FILE_VERSION_MAJOR 1 81 | #define OSO_FILE_VERSION_MINOR 0 82 | 83 | 84 | // Symbols documenting specific API or other changes 85 | #define OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS 1 86 | #define OSL_SHADERGLOBALS_HAS_RENDERER_PTR 1 87 | 88 | 89 | #ifdef OSL_NAMESPACE 90 | // Macros to use in each file to enter and exit the right name spaces. 91 | #define OSL_NAMESPACE_ENTER namespace OSL_NAMESPACE { namespace OSL { 92 | #define OSL_NAMESPACE_EXIT } } using namespace OSL_NAMESPACE; 93 | #else 94 | #define OSL_NAMESPACE_ENTER namespace OSL { 95 | #define OSL_NAMESPACE_EXIT } 96 | #endif 97 | 98 | // OSL_BUILD_CPP11 will be 1 if this OSL was built using C++11 99 | #define OSL_BUILD_CPP11 1 100 | // OSL_BUILD_CPP14 will be 1 if this OSL was built using C++14 101 | #define OSL_BUILD_CPP14 0 102 | 103 | #endif /* OSLVERSION_H */ 104 | -------------------------------------------------------------------------------- /nuke/OSL/include/OSL/shaderglobals.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2013 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | 31 | 32 | OSL_NAMESPACE_ENTER 33 | 34 | struct ClosureColor; 35 | class ShadingContext; 36 | class RendererServices; 37 | 38 | 39 | 40 | /// Type for an opaque pointer to whatever the renderer uses to represent a 41 | /// coordinate transformation. 42 | typedef const void * TransformationPtr; 43 | 44 | 45 | 46 | 47 | /// The ShaderGlobals structure represents the state describing a particular 48 | /// point to be shaded. It serves two primary purposes: (1) it holds the 49 | /// values of the "global" variables accessible from a shader (such as P, N, 50 | /// Ci, etc.); (2) it serves as a means of passing (via opaque pointers) 51 | /// additional state between the renderer when it invokes the shader, and 52 | /// the RendererServices that fields requests from OSL back to the renderer. 53 | /// 54 | /// Except where noted, it is expected that all values are filled in by the 55 | /// renderer before passing it to ShadingSystem::execute() to actually run 56 | /// the shader. Not all fields will be valid in all contexts. In particular, 57 | /// a few are only needed for lights and volumes. 58 | /// 59 | /// All points, vectors and normals are given in "common" space. 60 | /// 61 | struct ShaderGlobals { 62 | 63 | /// Surface position (and its x & y differentials). 64 | Vec3 P, dPdx, dPdy; 65 | /// P's z differential, used for volume shading only. 66 | Vec3 dPdz; 67 | 68 | /// Incident ray, and its x and y derivatives. 69 | Vec3 I, dIdx, dIdy; 70 | 71 | /// Shading normal, already front-facing. 72 | Vec3 N; 73 | 74 | /// True geometric normal. 75 | Vec3 Ng; 76 | 77 | /// 2D surface parameter u, and its differentials. 78 | float u, dudx, dudy; 79 | /// 2D surface parameter v, and its differentials. 80 | float v, dvdx, dvdy; 81 | 82 | /// Surface tangents: derivative of P with respect to surface u and v. 83 | Vec3 dPdu, dPdv; 84 | 85 | /// Time for this shading sample. 86 | float time; 87 | /// Time interval for the frame (or shading sample). 88 | float dtime; 89 | /// Velocity vector: derivative of position P with respect to time. 90 | Vec3 dPdtime; 91 | 92 | /// For lights or light attenuation shaders: the point being illuminated 93 | /// (Ps), and its differentials. 94 | Vec3 Ps, dPsdx, dPsdy; 95 | 96 | /// There are three opaque pointers that may be set by the renderer here 97 | /// in the ShaderGlobals before shading execution begins, and then 98 | /// retrieved again from the within the implementation of various 99 | /// RendererServices methods. Exactly what they mean and how they are 100 | /// used is renderer-dependent, but roughly speaking it's probably a 101 | /// pointer to some internal renderer state (needed for, say, figuring 102 | /// out how to retrieve userdata), state about the ray tree (needed to 103 | /// resume for a trace() call), and information about the object being 104 | /// shaded. 105 | void* renderstate; 106 | void* tracedata; 107 | void* objdata; 108 | 109 | /// Back-pointer to the ShadingContext (set and used by OSL itself -- 110 | /// renderers shouldn't mess with this at all). 111 | ShadingContext* context; 112 | 113 | /// Pointer to the RendererServices object. This is how OSL finds its 114 | /// way back to the renderer for callbacks. 115 | RendererServices* renderer; 116 | 117 | /// Opaque pointers set by the renderer before shader execution, to 118 | /// allow later retrieval of the object->common and shader->common 119 | /// transformation matrices, by the RendererServices 120 | /// get_matrix/get_inverse_matrix methods. This doesn't need to point 121 | /// to the 4x4 matrix itself; rather, it's just a pointer to whatever 122 | /// structure the RenderServices::get_matrix() needs to (if and when 123 | /// requested) generate the 4x4 matrix for the right time value. 124 | TransformationPtr object2common; 125 | TransformationPtr shader2common; 126 | 127 | /// The output closure will be placed here. The rendererer should 128 | /// initialize this to NULL before shading execution, and this is where 129 | /// it can retrieve the output closure from after shader execution has 130 | /// completed. 131 | ClosureColor *Ci; 132 | 133 | /// Surface area of the emissive object (used by light shaders for 134 | /// energy normalization). 135 | float surfacearea; 136 | 137 | /// Bit field of ray type flags. 138 | int raytype; 139 | 140 | /// If nonzero, will flip the result of calculatenormal(). 141 | int flipHandedness; 142 | 143 | /// If nonzero, we are shading the back side of a surface. 144 | int backfacing; 145 | }; 146 | 147 | 148 | OSL_NAMESPACE_EXIT 149 | -------------------------------------------------------------------------------- /nuke/OSL/lpexp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. 3 | All Rights Reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of Sony Pictures Imageworks nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #include "OSL/lpexp.h" 30 | 31 | 32 | OSL_NAMESPACE_ENTER 33 | 34 | 35 | 36 | 37 | lpexp::FirstLast 38 | lpexp::Cat::genAuto(NdfAutomata &automata)const 39 | { 40 | NdfAutomata::State * first = NULL; 41 | NdfAutomata::State * last = NULL; 42 | // Sequentially create the states for the expressions and link them all by 43 | // lambda transitions. Making the begin state of the first one our begin, and the 44 | // end state of the last one our end 45 | for (std::list::const_iterator i = m_children.begin(); i != m_children.end(); ++i) { 46 | FirstLast fl = (*i)->genAuto(automata); 47 | if (!first) 48 | first = fl.first; 49 | else 50 | // This is not the first of the list, so link it from the previous 51 | // one end state 52 | last->addTransition(lambda, fl.first); 53 | last = fl.second; 54 | } 55 | return FirstLast(first, last); 56 | } 57 | 58 | 59 | 60 | void 61 | lpexp::Cat::append(LPexp *lpexp) 62 | { 63 | m_children.push_back(lpexp); 64 | } 65 | 66 | 67 | 68 | lpexp::Cat::~Cat() 69 | { 70 | for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) 71 | delete *i; 72 | } 73 | 74 | 75 | 76 | lpexp::LPexp * 77 | lpexp::Cat::clone()const 78 | { 79 | Cat *newcat = new Cat(); 80 | for (std::list::const_iterator i = m_children.begin(); i != m_children.end(); ++i) 81 | newcat->append((*i)->clone()); 82 | return newcat; 83 | } 84 | 85 | 86 | 87 | lpexp::FirstLast 88 | lpexp::Symbol::genAuto(NdfAutomata &automata)const 89 | { 90 | // Easiest lpexp ever. Two new states, than join the first to 91 | // the second with the symbol we got 92 | NdfAutomata::State *begin = automata.newState(); 93 | NdfAutomata::State *end = automata.newState(); 94 | begin->addTransition(m_sym, end); 95 | return FirstLast(begin, end); 96 | } 97 | 98 | 99 | 100 | lpexp::FirstLast 101 | lpexp::Wildexp::genAuto(NdfAutomata &automata)const 102 | { 103 | // Same as the Symbol lpexp but with a wildcard insted of a symbol 104 | NdfAutomata::State *begin = automata.newState(); 105 | NdfAutomata::State *end = automata.newState(); 106 | begin->addWildcardTransition(new Wildcard(m_wildcard), end); 107 | return FirstLast(begin, end); 108 | } 109 | 110 | 111 | 112 | lpexp::FirstLast 113 | lpexp::Orlist::genAuto(NdfAutomata &automata)const 114 | { 115 | // Cat was like a serial circuit and this is a parallel one. We need 116 | // two new states begin and end 117 | NdfAutomata::State *begin = automata.newState(); 118 | NdfAutomata::State *end = automata.newState(); 119 | for (std::list::const_iterator i = m_children.begin(); i != m_children.end(); ++i) { 120 | // And then for every child we create its part of automata and link our begin to its 121 | // begin and its end to our end with lambda transitions 122 | FirstLast fl = (*i)->genAuto(automata); 123 | begin->addTransition(lambda, fl.first); 124 | fl.second->addTransition(lambda, end); 125 | } 126 | return FirstLast(begin, end); 127 | } 128 | 129 | 130 | 131 | void 132 | lpexp::Orlist::append(LPexp *lpexp) 133 | { 134 | m_children.push_back(lpexp); 135 | } 136 | 137 | 138 | 139 | lpexp::Orlist::~Orlist() 140 | { 141 | for (std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) 142 | delete *i; 143 | } 144 | 145 | 146 | 147 | lpexp::LPexp * 148 | lpexp::Orlist::clone()const 149 | { 150 | Orlist *newor = new Orlist(); 151 | for (std::list::const_iterator i = m_children.begin(); i != m_children.end(); ++i) 152 | newor->append((*i)->clone()); 153 | return newor; 154 | } 155 | 156 | 157 | 158 | lpexp::FirstLast 159 | lpexp::Repeat::genAuto(NdfAutomata &automata)const 160 | { 161 | NdfAutomata::State *begin = automata.newState(); 162 | NdfAutomata::State *end = automata.newState(); 163 | FirstLast fl = m_child->genAuto(automata); 164 | begin->addTransition(lambda, fl.first); 165 | fl.second->addTransition(lambda, end); 166 | // Easy, make its begin and end states almost the same with 167 | // lambda transitions so it can repeat for ever 168 | begin->addTransition(lambda, end); 169 | end->addTransition(lambda, begin); 170 | return FirstLast(begin, end); 171 | } 172 | 173 | 174 | 175 | lpexp::FirstLast 176 | lpexp::NRepeat::genAuto(NdfAutomata &automata)const 177 | { 178 | NdfAutomata::State *first = NULL; 179 | NdfAutomata::State *last = NULL; 180 | int i; 181 | // This is a bit trickier. For {m.n} we first make a concatenation of 182 | // the child expression m times 183 | for (i = 0; i < m_min; ++i) { 184 | FirstLast fl = m_child->genAuto(automata); 185 | if (!first) 186 | first = fl.first; 187 | else 188 | last->addTransition(lambda, fl.first); 189 | last = fl.second; 190 | } 191 | // And then n - m aditional movements. But we make them optional using 192 | // lambda transitions 193 | if (!last && i < m_max) 194 | first = last = automata.newState(); 195 | for (; i < m_max; ++i) { 196 | FirstLast fl = m_child->genAuto(automata); 197 | last->addTransition(lambda, fl.first); 198 | // Since this repetitions are optional, put a bypass with lambda 199 | last->addTransition(lambda, fl.second); 200 | last = fl.second; 201 | } 202 | return FirstLast(first, last); 203 | } 204 | 205 | 206 | 207 | void 208 | lpexp::Rule::genAuto(NdfAutomata &automata)const 209 | { 210 | // First generate the actual automata 211 | FirstLast fl = m_child->genAuto(automata); 212 | // now, put the rule in the last state (making it a final state) 213 | fl.second->setRule(m_rule); 214 | // And then make its begin state accessible from the master initial state 215 | // of the automata so it becomes initial too 216 | automata.getInitial()->addTransition(lambda, fl.first); 217 | } 218 | 219 | 220 | OSL_NAMESPACE_EXIT 221 | -------------------------------------------------------------------------------- /nuke/PickingKnob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | 17 | #if defined(_MSC_VER) && (_MSC_VER == 1600) 18 | #define FLT_RADIX 2 19 | #pragma warning(push, 0) 20 | #include 21 | #pragma warning(pop) 22 | #undef hypotf 23 | #endif 24 | 25 | #include "PickingKnob.h" 26 | #include "DeepOpenEXRId.h" 27 | 28 | using namespace DD::Image; 29 | 30 | // This is what Nuke will call once the below stuff is executed: 31 | bool handle_cb(ViewerContext* ctx, Knob* knob, int index) 32 | { 33 | if (ctx->event() == PUSH) 34 | { 35 | ((PickingKnob*)knob)->show = true; 36 | ((PickingKnob*)knob)->x0 = ctx->x(); 37 | ((PickingKnob*)knob)->y0 = ctx->y(); 38 | } 39 | if (ctx->event() == RELEASE) 40 | { 41 | ((PickingKnob*)knob)->show = false; 42 | const float x1 = ctx->x(); 43 | const float y1 = ctx->y(); 44 | ((PickingKnob*)knob)->theOp->select(((PickingKnob*)knob)->x0,((PickingKnob*)knob)->y0,x1,y1, 45 | (ctx->state()&SHIFT)!=0); 46 | } 47 | return true; 48 | } 49 | 50 | // Nuke calls this to draw the handle, this then calls make_handle 51 | // which tells Nuke to call the above function when the mouse does 52 | // something... 53 | void PickingKnob::draw_handle(ViewerContext* ctx) 54 | { 55 | if (ctx->event() == DRAW_OPAQUE 56 | || ctx->event() == PUSH // true for clicking hit-detection 57 | || ctx->event() == DRAG // true for selection box hit-detection 58 | ) { 59 | 60 | if (ctx->event() == DRAW_OPAQUE && show) 61 | { 62 | const float x1 = ctx->x(); 63 | const float y1 = ctx->y(); 64 | glPushAttrib (GL_ENABLE_BIT|GL_CURRENT_BIT); 65 | glColor3f(1, 1, 1); 66 | 67 | glEnable(GL_COLOR_LOGIC_OP); 68 | glLogicOp(GL_XOR); 69 | glLineStipple(1, 0xF0F0); 70 | glEnable(GL_LINE_STIPPLE); 71 | 72 | glBegin(GL_LINE_STRIP); 73 | 74 | glVertex2f(x0, y0); 75 | glVertex2f(x1, y0); 76 | glVertex2f(x1, y1); 77 | glVertex2f(x0, y1); 78 | glVertex2f(x0, y0); 79 | 80 | glEnd(); 81 | glPopAttrib (); 82 | } 83 | // Make clicks anywhere in the viewer call handle() with index = 0. 84 | // This takes the lowest precedence over, so above will be detected 85 | // first. 86 | begin_handle(Knob::ANYWHERE, ctx, handle_cb, 0 /*index*/, 0, 0, 0 /*xyz*/); 87 | end_handle(ctx); 88 | } 89 | } 90 | 91 | // And you need to implement this just to make it call draw_handle: 92 | bool PickingKnob::build_handle(ViewerContext* ctx) 93 | { 94 | // If your handles only work in 2D or 3D mode, only return true 95 | // in those cases: 96 | // return (ctx->transform_mode() == VIEWER_2D); 97 | return true; 98 | } 99 | 100 | PickingKnob::PickingKnob(Knob_Closure* kc, DeepOpenEXRId* t, const char* n) : Knob(kc, n), show(false) 101 | { 102 | theOp = t; 103 | } 104 | -------------------------------------------------------------------------------- /nuke/PickingKnob.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #pragma once 17 | 18 | #include "DDImage/Knobs.h" 19 | 20 | class PickingKnob : public DD::Image::Knob 21 | { 22 | public: 23 | class DeepOpenEXRId* theOp; 24 | const char* Class() const { return "PickingKnob"; } 25 | 26 | // Nuke calls this to draw the handle, this then calls make_handle 27 | // which tells Nuke to call the above function when the mouse does 28 | // something... 29 | void draw_handle(DD::Image::ViewerContext* ctx); 30 | 31 | // And you need to implement this just to make it call draw_handle: 32 | bool build_handle(DD::Image::ViewerContext* ctx); 33 | 34 | PickingKnob(DD::Image::Knob_Closure* kc, DeepOpenEXRId* t, const char* n); 35 | 36 | float x0, y0; 37 | bool show; 38 | }; 39 | -------------------------------------------------------------------------------- /nuke/b64.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Base64 encoding/decoding (RFC1341) 3 | * Copyright (c) 2005-2011, Jouni Malinen 4 | * 5 | * This software may be distributed under the terms of the BSD license. 6 | * See README for more details. 7 | */ 8 | 9 | // 2016-12-12 - Gaspard Petit : Slightly modified to return a std::string 10 | // instead of a buffer allocated with malloc. 11 | 12 | #include 13 | 14 | static const unsigned char base64_table[65] = 15 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 16 | 17 | /** 18 | * base64_encode - Base64 encode 19 | * @src: Data to be encoded 20 | * @len: Length of the data to be encoded 21 | * @out_len: Pointer to output length variable, or %NULL if not used 22 | * Returns: Allocated buffer of out_len bytes of encoded data, 23 | * or empty string on failure 24 | */ 25 | std::string base64_encode(const unsigned char *src, size_t len) 26 | { 27 | unsigned char *out, *pos; 28 | const unsigned char *end, *in; 29 | 30 | size_t olen; 31 | 32 | olen = 4*((len + 2) / 3); /* 3-byte blocks to 4-byte */ 33 | 34 | if (olen < len) 35 | return std::string(); /* integer overflow */ 36 | 37 | std::string outStr; 38 | outStr.resize(olen); 39 | out = (unsigned char*)&outStr[0]; 40 | 41 | end = src + len; 42 | in = src; 43 | pos = out; 44 | while (end - in >= 3) { 45 | *pos++ = base64_table[in[0] >> 2]; 46 | *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; 47 | *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; 48 | *pos++ = base64_table[in[2] & 0x3f]; 49 | in += 3; 50 | } 51 | 52 | if (end - in) { 53 | *pos++ = base64_table[in[0] >> 2]; 54 | if (end - in == 1) { 55 | *pos++ = base64_table[(in[0] & 0x03) << 4]; 56 | *pos++ = '='; 57 | } 58 | else { 59 | *pos++ = base64_table[((in[0] & 0x03) << 4) | 60 | (in[1] >> 4)]; 61 | *pos++ = base64_table[(in[1] & 0x0f) << 2]; 62 | } 63 | *pos++ = '='; 64 | } 65 | 66 | return outStr; 67 | } 68 | // *************************************************************************** 69 | 70 | static const int B64index[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 73 | 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 74 | 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 75 | 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 76 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; 77 | 78 | std::string b64decode(const void* data, const size_t len) 79 | { 80 | unsigned char* p = (unsigned char*)data; 81 | int pad = len > 0 && (len % 4 || p[len - 1] == '='); 82 | const size_t L = ((len + 3) / 4 - pad) * 4; 83 | std::string str(L / 4 * 3 + pad, '\0'); 84 | 85 | for (size_t i = 0, j = 0; i < L; i += 4) 86 | { 87 | int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]]; 88 | str[j++] = n >> 16; 89 | str[j++] = n >> 8 & 0xFF; 90 | str[j++] = n & 0xFF; 91 | } 92 | if (pad) 93 | { 94 | int n = B64index[p[L]] << 18 | B64index[p[L + 1]] << 12; 95 | str[str.size() - 1] = n >> 16; 96 | 97 | if (len > L + 2 && p[L + 2] != '=') 98 | { 99 | n |= B64index[p[L + 2]] << 6; 100 | str.push_back(n >> 8 & 0xFF); 101 | } 102 | } 103 | return str; 104 | } 105 | 106 | std::string b64encode(const std::string &str) 107 | { 108 | return base64_encode((const unsigned char *)str.c_str(), str.size()); 109 | } 110 | 111 | std::string b64decode(const std::string &str) 112 | { 113 | return b64decode(str.c_str(), str.size()); 114 | } 115 | -------------------------------------------------------------------------------- /nuke/md5.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * RFC 1321 compliant MD5 implementation 3 | * 4 | * Copyright (C) 2001-2003 Christophe Devine 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #include "md5.h" 25 | 26 | #define GET_UINT32(n,b,i) \ 27 | { \ 28 | (n) = ( (uint32_t) (b)[(i) ] ) \ 29 | | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 30 | | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 31 | | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 32 | } 33 | 34 | #define PUT_UINT32(n,b,i) \ 35 | { \ 36 | (b)[(i) ] = (uint8_t) ( (n) ); \ 37 | (b)[(i) + 1] = (uint8_t) ( (n) >> 8 ); \ 38 | (b)[(i) + 2] = (uint8_t) ( (n) >> 16 ); \ 39 | (b)[(i) + 3] = (uint8_t) ( (n) >> 24 ); \ 40 | } 41 | 42 | void md5_starts( md5_context *ctx ) 43 | { 44 | ctx->total[0] = 0; 45 | ctx->total[1] = 0; 46 | 47 | ctx->state[0] = 0x67452301; 48 | ctx->state[1] = 0xEFCDAB89; 49 | ctx->state[2] = 0x98BADCFE; 50 | ctx->state[3] = 0x10325476; 51 | } 52 | 53 | void md5_process( md5_context *ctx, const uint8_t data[64] ) 54 | { 55 | uint32_t X[16], A, B, C, D; 56 | 57 | GET_UINT32( X[0], data, 0 ); 58 | GET_UINT32( X[1], data, 4 ); 59 | GET_UINT32( X[2], data, 8 ); 60 | GET_UINT32( X[3], data, 12 ); 61 | GET_UINT32( X[4], data, 16 ); 62 | GET_UINT32( X[5], data, 20 ); 63 | GET_UINT32( X[6], data, 24 ); 64 | GET_UINT32( X[7], data, 28 ); 65 | GET_UINT32( X[8], data, 32 ); 66 | GET_UINT32( X[9], data, 36 ); 67 | GET_UINT32( X[10], data, 40 ); 68 | GET_UINT32( X[11], data, 44 ); 69 | GET_UINT32( X[12], data, 48 ); 70 | GET_UINT32( X[13], data, 52 ); 71 | GET_UINT32( X[14], data, 56 ); 72 | GET_UINT32( X[15], data, 60 ); 73 | 74 | #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 75 | 76 | #define P(a,b,c,d,k,s,t) \ 77 | { \ 78 | a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ 79 | } 80 | 81 | A = ctx->state[0]; 82 | B = ctx->state[1]; 83 | C = ctx->state[2]; 84 | D = ctx->state[3]; 85 | 86 | #define F(x,y,z) (z ^ (x & (y ^ z))) 87 | 88 | P( A, B, C, D, 0, 7, 0xD76AA478 ); 89 | P( D, A, B, C, 1, 12, 0xE8C7B756 ); 90 | P( C, D, A, B, 2, 17, 0x242070DB ); 91 | P( B, C, D, A, 3, 22, 0xC1BDCEEE ); 92 | P( A, B, C, D, 4, 7, 0xF57C0FAF ); 93 | P( D, A, B, C, 5, 12, 0x4787C62A ); 94 | P( C, D, A, B, 6, 17, 0xA8304613 ); 95 | P( B, C, D, A, 7, 22, 0xFD469501 ); 96 | P( A, B, C, D, 8, 7, 0x698098D8 ); 97 | P( D, A, B, C, 9, 12, 0x8B44F7AF ); 98 | P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); 99 | P( B, C, D, A, 11, 22, 0x895CD7BE ); 100 | P( A, B, C, D, 12, 7, 0x6B901122 ); 101 | P( D, A, B, C, 13, 12, 0xFD987193 ); 102 | P( C, D, A, B, 14, 17, 0xA679438E ); 103 | P( B, C, D, A, 15, 22, 0x49B40821 ); 104 | 105 | #undef F 106 | 107 | #define F(x,y,z) (y ^ (z & (x ^ y))) 108 | 109 | P( A, B, C, D, 1, 5, 0xF61E2562 ); 110 | P( D, A, B, C, 6, 9, 0xC040B340 ); 111 | P( C, D, A, B, 11, 14, 0x265E5A51 ); 112 | P( B, C, D, A, 0, 20, 0xE9B6C7AA ); 113 | P( A, B, C, D, 5, 5, 0xD62F105D ); 114 | P( D, A, B, C, 10, 9, 0x02441453 ); 115 | P( C, D, A, B, 15, 14, 0xD8A1E681 ); 116 | P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); 117 | P( A, B, C, D, 9, 5, 0x21E1CDE6 ); 118 | P( D, A, B, C, 14, 9, 0xC33707D6 ); 119 | P( C, D, A, B, 3, 14, 0xF4D50D87 ); 120 | P( B, C, D, A, 8, 20, 0x455A14ED ); 121 | P( A, B, C, D, 13, 5, 0xA9E3E905 ); 122 | P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); 123 | P( C, D, A, B, 7, 14, 0x676F02D9 ); 124 | P( B, C, D, A, 12, 20, 0x8D2A4C8A ); 125 | 126 | #undef F 127 | 128 | #define F(x,y,z) (x ^ y ^ z) 129 | 130 | P( A, B, C, D, 5, 4, 0xFFFA3942 ); 131 | P( D, A, B, C, 8, 11, 0x8771F681 ); 132 | P( C, D, A, B, 11, 16, 0x6D9D6122 ); 133 | P( B, C, D, A, 14, 23, 0xFDE5380C ); 134 | P( A, B, C, D, 1, 4, 0xA4BEEA44 ); 135 | P( D, A, B, C, 4, 11, 0x4BDECFA9 ); 136 | P( C, D, A, B, 7, 16, 0xF6BB4B60 ); 137 | P( B, C, D, A, 10, 23, 0xBEBFBC70 ); 138 | P( A, B, C, D, 13, 4, 0x289B7EC6 ); 139 | P( D, A, B, C, 0, 11, 0xEAA127FA ); 140 | P( C, D, A, B, 3, 16, 0xD4EF3085 ); 141 | P( B, C, D, A, 6, 23, 0x04881D05 ); 142 | P( A, B, C, D, 9, 4, 0xD9D4D039 ); 143 | P( D, A, B, C, 12, 11, 0xE6DB99E5 ); 144 | P( C, D, A, B, 15, 16, 0x1FA27CF8 ); 145 | P( B, C, D, A, 2, 23, 0xC4AC5665 ); 146 | 147 | #undef F 148 | 149 | #define F(x,y,z) (y ^ (x | ~z)) 150 | 151 | P( A, B, C, D, 0, 6, 0xF4292244 ); 152 | P( D, A, B, C, 7, 10, 0x432AFF97 ); 153 | P( C, D, A, B, 14, 15, 0xAB9423A7 ); 154 | P( B, C, D, A, 5, 21, 0xFC93A039 ); 155 | P( A, B, C, D, 12, 6, 0x655B59C3 ); 156 | P( D, A, B, C, 3, 10, 0x8F0CCC92 ); 157 | P( C, D, A, B, 10, 15, 0xFFEFF47D ); 158 | P( B, C, D, A, 1, 21, 0x85845DD1 ); 159 | P( A, B, C, D, 8, 6, 0x6FA87E4F ); 160 | P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); 161 | P( C, D, A, B, 6, 15, 0xA3014314 ); 162 | P( B, C, D, A, 13, 21, 0x4E0811A1 ); 163 | P( A, B, C, D, 4, 6, 0xF7537E82 ); 164 | P( D, A, B, C, 11, 10, 0xBD3AF235 ); 165 | P( C, D, A, B, 2, 15, 0x2AD7D2BB ); 166 | P( B, C, D, A, 9, 21, 0xEB86D391 ); 167 | 168 | #undef F 169 | 170 | ctx->state[0] += A; 171 | ctx->state[1] += B; 172 | ctx->state[2] += C; 173 | ctx->state[3] += D; 174 | } 175 | 176 | void md5_update( md5_context *ctx, const uint8_t *input, uint32_t length ) 177 | { 178 | uint32_t left, fill; 179 | 180 | if( ! length ) return; 181 | 182 | left = ctx->total[0] & 0x3F; 183 | fill = 64 - left; 184 | 185 | ctx->total[0] += length; 186 | ctx->total[0] &= 0xFFFFFFFF; 187 | 188 | if( ctx->total[0] < length ) 189 | ctx->total[1]++; 190 | 191 | if( left && length >= fill ) 192 | { 193 | memcpy( (void *) (ctx->buffer + left), 194 | (const void *) input, fill ); 195 | md5_process( ctx, ctx->buffer ); 196 | length -= fill; 197 | input += fill; 198 | left = 0; 199 | } 200 | 201 | while( length >= 64 ) 202 | { 203 | md5_process( ctx, input ); 204 | length -= 64; 205 | input += 64; 206 | } 207 | 208 | if( length ) 209 | { 210 | memcpy( (void *) (ctx->buffer + left), 211 | (const void *) input, length ); 212 | } 213 | } 214 | 215 | static uint8_t md5_padding[64] = 216 | { 217 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 221 | }; 222 | 223 | void md5_finish( md5_context *ctx, uint8_t digest[16] ) 224 | { 225 | uint32_t last, padn; 226 | uint32_t high, low; 227 | uint8_t msglen[8]; 228 | 229 | high = ( ctx->total[0] >> 29 ) 230 | | ( ctx->total[1] << 3 ); 231 | low = ( ctx->total[0] << 3 ); 232 | 233 | PUT_UINT32( low, msglen, 0 ); 234 | PUT_UINT32( high, msglen, 4 ); 235 | 236 | last = ctx->total[0] & 0x3F; 237 | padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 238 | 239 | md5_update( ctx, md5_padding, padn ); 240 | md5_update( ctx, msglen, 8 ); 241 | 242 | PUT_UINT32( ctx->state[0], digest, 0 ); 243 | PUT_UINT32( ctx->state[1], digest, 4 ); 244 | PUT_UINT32( ctx->state[2], digest, 8 ); 245 | PUT_UINT32( ctx->state[3], digest, 12 ); 246 | } 247 | -------------------------------------------------------------------------------- /nuke/md5.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | typedef struct 5 | { 6 | uint32_t total[2]; 7 | uint32_t state[4]; 8 | uint8_t buffer[64]; 9 | } 10 | md5_context; 11 | 12 | void md5_starts( md5_context *ctx ); 13 | void md5_update( md5_context *ctx, const uint8_t *input, uint32_t length ); 14 | void md5_finish( md5_context *ctx, uint8_t digest[16] ); 15 | 16 | -------------------------------------------------------------------------------- /nuke/menu.py: -------------------------------------------------------------------------------- 1 | m = nuke.menu( 'Nodes' ).findItem( 'Deep' ) 2 | m.addCommand( 'DeepOpenEXRId', lambda: nuke.createNode('DeepOpenEXRId') ) 3 | -------------------------------------------------------------------------------- /nuke/nuke.cmake: -------------------------------------------------------------------------------- 1 | 2 | PROJECT(OpenEXRIdForNuke${NDK_VERSION}) 3 | 4 | FILE(GLOB_RECURSE PROJECT_HDR "${CMAKE_CURRENT_LIST_DIR}/../nuke/*.h") 5 | FILE(GLOB_RECURSE PROJECT_SRC "${CMAKE_CURRENT_LIST_DIR}/../nuke/*.cpp") 6 | FILE(GLOB_RECURSE PROJECT_OSL_HDR "${CMAKE_CURRENT_LIST_DIR}/../nuke/OSL/include/OSL/*.h") 7 | FILE(GLOB_RECURSE PROJECT_OSL_SRC "${CMAKE_CURRENT_LIST_DIR}/../nuke/OSL/*.cpp") 8 | 9 | SOURCE_GROUP("Headers" FILES ${PROJECT_HDR}) 10 | SOURCE_GROUP("Sources" FILES ${PROJECT_SRC}) 11 | SOURCE_GROUP("Osl Headers" FILES ${PROJECT_OSL_HDR}) 12 | SOURCE_GROUP("Osl Sources" FILES ${PROJECT_OSL_SRC}) 13 | ADD_COMPILE_DEFINITIONS(NUKE_VERSION=Nuke${NDK_VERSION}) 14 | IF(WIN32) 15 | ADD_COMPILE_DEFINITIONS(oslexec_EXPORTS) 16 | ADD_COMPILE_DEFINITIONS(OSL_STATIC_LIBRARY) 17 | ENDIF(WIN32) 18 | 19 | INCLUDE_DIRECTORIES("${NDK_PATH}/include") 20 | INCLUDE_DIRECTORIES("${OPENEXRID_ROOT}/nuke/OSL/include") 21 | 22 | ADD_LIBRARY(${PROJECT_NAME} SHARED ${PROJECT_HDR} ${PROJECT_SRC} ${PROJECT_OSL_HDR} ${PROJECT_OSL_SRC}) 23 | 24 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OPENIMAGEIO_LIBRARIES} re2 ${OPENEXR_LIBRARIES} ${NDK_LIBRARIES} ${BOOST_LIBRARIES} ${OPENGL_LIBRARIES} ${ZLIB_LIBRARIES}) 25 | IF (TARGET IlmBase::Half) 26 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IlmBase::Half) 27 | ENDIF () 28 | 29 | IF (UNIX) 30 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "") 31 | ENDIF (UNIX) 32 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "DeepOpenEXRId") 33 | 34 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES 35 | ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${OPENEXRID_ROOT}/build/debug/lib/nuke${NDK_VERSION} 36 | LIBRARY_OUTPUT_DIRECTORY_DEBUG ${OPENEXRID_ROOT}/build/debug/lib/nuke${NDK_VERSION} 37 | RUNTIME_OUTPUT_DIRECTORY_DEBUG ${OPENEXRID_ROOT}/build/debug/lib/nuke${NDK_VERSION} 38 | ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${OPENEXRID_ROOT}/build/relwithdebinfo/lib/nuke${NDK_VERSION} 39 | LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${OPENEXRID_ROOT}/build/relwithdebinfo/lib/nuke${NDK_VERSION} 40 | RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${OPENEXRID_ROOT}/build/relwithdebinfo/lib/nuke${NDK_VERSION} 41 | ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${OPENEXRID_ROOT}/build/release/lib/nuke${NDK_VERSION} 42 | LIBRARY_OUTPUT_DIRECTORY_RELEASE ${OPENEXRID_ROOT}/build/release/lib/nuke${NDK_VERSION} 43 | RUNTIME_OUTPUT_DIRECTORY_RELEASE ${OPENEXRID_ROOT}/build/release/lib/nuke${NDK_VERSION} 44 | ) 45 | 46 | 47 | IF (WIN32) 48 | ADD_CUSTOM_COMMAND(TARGET ${PROJECT_NAME} POST_BUILD 49 | COMMAND ${CMAKE_COMMAND} -E copy $ $ENV{HOMEDRIVE}$ENV{HOMEPATH}\\.nuke\\ ) 50 | ENDIF (WIN32) 51 | 52 | SET_VS_FOLDER(Hosts/Nuke/) 53 | -------------------------------------------------------------------------------- /nuke/zlib.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | // *************************************************************************** 23 | 24 | // Inflate using zlib 25 | std::string inflate (const std::string& str) 26 | { 27 | z_stream zs; 28 | memset(&zs, 0, sizeof(zs)); 29 | 30 | if (inflateInit(&zs) != Z_OK) 31 | throw (std::runtime_error("inflateInit failed while decompressing.")); 32 | 33 | zs.next_in = (Bytef*)str.data(); 34 | zs.avail_in = (uInt)str.size(); 35 | 36 | int ret; 37 | char outbuffer[32768]; 38 | std::string outstring; 39 | 40 | do 41 | { 42 | zs.next_out = reinterpret_cast(outbuffer); 43 | zs.avail_out = sizeof(outbuffer); 44 | 45 | ret = inflate(&zs, 0); 46 | 47 | if (outstring.size() < zs.total_out) 48 | { 49 | outstring.append(outbuffer, 50 | zs.total_out - outstring.size()); 51 | } 52 | 53 | } 54 | while (ret == Z_OK); 55 | 56 | inflateEnd(&zs); 57 | 58 | if (ret != Z_STREAM_END) 59 | { 60 | std::ostringstream oss; 61 | oss << "Exception during zlib decompression: (" << ret << ") " << zs.msg; 62 | throw (std::runtime_error(oss.str())); 63 | } 64 | 65 | return outstring; 66 | } 67 | 68 | // *************************************************************************** 69 | -------------------------------------------------------------------------------- /nuke11.1/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 11.1) 3 | SET(NDK_PATH ${NUKE111_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE111_LIBRARY}) 5 | 6 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 7 | -------------------------------------------------------------------------------- /nuke11.2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 11.2) 3 | SET(NDK_PATH ${NUKE112_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE112_LIBRARY}) 5 | 6 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 7 | -------------------------------------------------------------------------------- /nuke11.3/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 11.3) 3 | SET(NDK_PATH ${NUKE113_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE113_LIBRARY}) 5 | 6 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 7 | -------------------------------------------------------------------------------- /nuke12.0/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 12.0) 3 | SET(NDK_PATH ${NUKE120_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE120_LIBRARY}) 5 | 6 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 7 | -------------------------------------------------------------------------------- /nuke12.1/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 12.1) 3 | SET(NDK_PATH ${NUKE121_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE121_LIBRARY}) 5 | 6 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 7 | -------------------------------------------------------------------------------- /nuke12.2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 12.2) 3 | SET(NDK_PATH ${NUKE122_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE122_LIBRARY}) 5 | 6 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 7 | -------------------------------------------------------------------------------- /nuke13.0/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 13.0) 3 | SET(NDK_PATH ${NUKE130_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE130_LIBRARY}) 5 | 6 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 7 | -------------------------------------------------------------------------------- /nuke13.2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 13.2) 3 | SET(NDK_PATH ${NUKE132_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE132_LIBRARY}) 5 | 6 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 7 | -------------------------------------------------------------------------------- /nuke14.0/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 14.0) 3 | SET(NDK_PATH ${NUKE140_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE140_LIBRARY}) 5 | 6 | ADD_DEFINITIONS(-DNOMINMAX) 7 | ADD_DEFINITIONS(-D_USE_MATH_DEFINES) 8 | 9 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 10 | -------------------------------------------------------------------------------- /nuke15.1/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 15.1) 3 | SET(NDK_PATH ${NUKE151_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE151_LIBRARY}) 5 | 6 | ADD_DEFINITIONS(-DNOMINMAX) 7 | ADD_DEFINITIONS(-D_USE_MATH_DEFINES) 8 | 9 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 10 | -------------------------------------------------------------------------------- /nuke16.0/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | SET(NDK_VERSION 16.0) 3 | SET(NDK_PATH ${NUKE160_LIBRARY_DIR}) 4 | SET(NDK_LIBRARIES ${DDIMAGE160_LIBRARY}) 5 | 6 | ADD_DEFINITIONS(-DNOMINMAX) 7 | ADD_DEFINITIONS(-D_USE_MATH_DEFINES) 8 | 9 | INCLUDE(${CMAKE_CURRENT_LIST_DIR}/../nuke/nuke.cmake) 10 | -------------------------------------------------------------------------------- /openexrid/Builder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #include "Builder.h" 17 | #include "Mask.h" 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | using namespace Imf; 34 | using namespace openexrid; 35 | using namespace std; 36 | 37 | // Compression 38 | extern std::string b64encode (const std::string &data); 39 | extern std::string deflate (const char *str, int len); 40 | 41 | //********************************************************************** 42 | 43 | Builder::Builder (int width, int height, const std::vector &slices) : _Width (width), _Height (height), _Finished (false), _Pixels (width*height), _Slices (slices) {} 44 | 45 | //********************************************************************** 46 | 47 | void Builder::addCoverage (int x, int y, uint32_t id, float z, float weight, const float *sliceValues) 48 | { 49 | // The pixel sample list 50 | SampleList &sl = _Pixels[x+y*_Width]; 51 | sl.addCoverage (id, z, weight, sliceValues, (int)_Slices.size ()); 52 | } 53 | 54 | //********************************************************************** 55 | 56 | static int PtFuncCompare(void const *a, void const *b) 57 | { 58 | float _a = ((SampleList::Header*)a)->Z; 59 | float _b = ((SampleList::Header*)b)->Z; 60 | return _a < _b ? -1 : _a > _b ? 1 : 0; 61 | } 62 | 63 | void Builder::finish (const std::vector &weightSums) 64 | { 65 | if (_Finished) 66 | throw runtime_error ("Builder::finish has been already called"); 67 | 68 | std::vector::iterator ite = std::find (_Slices.begin(), _Slices.end (), "A"); 69 | if (ite == _Slices.end()) 70 | throw runtime_error ("No A channel"); 71 | const int A = (int)(ite-_Slices.begin ()); 72 | 73 | const int vn = (int)_Slices.size (); 74 | std::vector acc; 75 | int index = 0; 76 | for (vector::iterator ite = _Pixels.begin(); ite != _Pixels.end(); ++ite, ++index) 77 | { 78 | acc.clear (); 79 | acc.resize (vn, 0.f); 80 | 81 | // Normalize the values by the weight sum 82 | ite->normalize (weightSums[index], vn); 83 | 84 | // Sort the samples in the pixel by Z 85 | const int sn = ite->getSampleN (vn); 86 | if (sn > 0) 87 | qsort (&ite->getSampleHeader(0,vn), sn, sizeof(uint32_t)*(SampleList::HeaderSize+vn), PtFuncCompare); 88 | 89 | // Cumulate the values in the EXR deep image way 90 | for (int s = 0; s < sn; ++s) 91 | { 92 | float *values = ite->getSampleValues (s,vn); 93 | for (int v = 0; v < vn; ++v) 94 | values[v] = (acc[v] += values[v]); 95 | } 96 | for (int s = sn-1; s > 0; --s) 97 | { 98 | float *values = ite->getSampleValues (s,vn); 99 | float *valuesPrev = ite->getSampleValues (s-1,vn); 100 | const float oma = 1.f-valuesPrev[A]; 101 | for (int v = 0; v < vn; ++v) 102 | values[v] = (values[v]-valuesPrev[v])/(oma > 0.f ? oma : 1.f); 103 | } 104 | } 105 | 106 | _Finished = true; 107 | } 108 | 109 | //********************************************************************** 110 | 111 | void Builder::write (const char *filename, const char *names, int namesLength, const char *namesHash, 112 | bool computeDataWindow, Compression compression) const 113 | { 114 | if (!_Finished) 115 | throw runtime_error ("Builder::finish has not been called"); 116 | 117 | const int vn = (int)_Slices.size (); 118 | 119 | Imath::Box2i dataW; 120 | 121 | // If required, compute the data window 122 | if (computeDataWindow) 123 | { 124 | for (int y = 0; y < _Height; ++y) 125 | for (int x = 0; x < _Width; ++x) 126 | { 127 | if (_Pixels[x+y*_Width].getSampleN (vn) > 0) 128 | dataW.extendBy (Imath::V2i (x, y)); 129 | } 130 | 131 | // Exr doesn't like empty images 132 | if (dataW.isEmpty()) 133 | { 134 | dataW.extendBy (Imath::V2i(0,0)); 135 | } 136 | else 137 | { 138 | dataW.min.x = std::max (0, int (dataW.min.x)-1); 139 | dataW.max.x = std::min (int (_Width-1), int (dataW.max.x)+1); 140 | dataW.min.y = std::max (0, int (dataW.min.y)-1); 141 | dataW.max.y = std::min (int (_Height-1), int (dataW.max.y)+1); 142 | } 143 | } 144 | else 145 | { 146 | // Or use the whole image 147 | dataW = Imath::Box2i (Imath::V2i(0,0),Imath::V2i(_Width-1,_Height-1)); 148 | } 149 | 150 | // EXR Header 151 | // Right now, the image window is the data window 152 | Header header (_Width, _Height, dataW); 153 | header.channels().insert ("Id", Channel (UINT)); 154 | header.channels().insert ("Z", Channel (FLOAT)); 155 | for (size_t s = 0; s < _Slices.size (); ++s) 156 | header.channels().insert (_Slices[s], Channel (HALF)); 157 | header.setType (DEEPSCANLINE); 158 | header.compression () = compression; 159 | 160 | // Write the names in an Attribute 161 | header.insert ("EXRIdVersion", Imf::IntAttribute (Mask::Version)); 162 | header.insert ("EXRIdNames", Imf::StringAttribute (b64encode(deflate (names, namesLength)))); 163 | // Add the hash if provided 164 | if (namesHash != NULL) 165 | header.insert ("EXRIdHash", Imf::StringAttribute (std::string (namesHash))); 166 | 167 | DeepScanLineOutputFile file (filename, header); 168 | DeepFrameBuffer frameBuffer; 169 | 170 | // Build a sample count buffer for a line 171 | vector sampleCount (_Width); 172 | frameBuffer.insertSampleCountSlice (Imf::Slice (UINT, (char *)(&sampleCount[0]), 173 | sizeof (uint32_t), 174 | 0)); 175 | 176 | // A line of id 177 | vector ids; 178 | vector id (_Width); 179 | frameBuffer.insert ("Id", 180 | DeepSlice (UINT, 181 | (char *) (&id[0]), 182 | sizeof (uint32_t*), 183 | 0, 184 | sizeof (uint32_t))); 185 | 186 | // A line of Z 187 | vector _z; 188 | vector z (_Width); 189 | frameBuffer.insert ("Z", 190 | DeepSlice (FLOAT, 191 | (char *) (&z[0]), 192 | sizeof (float*), 193 | 0, 194 | sizeof (float))); 195 | 196 | // A line of coverage 197 | vector values; 198 | vector > slices (_Slices.size ()); 199 | for (size_t s = 0; s < _Slices.size (); ++s) 200 | { 201 | slices[s].resize (_Width); 202 | frameBuffer.insert (_Slices[s], 203 | DeepSlice (HALF, 204 | (char *) (&slices[s][0]), 205 | sizeof (half*), 206 | 0, 207 | sizeof (half)*vn)); 208 | } 209 | 210 | file.setFrameBuffer(frameBuffer); 211 | 212 | // For each line 213 | for (int y = dataW.min.y; y <= dataW.max.y; y++) 214 | { 215 | const int lineStart = y*_Width; 216 | 217 | ids.clear (); 218 | _z.clear (); 219 | values.clear (); 220 | 221 | // For each pixel 222 | for (int x = 0; x < _Width; x++) 223 | { 224 | const SampleList &sl = _Pixels[lineStart+x]; 225 | const int sn = sl.getSampleN(vn); 226 | for (int s = 0; s < sn; ++s) 227 | { 228 | const SampleList::Header &header = sl.getSampleHeader(s, vn); 229 | ids.push_back (header.Id); 230 | _z.push_back (header.Z); 231 | const float *src = sl.getSampleValues(s, vn); 232 | for (int v = 0; v < vn; ++v) 233 | values.push_back(src[v]); 234 | } 235 | 236 | sampleCount[x] = sn; 237 | } 238 | 239 | int index = 0; 240 | for (int x = 0; x < _Width; x++) 241 | { 242 | const int sn = _Pixels[lineStart+x].getSampleN(vn); 243 | 244 | // Set the ids pointer, it may have changed 245 | id[x] = sn ? &ids[index] : NULL; 246 | z[x] = sn ? &_z[index] : NULL; 247 | for (int v = 0; v < vn; ++v) 248 | { 249 | // Set the value pointers, they may have changed 250 | slices[v][x] = sn ? &values[index*vn+v] : NULL; 251 | } 252 | 253 | index += sn; 254 | } 255 | file.writePixels(1); 256 | } 257 | } 258 | 259 | // *************************************************************************** 260 | -------------------------------------------------------------------------------- /openexrid/Builder.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | #include "Mask.h" 21 | 22 | namespace openexrid 23 | { 24 | 25 | // This class is used during the rendering of the image to accumulate 26 | // the coverage data and then build a Mask object. 27 | class Builder 28 | { 29 | friend class Mask; 30 | public: 31 | 32 | // Initialize a builder 33 | Builder (int width, int height, const std::vector &slices); 34 | 35 | // Add a contribution in the pixel (x,y) for the object 'id'. 36 | // The sliceValues will be multiplied internally by the weight. 37 | // The z is the contribution depth, it is used to generate an approximate deep Z value. 38 | // This method is not thread safe. 39 | void addCoverage (int x, int y, uint32_t id, float z, float weight, const float *sliceValues); 40 | 41 | // Finish the builder 42 | // Call it once before to write 43 | // Once the Builder as been finished, no data can be added. 44 | // weightSums is the accumulated weights for each pixel 45 | // which will be used to normalize the contributions. 46 | void finish (const std::vector &weightSums); 47 | 48 | // Finish 49 | // Write the mask in an EXR file. 50 | // names is the concatenated C strings of the object names 51 | // namesLength is the size of the names buffer 52 | // If computeDataWindow is true, compute the dataWindow of the none empty pixel and store it in the EXR header 53 | void write (const char *filename, const char *names, int namesLength, const char *namesHash, 54 | bool computeDataWindow, Imf::Compression compression=Imf::ZIPS_COMPRESSION) const; 55 | 56 | private: 57 | 58 | // The image resolution. 59 | int _Width, _Height; 60 | 61 | bool _Finished; 62 | 63 | // The sample list per pixel. 64 | std::vector _Pixels; 65 | 66 | std::vector _Slices; 67 | }; 68 | 69 | } 70 | -------------------------------------------------------------------------------- /openexrid/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | PROJECT(LibOpenEXRId) 3 | 4 | FILE(GLOB_RECURSE PROJECT_HDR "${CMAKE_CURRENT_LIST_DIR}/*.h") 5 | FILE(GLOB_RECURSE PROJECT_SRC "${CMAKE_CURRENT_LIST_DIR}/*.cpp") 6 | 7 | SOURCE_GROUP("Headers" FILES ${PROJECT_HDR}) 8 | SOURCE_GROUP("Sources" FILES ${PROJECT_SRC}) 9 | 10 | ADD_LIBRARY(${PROJECT_NAME} STATIC ${PROJECT_HDR} ${PROJECT_SRC}) 11 | 12 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "lib") 13 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "openexrid") 14 | -------------------------------------------------------------------------------- /openexrid/Mask.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #include "Mask.h" 17 | #include "Builder.h" 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | using namespace Imf; 31 | using namespace Imath; 32 | using namespace std; 33 | using namespace openexrid; 34 | 35 | // Compression 36 | extern std::string b64decode (const std::string& str); 37 | extern std::string inflate (const std::string& str); 38 | 39 | // *************************************************************************** 40 | 41 | Mask::Mask () : _Width (0), _Height (0), _A (-1) {} 42 | 43 | // *************************************************************************** 44 | 45 | void Mask::read (const char *filename) 46 | { 47 | DeepScanLineInputFile file (filename); 48 | const Header& header = file.header(); 49 | 50 | const Box2i displayWindow = header.displayWindow(); 51 | _Width = displayWindow.max.x - displayWindow.min.x + 1; 52 | _Height = displayWindow.max.y - displayWindow.min.y + 1; 53 | 54 | const Box2i dataWindow = header.dataWindow(); 55 | 56 | // Check the version 57 | const Imf::IntAttribute *version = header.findTypedAttribute ("EXRIdVersion"); 58 | if (!version) 59 | throw runtime_error ("The EXRIdVersion attribute is missing"); 60 | if (version->value () > (int)Version) 61 | throw runtime_error ("The file has been created by an unknown version of the library"); 62 | 63 | // Get the name attribute 64 | const Imf::StringAttribute *names = header.findTypedAttribute ("EXRIdNames"); 65 | if (!names) 66 | throw runtime_error ("The EXRIdNames attribute is missing"); 67 | 68 | // Copy the names 69 | if (version->value() < 3) 70 | _Names = inflate (names->value ()); 71 | else 72 | _Names = inflate (b64decode(names->value ())); 73 | 74 | // Count the names 75 | int namesN = 0; 76 | { 77 | size_t index = 0; 78 | while (index < _Names.size ()) 79 | { 80 | index += strnlen (&_Names[index], _Names.size ()-index)+1; 81 | ++namesN; 82 | } 83 | } 84 | 85 | // Build the name indexes 86 | _NamesIndexes.clear (); 87 | _NamesIndexes.reserve (namesN); 88 | { 89 | // Current index 90 | size_t index = 0; 91 | while (index < _Names.size ()) 92 | { 93 | // Push the index of the current name 94 | _NamesIndexes.push_back ((uint32_t)index); 95 | index += strnlen (&_Names[index], _Names.size ()-index)+1; 96 | } 97 | assert (_NamesIndexes.size () == namesN); 98 | } 99 | 100 | // Allocate the pixel indexes 101 | _PixelsIndexes.clear (); 102 | _PixelsIndexes.resize (_Width*_Height+1, 0); 103 | 104 | // Initialize the frame buffer 105 | DeepFrameBuffer frameBuffer; 106 | frameBuffer.insertSampleCountSlice (Imf::Slice (UINT, 107 | (char *) (&_PixelsIndexes[0]), 108 | sizeof (uint32_t), 109 | sizeof (uint32_t)*_Width)); 110 | 111 | // For each pixel of a single line, the pointer on the id values 112 | vector id (_Width); 113 | frameBuffer.insert ("Id", DeepSlice (UINT, (char *)&id[0], sizeof (uint32_t*), 0, sizeof (uint32_t))); 114 | 115 | // Read the slices 116 | _Slices.clear (); 117 | const ChannelList &channels = header.channels (); 118 | for (ChannelList::ConstIterator channel = channels.begin (); channel != channels.end (); ++channel) 119 | { 120 | if (channel.channel ().type == HALF) 121 | _Slices.push_back (channel.name()); 122 | } 123 | 124 | // For each pixel of a single line, the pointer on the coverage values 125 | vector > slices (_Slices.size ()); 126 | for (size_t s = 0; s < _Slices.size (); ++s) 127 | { 128 | slices[s].resize (_Width); 129 | frameBuffer.insert (_Slices[s], DeepSlice (HALF, (char *)&slices[s][0], sizeof (half*), 0, sizeof (half))); 130 | } 131 | 132 | file.setFrameBuffer(frameBuffer); 133 | 134 | // Read the whole pixel sample counts 135 | file.readPixelSampleCounts(dataWindow.min.y, dataWindow.max.y); 136 | 137 | // Accumulate the sample counts to get the indexes 138 | // The current index 139 | uint32_t index = 0; 140 | for (int i = 0; i < _Width*_Height+1; ++i) 141 | { 142 | const uint32_t n = _PixelsIndexes[i]; 143 | // Convert from a sample count to a sample index 144 | _PixelsIndexes[i] = index; 145 | index += n; 146 | } 147 | 148 | // Resize the samples 149 | _Ids.clear (); 150 | _Ids.resize (index, 0); 151 | _SlicesData.resize (_Slices.size ()); 152 | for (size_t s = 0; s < _Slices.size (); ++s) 153 | { 154 | _SlicesData[s].clear (); 155 | _SlicesData[s].resize (index, 0.f); 156 | } 157 | 158 | // For each line 159 | for (int y = dataWindow.min.y; y <= dataWindow.max.y; y++) 160 | { 161 | const int lineStart = y*_Width; 162 | // For each pixel 163 | for (int x = 0; x < _Width; x++) 164 | { 165 | const int _i = lineStart+x; 166 | // The sample id and coverage pointers for this pixel 167 | const uint32_t count = _PixelsIndexes[_i+1]-_PixelsIndexes[_i]; 168 | 169 | // Avoid invalide indexes 170 | id[x] = count ? &_Ids[_PixelsIndexes[_i]] : NULL; 171 | for (size_t s = 0; s < _Slices.size (); ++s) 172 | slices[s][x] = count ? &_SlicesData[s][_PixelsIndexes[_i]] : NULL; 173 | } 174 | file.readPixels (y); 175 | 176 | // In version 1, samples are already uncumulated 177 | if (version->value () > 1) 178 | { 179 | const int A = findSlice ("A"); 180 | for (int x = 0; x < _Width; x++) 181 | { 182 | const int _i = lineStart+x; 183 | const uint32_t count = _PixelsIndexes[_i+1]-_PixelsIndexes[_i]; 184 | if (count == 0) continue; 185 | // Uncumulate the pixels value 186 | float prevAlpha = 0.f; 187 | for (uint32_t s = 0; s < count; ++s) 188 | { 189 | const int curr = _PixelsIndexes[_i]+s; 190 | const float alpha = (float)_SlicesData[A][curr]; 191 | for (size_t v = 0; v < _Slices.size (); ++v) 192 | _SlicesData[v][curr] = (1.f-prevAlpha)*_SlicesData[v][curr]; 193 | prevAlpha += (1.f-prevAlpha)*alpha; 194 | } 195 | } 196 | } 197 | } 198 | } 199 | 200 | // *************************************************************************** 201 | -------------------------------------------------------------------------------- /openexrid/Mask.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #pragma once 17 | #include "Sample.h" 18 | #include "Slice.h" 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace openexrid 27 | { 28 | 29 | // The Mask object hold the data needed to dynamically craft the mask images. 30 | // The Mask is built using a Builder object. It can be loaded and saved in an EXR file. 31 | class Mask 32 | { 33 | friend class Query; 34 | public: 35 | 36 | // Build an empty Mask 37 | Mask (); 38 | 39 | // Read a Mask from an EXR file. 40 | // This method throws exceptions in case of reading issues. 41 | void read (const char *filename); 42 | 43 | // Returns the image size 44 | // This method is thread safe 45 | inline std::pair getSize () const; 46 | 47 | // Returns the number of sample in the pixel 48 | // This method is thread safe 49 | inline int getSampleN (int x, int y) const; 50 | 51 | // Returns the pixel n-th sample 52 | // This method is thread safe 53 | // x and y and samples must be in the valid range 54 | inline void getSample (int x, int y, int sample, Sample &result) const; 55 | 56 | // Returns the sample name 57 | // This method is thread safe 58 | // x and y and samples must be in the valid range 59 | // The returned pointer is valid until the Mask content is changed or destroyed 60 | inline const char *getSampleName (int x, int y, int sample) const; 61 | 62 | // Returns the id limit, i-e the largest id + 1. 63 | // This method is thread safe 64 | inline uint32_t getIdN () const; 65 | 66 | // Returns the name using a sample id. 67 | // The id should be < than getIdN(). "" is returned if no name is found for this id. 68 | // The returned pointer is valid until the Mask content is changed or destroyed 69 | // This method is thread safe 70 | inline const char *getName (uint32_t id) const; 71 | 72 | // Returns the number of slice in this image 73 | // This method is thread safe 74 | inline int getSliceN () const; 75 | 76 | // Returns the name of the nth slice 77 | // This method is thread safe 78 | inline const std::string &getSlice (int slice) const; 79 | 80 | // Find a slice by name. 81 | // Returns -1 if the slice is not found. 82 | // This method is thread safe 83 | inline int findSlice (const char *name) const; 84 | 85 | // Mask version 86 | static const uint32_t Version = 3; 87 | private: 88 | 89 | // The image resolution 90 | int _Width, _Height; 91 | 92 | // The alpha channel 93 | int _A; 94 | 95 | // For each name, the index of the begining of the string in the _Names buffer. 96 | std::vector _NamesIndexes; 97 | 98 | // All the names concatenated in a large string. The strings are C strings, 99 | // with an ending \0 character. 100 | std::string _Names; 101 | 102 | // For each pixels, the index of the first pixel sample in the _Samples vector. 103 | // The number of sample in the pixel p is (_PixelsIndexes[p+1]-_PixelsIndexes[p]). 104 | // _PixelsIndexes size is _Width*_Height+1. 105 | std::vector _PixelsIndexes; 106 | 107 | // The pixel id concatenated in a single vector. 108 | std::vector _Ids; 109 | 110 | // The slices available in this mask 111 | std::vector _Slices; 112 | 113 | // The pixel samples concatenated in a single vector. 114 | std::vector > _SlicesData; 115 | }; 116 | 117 | inline std::pair Mask::getSize () const 118 | { 119 | return std::pair (_Width, _Height); 120 | } 121 | 122 | inline int Mask::getSampleN (int x, int y) const 123 | { 124 | const int offset = x+y*_Width; 125 | return _PixelsIndexes[offset+1]-_PixelsIndexes[offset]; 126 | } 127 | 128 | inline void Mask::getSample (int x, int y, int sample, Sample &result) const 129 | { 130 | const int index = _PixelsIndexes[x+y*_Width]+sample; 131 | result.Id = _Ids[index]; 132 | result.Values.clear (); 133 | for (size_t s = 0; s < _Slices.size (); ++s) 134 | result.Values.push_back (_SlicesData[s][index]); 135 | } 136 | 137 | inline const char *Mask::getSampleName (int x, int y, int sample) const 138 | { 139 | return getName (_Ids[_PixelsIndexes[x+y*_Width]+sample]); 140 | } 141 | 142 | inline uint32_t Mask::getIdN () const 143 | { 144 | return (uint32_t)_NamesIndexes.size (); 145 | } 146 | 147 | inline const char *Mask::getName (uint32_t id) const 148 | { 149 | if (id < getIdN ()) 150 | return &_Names[_NamesIndexes[id]]; 151 | else 152 | return ""; 153 | } 154 | 155 | inline int Mask::getSliceN () const 156 | { 157 | return (int)_Slices.size (); 158 | } 159 | 160 | inline const std::string &Mask::getSlice (int slice) const 161 | { 162 | return _Slices[slice]; 163 | } 164 | 165 | inline int Mask::findSlice (const char *name) const 166 | { 167 | std::vector::const_iterator ite = std::find (_Slices.begin (), _Slices.end (), name); 168 | return ite == _Slices.end () ? -1 : (int)(ite-_Slices.begin ()); 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /openexrid/Query.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #pragma once 17 | 18 | #include "Mask.h" 19 | 20 | namespace openexrid 21 | { 22 | 23 | // Query pre processes the Mask data for a specific mask selection 24 | // Query then provide the final mask value 25 | // It is possible to have multiple queries on the same Mask 26 | class Query 27 | { 28 | public: 29 | const openexrid::Mask *TheMask; 30 | 31 | // Build a query object 32 | // The match prototype is : bool match(const char *name) 33 | // The mask pointer must be valid during the queries 34 | // The mask pointer won't be deleted by the Query object 35 | template 36 | inline Query (const Mask *mask, Match match) : TheMask (mask) 37 | { 38 | const size_t namesN = mask->_NamesIndexes.size (); 39 | _State.resize (namesN); 40 | for (size_t i = 0; i < namesN; ++i) 41 | _State[i] = match (&TheMask->_Names[mask->_NamesIndexes[i]]); 42 | } 43 | 44 | // Get the pixel coverage for this query 45 | // This method is thread safe 46 | inline void getSliceData (int x, int y, std::vector &result) 47 | { 48 | result.clear (); 49 | const size_t index = x+y*TheMask->_Width; 50 | const uint32_t begin = TheMask->_PixelsIndexes[index]; 51 | const uint32_t end = TheMask->_PixelsIndexes[index+1]; 52 | 53 | result.clear (); 54 | result.resize (TheMask->_Slices.size (), 0); 55 | for (uint32_t i = begin; i < end; ++i) 56 | { 57 | if (_State[TheMask->_Ids[i]]) 58 | { 59 | for (size_t s = 0; s < TheMask->_Slices.size (); ++s) 60 | result[s] += (float)TheMask->_SlicesData[s][i]; 61 | } 62 | } 63 | } 64 | 65 | // Is this Id selected 66 | // This method is thread safe 67 | inline bool isSelected (uint32_t id) 68 | { 69 | return _State[id]; 70 | } 71 | 72 | private: 73 | 74 | // The match status of every name 75 | std::vector _State; 76 | }; 77 | 78 | } 79 | -------------------------------------------------------------------------------- /openexrid/Sample.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #pragma once 17 | #include 18 | #include 19 | #include 20 | 21 | namespace openexrid 22 | { 23 | 24 | // A pixel sample. A fragment is composed of a name id and a coverage. 25 | class Sample 26 | { 27 | public: 28 | // The Id of the string in the strings vector associated with this coverage value. 29 | uint32_t Id; 30 | 31 | // The average Z of the sample of the object 32 | float Z; 33 | 34 | // The values in the pixel for this string. 35 | // The sum of the coverage values in a pixel shoud be between [0,1]. 36 | std::vector Values; 37 | }; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /openexrid/Slice.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | #include "Mask.h" 21 | 22 | namespace openexrid 23 | { 24 | 25 | /* The SampleList is a single array per pixel. 26 | * Each object present in the pixel as a single entry in this list. 27 | * 28 | * The entry structure is : 29 | * Header 30 | * float[valueN] - accumulated values 31 | */ 32 | class SampleList 33 | { 34 | public: 35 | struct Header 36 | { 37 | uint32_t Id; // Object Id 38 | float Z; // Accumulated Z 39 | float Weight; // Accumulated Weight per fragment to average Z 40 | }; 41 | 42 | 43 | static const int HeaderSize = 3; // Unaligned header size in uint32_t 44 | 45 | inline int getSampleN (int valueN) const 46 | { 47 | return (int)_Data.size ()/(valueN+HeaderSize); 48 | } 49 | Header &getSampleHeader (int sample, int valueN) const 50 | { 51 | return *(Header*)&_Data[sample*(valueN+HeaderSize)]; 52 | } 53 | const float *getSampleValues (int sample, int valueN) const 54 | { 55 | return (const float*)&_Data[sample*(valueN+HeaderSize)+HeaderSize]; 56 | } 57 | float *getSampleValues (int sample, int valueN) 58 | { 59 | return (float*)&_Data[sample*(valueN+HeaderSize)+HeaderSize]; 60 | } 61 | void addCoverage (uint32_t id, float z, float weight, const float *sliceValues, int valueN) 62 | { 63 | if (weight == 0.f) return; 64 | 65 | const int sn = getSampleN (valueN); 66 | for (int s = 0; s < sn; ++s) 67 | { 68 | Header &header = getSampleHeader (s, valueN); 69 | if (header.Id == id) 70 | { 71 | header.Z += z*weight; 72 | header.Weight += weight; 73 | float *values = getSampleValues (s, valueN); 74 | for (int v = 0; v < valueN; ++v) 75 | values[v] += sliceValues[v]*weight; 76 | return; 77 | } 78 | } 79 | 80 | // Not found, add an entry for this id 81 | const size_t index = _Data.size (); 82 | _Data.resize (index+valueN+HeaderSize, 0); 83 | 84 | // The id 85 | Header &header = *(Header*)&_Data[index]; 86 | header.Id = id; 87 | header.Z = z*weight; 88 | header.Weight = weight; 89 | 90 | // The values 91 | for (int v = 0; v < valueN; ++v) 92 | *(float*)&_Data[index+v+HeaderSize] = sliceValues[v]*weight; 93 | } 94 | 95 | // Normalize the samples by the weight sum 96 | void normalize (float weightSum, int valueN) 97 | { 98 | const int sn = getSampleN (valueN); 99 | for (int s = 0; s < sn; ++s) 100 | { 101 | SampleList::Header &header = getSampleHeader(s,valueN); 102 | 103 | // Average the Z using the fragment weight sum, not the pixel weight sum 104 | if (header.Weight != 0) 105 | header.Z /= header.Weight; 106 | 107 | if (weightSum != 0.f) 108 | { 109 | float *values = getSampleValues (s,valueN); 110 | for (int v = 0; v < valueN; ++v) 111 | values[v] /= weightSum; 112 | } 113 | } 114 | } 115 | 116 | private: 117 | std::vector _Data; 118 | }; 119 | 120 | } 121 | -------------------------------------------------------------------------------- /openexrid/Version.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | 21 | namespace openexrid 22 | { 23 | 24 | std::string Version = "1.0-beta.30"; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /openexrid/b64.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Base64 encoding/decoding (RFC1341) 3 | * Copyright (c) 2005-2011, Jouni Malinen 4 | * 5 | * This software may be distributed under the terms of the BSD license. 6 | * See README for more details. 7 | */ 8 | 9 | // 2016-12-12 - Gaspard Petit : Slightly modified to return a std::string 10 | // instead of a buffer allocated with malloc. 11 | 12 | #include 13 | 14 | static const unsigned char base64_table[65] = 15 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 16 | 17 | /** 18 | * base64_encode - Base64 encode 19 | * @src: Data to be encoded 20 | * @len: Length of the data to be encoded 21 | * @out_len: Pointer to output length variable, or %NULL if not used 22 | * Returns: Allocated buffer of out_len bytes of encoded data, 23 | * or empty string on failure 24 | */ 25 | std::string base64_encode(const unsigned char *src, size_t len) 26 | { 27 | unsigned char *out, *pos; 28 | const unsigned char *end, *in; 29 | 30 | size_t olen; 31 | 32 | olen = 4*((len + 2) / 3); /* 3-byte blocks to 4-byte */ 33 | 34 | if (olen < len) 35 | return std::string(); /* integer overflow */ 36 | 37 | std::string outStr; 38 | outStr.resize(olen); 39 | out = (unsigned char*)&outStr[0]; 40 | 41 | end = src + len; 42 | in = src; 43 | pos = out; 44 | while (end - in >= 3) { 45 | *pos++ = base64_table[in[0] >> 2]; 46 | *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; 47 | *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; 48 | *pos++ = base64_table[in[2] & 0x3f]; 49 | in += 3; 50 | } 51 | 52 | if (end - in) { 53 | *pos++ = base64_table[in[0] >> 2]; 54 | if (end - in == 1) { 55 | *pos++ = base64_table[(in[0] & 0x03) << 4]; 56 | *pos++ = '='; 57 | } 58 | else { 59 | *pos++ = base64_table[((in[0] & 0x03) << 4) | 60 | (in[1] >> 4)]; 61 | *pos++ = base64_table[(in[1] & 0x0f) << 2]; 62 | } 63 | *pos++ = '='; 64 | } 65 | 66 | return outStr; 67 | } 68 | // *************************************************************************** 69 | 70 | static const int B64index[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 73 | 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 74 | 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 75 | 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 76 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; 77 | 78 | std::string b64decode(const void* data, const size_t len) 79 | { 80 | unsigned char* p = (unsigned char*)data; 81 | int pad = len > 0 && (len % 4 || p[len - 1] == '='); 82 | const size_t L = ((len + 3) / 4 - pad) * 4; 83 | std::string str(L / 4 * 3 + pad, '\0'); 84 | 85 | for (size_t i = 0, j = 0; i < L; i += 4) 86 | { 87 | int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 | B64index[p[i + 2]] << 6 | B64index[p[i + 3]]; 88 | str[j++] = n >> 16; 89 | str[j++] = n >> 8 & 0xFF; 90 | str[j++] = n & 0xFF; 91 | } 92 | if (pad) 93 | { 94 | int n = B64index[p[L]] << 18 | B64index[p[L + 1]] << 12; 95 | str[str.size() - 1] = n >> 16; 96 | 97 | if (len > L + 2 && p[L + 2] != '=') 98 | { 99 | n |= B64index[p[L + 2]] << 6; 100 | str.push_back(n >> 8 & 0xFF); 101 | } 102 | } 103 | return str; 104 | } 105 | 106 | std::string b64encode(const std::string &str) 107 | { 108 | return base64_encode((const unsigned char *)str.c_str(), str.size()); 109 | } 110 | 111 | std::string b64decode(const std::string &str) 112 | { 113 | return b64decode(str.c_str(), str.size()); 114 | } 115 | -------------------------------------------------------------------------------- /openexrid/zlib.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | // *************************************************************************** 23 | 24 | // Deflate using zlib 25 | std::string deflate (const char *str, int len) 26 | { 27 | z_stream zs; 28 | memset(&zs, 0, sizeof(zs)); 29 | 30 | if (deflateInit(&zs, Z_BEST_COMPRESSION) != Z_OK) 31 | throw (std::runtime_error("deflateInit failed while compressing.")); 32 | 33 | zs.next_in = (Bytef*)str; 34 | zs.avail_in = (uInt)len; 35 | 36 | int ret; 37 | char outbuffer[32]; 38 | std::string outstring; 39 | 40 | do 41 | { 42 | zs.next_out = reinterpret_cast(outbuffer); 43 | zs.avail_out = sizeof(outbuffer); 44 | ret = deflate(&zs, Z_FINISH); 45 | if (outstring.size() < zs.total_out) 46 | { 47 | outstring.append(outbuffer, 48 | zs.total_out - outstring.size()); 49 | } 50 | } 51 | while (ret == Z_OK); 52 | 53 | deflateEnd(&zs); 54 | 55 | if (ret != Z_STREAM_END) 56 | { 57 | std::ostringstream oss; 58 | oss << "Exception during zlib compression: (" << ret << ") " << zs.msg; 59 | throw(std::runtime_error(oss.str())); 60 | } 61 | 62 | return outstring; 63 | } 64 | 65 | // *************************************************************************** 66 | 67 | // Inflate using zlib 68 | std::string inflate (const std::string& str) 69 | { 70 | z_stream zs; 71 | memset(&zs, 0, sizeof(zs)); 72 | 73 | if (inflateInit(&zs) != Z_OK) 74 | throw (std::runtime_error("inflateInit failed while decompressing.")); 75 | 76 | zs.next_in = (Bytef*)str.data(); 77 | zs.avail_in = (uInt)str.size(); 78 | 79 | int ret; 80 | char outbuffer[32768]; 81 | std::string outstring; 82 | 83 | do 84 | { 85 | zs.next_out = reinterpret_cast(outbuffer); 86 | zs.avail_out = sizeof(outbuffer); 87 | 88 | ret = inflate(&zs, 0); 89 | 90 | if (outstring.size() < zs.total_out) 91 | { 92 | outstring.append(outbuffer, 93 | zs.total_out - outstring.size()); 94 | } 95 | 96 | } 97 | while (ret == Z_OK); 98 | 99 | inflateEnd(&zs); 100 | 101 | if (ret != Z_STREAM_END) 102 | { 103 | std::ostringstream oss; 104 | oss << "Exception during zlib decompression: (" << ret << ") " << zs.msg; 105 | throw (std::runtime_error(oss.str())); 106 | } 107 | 108 | return outstring; 109 | } 110 | 111 | // *************************************************************************** 112 | -------------------------------------------------------------------------------- /openfx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | PROJECT(OpenEXRIdOFX) 3 | 4 | FILE(GLOB_RECURSE PROJECT_HDR "${CMAKE_CURRENT_LIST_DIR}/*.h") 5 | FILE(GLOB_RECURSE PROJECT_SRC "${CMAKE_CURRENT_LIST_DIR}/*.cpp") 6 | 7 | SOURCE_GROUP("Headers" FILES ${PROJECT_HDR}) 8 | SOURCE_GROUP("Sources" FILES ${PROJECT_SRC}) 9 | 10 | INCLUDE_DIRECTORIES("${OPENEXRID_ROOT}") 11 | INCLUDE_DIRECTORIES("${OFX_INCLUDE_DIR}") 12 | 13 | ADD_LIBRARY(${PROJECT_NAME} SHARED ${PROJECT_HDR} ${PROJECT_SRC}) 14 | 15 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} LibOpenEXRId) 16 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OPENIMAGEIO_LIBRARIES} re2 ${OPENEXR_LIBRARIES} ${OPENGL_LIBRARIES} ${ZLIB_LIBRARIES}) 17 | IF (TARGET IlmBase::Half) 18 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IlmBase::IlmBaseConfig IlmBase::Half IlmBase::Iex IlmBase::IexMath IlmBase::Imath OpenEXR::IlmImf) 19 | ENDIF () 20 | 21 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "") 22 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "openexrid") 23 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SUFFIX ".ofx") 24 | 25 | IF (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 26 | IF (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.2) 27 | SET(OUTPUT_FOLDER "OFX/") 28 | ELSE (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.2) 29 | SET(OUTPUT_FOLDER "OFX_nuke9/") 30 | ENDIF (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.2) 31 | ENDIF () 32 | 33 | SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES 34 | ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${OPENEXRID_ROOT}/build/debug/lib/${OUTPUT_FOLDER} 35 | LIBRARY_OUTPUT_DIRECTORY_DEBUG ${OPENEXRID_ROOT}/build/debug/lib/${OUTPUT_FOLDER} 36 | RUNTIME_OUTPUT_DIRECTORY_DEBUG ${OPENEXRID_ROOT}/build/debug/lib/${OUTPUT_FOLDER} 37 | ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${OPENEXRID_ROOT}/build/relwithdebinfo/lib/${OUTPUT_FOLDER} 38 | LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${OPENEXRID_ROOT}/build/relwithdebinfo/lib/${OUTPUT_FOLDER} 39 | RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${OPENEXRID_ROOT}/build/relwithdebinfo/lib/${OUTPUT_FOLDER} 40 | ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${OPENEXRID_ROOT}/build/release/lib/${OUTPUT_FOLDER} 41 | LIBRARY_OUTPUT_DIRECTORY_RELEASE ${OPENEXRID_ROOT}/build/release/lib/${OUTPUT_FOLDER} 42 | RUNTIME_OUTPUT_DIRECTORY_RELEASE ${OPENEXRID_ROOT}/build/release/lib/${OUTPUT_FOLDER} 43 | ) 44 | -------------------------------------------------------------------------------- /openfx/dir.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #ifdef WIN32 17 | 18 | // *** A dirent.h API like for directory listing on Windows 19 | 20 | #include "dir.h" 21 | #include 22 | 23 | DIR *opendir (const char *filename) 24 | { 25 | DIR *dir = new DIR; 26 | std::string path = filename; 27 | path += "/*"; 28 | dir->Handle = FindFirstFile(path.c_str (), &(dir->Data)); 29 | dir->First = true; 30 | if (dir->Handle == INVALID_HANDLE_VALUE) 31 | { 32 | delete dir; 33 | dir = NULL; 34 | } 35 | return dir; 36 | } 37 | 38 | // *************************************************************************** 39 | 40 | dirent *readdir (DIR *dir) 41 | { 42 | if (dir->First || FindNextFile (dir->Handle, &(dir->Data))) 43 | { 44 | dir->First = false; 45 | strncpy (dir->Dirent.d_name, dir->Data.cFileName, sizeof (dir->Dirent.d_name)-1); 46 | return &(dir->Dirent); 47 | } 48 | return NULL; 49 | } 50 | 51 | // *************************************************************************** 52 | 53 | void closedir (DIR *dir) 54 | { 55 | FindClose (dir->Handle); 56 | delete dir; 57 | } 58 | 59 | #endif // WIN32 60 | -------------------------------------------------------------------------------- /openfx/dir.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #pragma once 17 | 18 | // *** A dirent.h API like for directory listing on Windows 19 | 20 | #ifdef WIN32 21 | #include 22 | #undef min 23 | #undef max 24 | 25 | struct dirent 26 | { 27 | char d_name[MAX_PATH + 1]; 28 | }; 29 | 30 | // *************************************************************************** 31 | 32 | struct DIR 33 | { 34 | bool First; 35 | HANDLE Handle; 36 | WIN32_FIND_DATA Data; 37 | dirent Dirent; 38 | }; 39 | 40 | // *************************************************************************** 41 | 42 | DIR *opendir (const char *filename); 43 | dirent *readdir (DIR *dir); 44 | void closedir (DIR *dir); 45 | 46 | #else // WIN32 47 | 48 | #include 49 | #include 50 | 51 | #endif // WIN32 52 | -------------------------------------------------------------------------------- /openfx/file_range.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #include "instance.h" 17 | #include "dir.h" 18 | #include 19 | #include "ofxUtilities.h" 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | /* This file contains the range related functions */ 26 | 27 | bool matchFramePattern (const std::string &file, const std::string &pre, const std::string &post, size_t off, int n, int &frame) 28 | { 29 | if (file.size () != pre.size ()+n+post.size ()) return false; 30 | if (file.compare (0, pre.size (), pre) != 0) return false; 31 | if (file.compare (pre.size ()+n, file.npos, post) != 0) return false; 32 | 33 | frame = atoi (file.substr (pre.size (), n).c_str ()); 34 | return true; 35 | } 36 | 37 | // Get the frame range of a filename using a pattern 38 | bool getFrameRange (const std::string &file, int &start, int &end) 39 | { 40 | // If the file already contains special characters abort 41 | const size_t tagS = file.find ('#'); 42 | 43 | // No frame hashes 44 | if (tagS == file.npos) 45 | { 46 | start = end = 1; 47 | return true; 48 | } 49 | 50 | // Count the number of hash 51 | int n = 1; 52 | while (file[tagS+n] == '#') ++n; 53 | 54 | std::string pre = file.substr (0, file.find_first_of ("\\/", tagS+n)); 55 | const std::string post = pre.substr (tagS+n); 56 | const size_t pos = pre.find_last_of ("\\/")+1; // pos is 0 if not \\ nor / 57 | pre = pre.substr (pos, tagS-pos); 58 | 59 | // Get the parent folder where the hash tag name is stored 60 | const std::string parentDir = file.substr (0, pos); 61 | 62 | // Iterates the filenames where the hash tag name is stored 63 | start = INT_MAX; 64 | end = INT_MIN; 65 | DIR *dir = opendir (parentDir.c_str ()); 66 | if (!dir) 67 | return false; 68 | dirent *entry; 69 | while ((entry = readdir (dir))) 70 | { 71 | int frame; 72 | if (matchFramePattern (entry->d_name, pre, post, tagS-parentDir.size(), n, frame)) 73 | { 74 | start = std::min (frame, start); 75 | end = std::max (frame, start); 76 | } 77 | } 78 | closedir (dir); 79 | 80 | return start<=end; 81 | } 82 | 83 | // OFX callback for parameter changes 84 | OfxStatus onInstanceChanged(OfxImageEffectHandle effect, OfxPropertySetHandle inArgs) 85 | { 86 | Instance *instance = (Instance *) ofxuGetEffectInstanceData(effect); 87 | char *paramName, *changeReason; 88 | if (gPropHost->propGetString (inArgs, kOfxPropName, 0, ¶mName) == kOfxStatOK && 89 | gPropHost->propGetString (inArgs, kOfxPropChangeReason, 0, &changeReason) == kOfxStatOK && 90 | strcmp (changeReason, kOfxChangeUserEdited) == 0) 91 | { 92 | // The user changed some range related parameters 93 | // Synchronize the other parameters 94 | OfxPropertySetHandle effectProps; 95 | gEffectHost->getPropertySet(effect, &effectProps); 96 | if (strcmp (paramName, "file") == 0) 97 | { 98 | int start; 99 | int end; 100 | char *file; 101 | if (gParamHost->paramGetValue (instance->File, &file) == kOfxStatOK && 102 | getFrameRange (file, start, end)) 103 | { 104 | gParamHost->paramSetValue (instance->FirstFrame, start); 105 | gParamHost->paramSetValue (instance->LastFrame, end); 106 | } 107 | } 108 | } 109 | return kOfxStatOK; 110 | } 111 | 112 | // Positive modulus 113 | int modabs (int a, int b) 114 | { 115 | return (a = a%b) < 0 ? b+a : a; 116 | } 117 | 118 | int clampFrame (int mode, int frame, int len, bool &black) 119 | { 120 | switch (mode) 121 | { 122 | case 3: 123 | black = true; 124 | case 0: 125 | if (frame < 0) 126 | return 0; 127 | else 128 | return len-1; 129 | case 1: 130 | return modabs (frame, len); 131 | case 2: 132 | int tmp; 133 | return ((tmp = modabs (frame, len*2-2)) >= len ? len*2-2-tmp : tmp); 134 | } 135 | return frame; 136 | }; 137 | 138 | // Compute the final frame name using the file pattern and the boundary rules 139 | std::string computeFinalName (OfxPropertySetHandle inArgs, Instance *instance, bool &black) 140 | { 141 | black = false; 142 | OfxTime time; 143 | gPropHost->propGetDouble(inArgs, kOfxPropTime, 0, &time); 144 | 145 | const char *_filename; 146 | if (isHostNuke()) 147 | gParamHost->paramGetValueAtTime(instance->File, time, &_filename); 148 | else 149 | gParamHost->paramGetValue(instance->File, &_filename); 150 | const std::string filename = _filename; 151 | 152 | const size_t hashPos = filename.find ('#'); 153 | if (hashPos == filename.npos) 154 | return filename; 155 | 156 | // Count the number of hash 157 | int n = 1; 158 | while (filename[hashPos+n] == '#') ++n; 159 | 160 | // ** Clamp the final time 161 | int firstFrame; 162 | gParamHost->paramGetValue (instance->FirstFrame, &firstFrame); 163 | int lastFrame; 164 | gParamHost->paramGetValue (instance->LastFrame, &lastFrame); 165 | int frameMode; 166 | gParamHost->paramGetValue (instance->Frame, &frameMode); 167 | int offset; 168 | gParamHost->paramGetValue (instance->Offset, &offset); 169 | int before; 170 | gParamHost->paramGetValue (instance->Before, &before); 171 | int after; 172 | gParamHost->paramGetValue (instance->After, &after); 173 | 174 | const int relativeTime = frameMode==0?(int)time-offset:(int)time+offset-firstFrame; 175 | const int len = lastFrame-firstFrame+1; 176 | 177 | const int finalTime = 178 | ( 179 | relativeTime < 0 ? clampFrame (before, relativeTime, len, black) : 180 | relativeTime >= len ? clampFrame (after, relativeTime, len, black) : 181 | relativeTime 182 | )+firstFrame; 183 | 184 | // std::cout << "Frame " << finalTime << std::endl; 185 | 186 | std::stringstream ss; 187 | ss << std::setw(n) << std::setfill('0') << finalTime; 188 | return filename.substr (0, hashPos) + ss.str () + filename.substr (hashPos+n); 189 | } 190 | 191 | bool isFileAnimated (OfxPropertySetHandle inArgs, Instance *instance) 192 | { 193 | const char *_filename; 194 | gParamHost->paramGetValue(instance->File, &_filename); 195 | const std::string filename = _filename; 196 | 197 | const size_t hashPos = filename.find ('#'); 198 | return hashPos != filename.npos; 199 | } 200 | -------------------------------------------------------------------------------- /openfx/instance.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * 4 | *** 5 | ***** 6 | ********************* Mercenaries Engineering SARL 7 | ***************** Copyright (C) 2016 8 | ************* 9 | ********* http://www.mercenaries-engineering.com 10 | *********** 11 | **** **** 12 | ** ** 13 | 14 | */ 15 | 16 | #pragma once 17 | #include 18 | #include 19 | 20 | // private instance data type 21 | class Instance 22 | { 23 | public: 24 | openexrid::Mask Mask; 25 | 26 | // Name of the last mask file loaded 27 | std::string LastMaskFilename; 28 | 29 | // handles to the clips we deal with 30 | OfxImageClipHandle OutputClip; 31 | 32 | // handles to a our parameters 33 | OfxParamHandle Version; 34 | OfxParamHandle File; 35 | OfxParamHandle FirstFrame; 36 | OfxParamHandle LastFrame; 37 | OfxParamHandle Before; 38 | OfxParamHandle After; 39 | OfxParamHandle Frame; 40 | OfxParamHandle Offset; 41 | OfxParamHandle MissingFrames; 42 | OfxParamHandle Pattern; 43 | OfxParamHandle Colors; 44 | OfxParamHandle Invert; 45 | OfxParamHandle Alpha; 46 | }; 47 | -------------------------------------------------------------------------------- /test/makefile: -------------------------------------------------------------------------------- 1 | sinclude ../makefile.myconfig 2 | sinclude ../makefile.config 3 | 4 | # Configuration 5 | PREFIX ?= /usr/local/openexrid 6 | EXR_INCLUDE ?= /usr/include/OpenEXR 7 | EXR_LIB ?= /usr/lib 8 | 9 | VERSION ?= release 10 | CPPFLAGS += -O3 -Wall -DNDEBUG -fPIC -I $(EXR_INCLUDE) 11 | 12 | 13 | PWD = $(shell pwd) 14 | SRCS = ${wildcard *.cpp} 15 | OBJS = $(SRCS:%.cpp=$(VERSION)/%.o) 16 | 17 | all: $(VERSION) $(VERSION)/test 18 | 19 | $(VERSION): 20 | mkdir -p $(VERSION) 21 | 22 | $(VERSION)/test: $(OBJS) 23 | g++ -o $@ $(OBJS) $(LDFLAGS) 24 | 25 | $(OBJS): $(VERSION)/%.o: %.cpp 26 | g++ -c $(CPPFLAGS) $< -o $@ 27 | 28 | clean: 29 | rm -f $(VERSION)/*.o $(VERSION)/*.a $(VERSION)/*.d $(VERSION)/test 30 | 31 | DEPS = $(SRCS:%.cpp=$(VERSION)/%.d) 32 | sinclude $(DEPS) 33 | -------------------------------------------------------------------------------- /test/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "../openexrid/Builder.h" 7 | #include "../openexrid/Mask.h" 8 | #include "../openexrid/Query.h" 9 | 10 | using namespace std; 11 | using namespace openexrid; 12 | 13 | // Number max of samples per pixel during the test 14 | const int SamplesMax = 4; 15 | 16 | // Number of different names 17 | const int NameN = 100; 18 | 19 | // Image resolution 20 | const int Width = 192; 21 | const int Height = 108; 22 | 23 | // Number of errors during the test 24 | int Errors = 0; 25 | 26 | // The temporary file 27 | const char *filename = "temp.exr"; 28 | 29 | std::string to_string (int d) 30 | { 31 | char buffer[256]; 32 | std::sprintf (buffer, "%d", d); 33 | return std::string (buffer); 34 | } 35 | 36 | class TestMatch 37 | { 38 | public: 39 | std::vector &names; 40 | int i; 41 | TestMatch (std::vector &_names, int _i) : names (_names), i (_i) 42 | {} 43 | bool operator () (const char *name) const 44 | { 45 | return names[i] == name; 46 | } 47 | }; 48 | 49 | // The name id per pixels 50 | struct entry 51 | { 52 | int Id; 53 | float Z; 54 | float Values[4]; 55 | float Weight; 56 | bool operator<(const entry &o) const 57 | { 58 | return Z < o.Z; 59 | } 60 | }; 61 | 62 | int main(int argc, char **argv) 63 | { 64 | try 65 | { 66 | // Generate some names 67 | vector names; 68 | for (int i = 0; i < NameN; ++i) 69 | names.push_back (::to_string (rand())); 70 | 71 | vector > pixelToNames (Width*Height); 72 | 73 | // Generate a random image 74 | for (vector >::iterator itp = pixelToNames.begin (); itp != pixelToNames.end (); ++itp) 75 | { 76 | const size_t x = (itp - pixelToNames.begin ())%Width; 77 | const size_t y = (itp - pixelToNames.begin ())/Width; 78 | 79 | // Compute an empty rectangle around to test the dataWindow 80 | if (x == 0 || x == Width-1 || y == 0 || y == Height-1) 81 | continue; 82 | 83 | const int samplesN = rand ()%(SamplesMax+1); 84 | const float weight = 1.f/(float)samplesN; 85 | const int baseId = rand(); 86 | for (int s = 0; s < samplesN; ++s) 87 | { 88 | entry e; 89 | e.Id = (baseId+s*10)%NameN; 90 | e.Z = (float)((baseId+s*10)%NameN); 91 | e.Values[0] = (float)rand()/(float)RAND_MAX; 92 | e.Values[1] = (float)rand()/(float)RAND_MAX; 93 | e.Values[2] = (float)rand()/(float)RAND_MAX; 94 | e.Values[3] = (float)rand()/(float)RAND_MAX; 95 | e.Weight = weight; 96 | itp->push_back (e); 97 | } 98 | 99 | // Sort by Z 100 | sort (itp->begin(), itp->end ()); 101 | } 102 | 103 | cout << "Fill a mask id map" << endl; 104 | std::vector slices; 105 | slices.push_back ("R"); 106 | slices.push_back ("G"); 107 | slices.push_back ("B"); 108 | slices.push_back ("A"); 109 | Builder builder (Width, Height, slices); 110 | const int TestA = 3; 111 | 112 | // Fill the builder 113 | for (int y = 0; y < Height; ++y) 114 | for (int x = 0; x < Width; ++x) 115 | { 116 | const vector &pixel = pixelToNames[x+y*Width]; 117 | for (size_t s = 0; s < pixel.size (); ++s) 118 | // Let's use the id as Z value 119 | builder.addCoverage (x, y, pixel[s].Id, pixel[s].Z, pixel[s].Weight, pixel[s].Values); 120 | } 121 | 122 | std::vector pixelWeights (Width*Height, 0.f); 123 | { 124 | // Concat the names 125 | std::string _names; 126 | for (vector::const_iterator ite = names.begin(); ite != names.end(); ++ite) 127 | { 128 | _names += *ite; 129 | _names += '\0'; 130 | } 131 | 132 | // Build the final weight array 133 | for (int i =0; i < Width*Height; ++i) 134 | { 135 | const vector &pixel = pixelToNames[i]; 136 | for (size_t s = 0; s < pixel.size (); ++s) 137 | pixelWeights[i] += pixel[s].Weight; 138 | } 139 | 140 | cout << "Finish the mask" << endl; 141 | builder.finish (pixelWeights); 142 | 143 | cout << "Write the mask" << endl; 144 | builder.write (filename, _names.c_str (), (int)_names.size(), true); 145 | } 146 | 147 | // Accumulate the pixels values 148 | for (int y=0; y &pixel = pixelToNames[x+y*Width]; 152 | if (!pixel.empty()) 153 | { 154 | // First normalize the pixel using the weights 155 | const float weightSum = pixelWeights[x+y*Width]; 156 | for (int v = 0; v < 4; ++v) 157 | { 158 | for (size_t s = 0; s < pixel.size (); ++s) 159 | { 160 | if (weightSum != 0) 161 | pixel[s].Values[v] = pixel[s].Values[v]*pixel[s].Weight/weightSum; 162 | } 163 | } 164 | 165 | // The accumulates the fragments in a deep fashion way 166 | for (int v = 0; v < 4; ++v) 167 | { 168 | float acc = 0.f; 169 | for (size_t s = 0; s < pixel.size (); ++s) 170 | pixel[s].Values[v] = (acc += pixel[s].Values[v]); 171 | } 172 | for (size_t s = pixel.size ()-1; s > 0; --s) 173 | { 174 | for (int v = 0; v < 4; ++v) 175 | pixel[s].Values[v] = (pixel[s].Values[v]-pixel[s-1].Values[v])/(1.f-pixel[s-1].Values[TestA]); 176 | } 177 | } 178 | } 179 | 180 | // Read a mask 181 | cout << "Read the mask" << endl; 182 | Mask mask; 183 | mask.read (filename); 184 | 185 | const int R = mask.findSlice ("R"); 186 | const int G = mask.findSlice ("G"); 187 | const int B = mask.findSlice ("B"); 188 | const int A = mask.findSlice ("A"); 189 | 190 | // Check the mask 191 | cout << "Check the mask" << endl; 192 | // Build the mask of every name 193 | for (int i = 0; i < NameN; ++i) 194 | { 195 | // Create a query for this name 196 | Query query (&mask, TestMatch (names, i)); 197 | 198 | for (int y=0; y &pixel = pixelToNames[x+y*Width]; 203 | float weightSum[4] = {0, 0, 0, 0}; 204 | 205 | // Fill the accumulated buffer 206 | float prevAlpha = 0.f; 207 | for (size_t s = 0; s < pixel.size (); ++s) 208 | { 209 | if (pixel[s].Id == i) 210 | { 211 | for (int v = 0; v < 4; ++v) 212 | weightSum[v] += (half)((1.f - prevAlpha)*(half)pixel[s].Values[v]); 213 | } 214 | prevAlpha += (1.f - prevAlpha)*(half)pixel[s].Values[TestA]; 215 | } 216 | 217 | // The coverage from the file 218 | std::vector coverage; 219 | query.getSliceData (x, y, coverage); 220 | 221 | Errors += int(weightSum[0] != coverage[R]); 222 | Errors += int(weightSum[1] != coverage[G]); 223 | Errors += int(weightSum[2] != coverage[B]); 224 | Errors += int(weightSum[3] != coverage[A]); 225 | } 226 | } 227 | } 228 | catch (runtime_error &e) 229 | { 230 | cout << e.what () << endl; 231 | remove (filename); 232 | return -1; 233 | } 234 | 235 | remove (filename); 236 | cout << Errors << " error(s)" << endl; 237 | 238 | return Errors; 239 | } 240 | 241 | --------------------------------------------------------------------------------