diff --git a/conan/cesdk/conanfile.py b/conan/cesdk/conanfile.py index 932287ea..696816cf 100644 --- a/conan/cesdk/conanfile.py +++ b/conan/cesdk/conanfile.py @@ -1,17 +1,18 @@ from conans import ConanFile from conans import tools -# usage: conan create cesdk/1.9.3786@esri-rd-zurich/stable -s compiler=gcc -s compiler.version=4.8 +# usage: conan create -s compiler=gcc -s compiler.version=4.8 . cesdk/1.9.3786@esri-rd-zurich/stable + class CESDKConan(ConanFile): - name = "cesdk" - version = "1.9.3786" - settings = "os", "compiler", "arch" + name = "cesdk" + version = "1.9.3786" + settings = "os", "compiler", "arch" description = "Develop 3D applications using the procedural geometry engine of Esri CityEngine." - url = "https://github.com/Esri/esri-cityengine-sdk" - license = "CityEngine EULA" + url = "https://github.com/Esri/esri-cityengine-sdk" + license = "CityEngine EULA" - baseURL = "https://github.com/esri/esri-cityengine-sdk/releases/download/{}/esri_ce_sdk-{}-{}-{}-x86_64-rel-opt.zip" + baseURL = "https://github.com/esri/esri-cityengine-sdk/releases/download/{}/esri_ce_sdk-{}-{}-{}-x86_64-rel-opt.zip" def build(self): if self.settings.os == "Windows": @@ -24,6 +25,15 @@ def build(self): raise Exception("Binary does not exist for this configuration") tools.get(url) + # hack: both cesdk and houdini provide libAlembic.so which are not compatible + # the alembic library from houdini is loaded first and this prevents libcom.esri.prt.codecs.so to load + # we are using a using patchelf to rename libAlembic.so of cesdk + # note: this requires patchelf 0.9 or later (https://github.com/NixOS/patchelf) + if self.settings.os == "Linux": + self.run('cd esri_ce_sdk/lib && mv libAlembic.so libAlembicCESDK.so') + self.run('patchelf --replace-needed libAlembic.so libAlembicCESDK.so esri_ce_sdk/lib/libcom.esri.prt.codecs.so') + tools.replace_in_file('esri_ce_sdk/cmake/prtConfig.cmake', 'Alembic', 'AlembicCESDK') + def package(self): self.copy("*", ".", "esri_ce_sdk") diff --git a/conan/houdini/conanfile.py b/conan/houdini/conanfile.py index bda754c2..9598d7ed 100644 --- a/conan/houdini/conanfile.py +++ b/conan/houdini/conanfile.py @@ -1,29 +1,37 @@ from conans import ConanFile -from conans import tools import os # this recipe creates a houdini conan package from a locally installed houdini -# usage: conan create houdini/X.Y.Z@sidefx/stable -s compiler=gcc -s compiler.version=4.8 +# usage: conan create -s compiler=gcc -s compiler.version=4.8 . houdini/X.Y.Z@sidefx/stable # if houdini is not installed at the default location, try -e HOUDINI_INSTALL= + class HoudiniConan(ConanFile): - name = "houdini" - settings = "os", "compiler", "arch" + name = "houdini" + settings = "os", "compiler", "arch" description = "Houdini is a 3D animation application software developed by Side Effects Software based in Toronto." - url = "https://www.sidefx.com" - license = "SIDE EFFECTS SOFTWARE LICENSE AGREEMENT, https://www.sidefx.com/legal/license-agreement" + url = "https://www.sidefx.com" + license = "SIDE EFFECTS SOFTWARE LICENSE AGREEMENT, https://www.sidefx.com/legal/license-agreement" + short_paths = True + + houdiniDefaultInstallationPath = r'C:\Program Files\Side Effects Software\Houdini {}' def build(self): pass def package(self): if self.settings.os == "Windows": - # TODO - pass + local_install = os.getenv('HOUDINI_INSTALL')\ + if 'HOUDINI_INSTALL' in os.environ\ + else self.houdiniDefaultInstallationPath.format(self.version) + self.copy("*", ".", local_install) elif self.settings.os == "Linux": - local_install = os.getenv('HOUDINI_INSTALL') if 'HOUDINI_INSTALL' in os.environ else "/opt/hfs{}".format(self.version) + local_install = os.getenv('HOUDINI_INSTALL')\ + if 'HOUDINI_INSTALL' in os.environ\ + else "/opt/hfs{}".format(self.version) + # the python exclude is a workaround: houdini installs some + # files in the python subdir as only readable by root self.copy("*", ".", local_install, symlinks=True, excludes="python/*") - # the python exclude is a hacky workaround: houdini installs some files in the python subdir as only readable by root elif self.settings.os == "Macos": # TODO pass @@ -32,7 +40,5 @@ def package(self): def package_info(self): self.cpp_info.libdirs = ['dsolib'] - self.cpp_info.libs = [ 'HoudiniUI', 'HoudiniOPZ', 'HoudiniOP3', 'HoudiniOP2', 'HoudiniOP1', 'HoudiniGEO', 'HoudiniPRM', 'HoudiniUT'] - # TODO: provide cpp flags required by houdini - # TODO: raise conan github issue to get version info by default - self.user_info.version = self.version + self.cpp_info.libs = ['HoudiniUI', 'HoudiniOPZ', 'HoudiniOP3', 'HoudiniOP2', + 'HoudiniOP1', 'HoudiniGEO', 'HoudiniPRM', 'HoudiniUT'] diff --git a/doc/build.md b/doc/build.md index 321e94f2..f5ffd028 100644 --- a/doc/build.md +++ b/doc/build.md @@ -2,34 +2,80 @@ ## Build Requirements - RHEL/CentOS 6/7 (or compatible) with GCC 4.8 -- Installation of [Houdini 16.0](https://sidefx.com/download) +- or Windows 7/8.1/10 with Visual Studio 2015 (MSVC 14.0) +- Installation of [Houdini 16.5](https://sidefx.com/download) - [cmake 3.8 or later](https://cmake.org/download) -- [conan 1.0.1 or later](https://www.conan.io/downloads) +- [conan 1.1 or later](https://www.conan.io/downloads) -The bootstrap step below will take care of these additional dependencies: -- SideFX Houdini HDK 16 +The bootstrap steps below will take care of these additional dependencies: +- SideFX Houdini HDK 16.5 - [Esri CityEngine SDK 1.9](https://github.com/Esri/esri-cityengine-sdk) +- Boost ## Build Instructions ### Bootstrap + The below steps will populate your local Conan repository with dependencies for the Palladio build system. You only need to work through this section once (or if you want to upgrade one of the dependencies). + +#### Linux 1. Checkout Palladio:```git clone git@github.com:esri/palladio.git && cd palladio``` -1. Download (from github) and package CityEngine SDK: ```cd conan/cesdk && conan create . cesdk/1.9.3786@esri-rd-zurich/stable -s compiler=gcc -s compiler.version=4.8``` -1. Extract and package the HDK from your local Houdini installation (adjust X.Y.Z): ```cd conan/houdini && conan create . houdini/X.Y.Z@sidefx/stable -s compiler=gcc -s compiler.version=4.8``` (Note: use the option ``-e HOUDINI_INSTALL=/path/to/your/hfsX.Y.Z``, if Houdini is not installed at the standard location, e.g. at ``/opt/hfsX.Y.Z`` for Linux). +1. Download CityEngine SDK: ```conan create -s compiler=gcc -s compiler.version=4.8 conan/cesdk cesdk/1.9.3786@esri-rd-zurich/stable ``` +1. Extract and package the HDK from your local Houdini installation (adjust Z to your Houdini version): ```conan create -s compiler=gcc -s compiler.version=4.8 conan/houdini houdini/16.5.Z@sidefx/stable``` (Note: use the option ``-e HOUDINI_INSTALL=/path/to/your/hfs16.5.Z``, if Houdini is not installed at the standard location, e.g. at ``/opt/hfs16.5.Z`` for Linux). + +#### Windows +1. Checkout Palladio git repository +1. Open a MSVC 14.0 x64 shell (Visual Studio 2015) and `cd` to the Palladio git repository +1. Download CityEngine SDK: ```conan create conan/cesdk cesdk/1.9.3786@esri-rd-zurich/stable ``` +1. Extract and package the HDK from your local Houdini installation (adjust Z to your Houdini version): ```conan create conan/houdini houdini/16.5.Z@sidefx/stable``` (Note: use the option ``-e HOUDINI_INSTALL=C:/path/to/your/houdini/installation``, if Houdini is not installed at the standard location for Windows). ### Building Palladio + +#### Linux +1. `cd` into your Palladio git repository 1. ```mkdir -p build/release && cd build/release``` 1. ```cmake -DCMAKE_BUILD_TYPE=Release ../../src``` -1. ```make install``` (the plugin is installed into your ~/houdiniX.Y/dso directory) +1. ```make install``` (the plugin will be installed into your ~/houdini16.5/dso directory) Note: the `Debug` build type should also work out of the box. If you want to use the `RelWithDebInfo` build type you need to edit your `~/.conan/settings.yml` file and append `RelWithDebInfo` to the `build_type` array at the bottom. +#### Windows +1. Open a MSVC 14.0 x64 shell (Visual Studio 2015) and `cd` to the Palladio git repository +1. ```mkdir build/release``` +1. ```cd build/release``` +1. ```cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release ../../src``` +1. ```nmake install``` (the plugin will be installed into your ~/houdini16.5/dso directory) + +Note: if you run Visual Studio 2017 you can enable the MSVC 14.0 (VS2015) toolchain as follows: +1. Use the Visual Studio Installer to install `VC++ 2015.3 v140 toolset for Desktop` (see `Individual Components`) +1. Open a cmd shell and run `%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvarsall.bat" x64 8.1 -vcvars_ver=14.0` +1. `cl.exe` should now have version `19.00.xxx` + ### Running Palladio See [Quick Start](usage.md) how to launch Houdini with Palladio. +### Building and Running Unit Tests + +#### Linux +1. `cd` into your Palladio git repository +1. ```mkdir -p build/relTest && cd build/relTest``` +1. ```cmake -DCMAKE_BUILD_TYPE=Release -DPLD_TEST=1 ../../src``` +1. ```make palladio_test``` +1. run `bin/palladio_test` + +#### Windows +1. Open a MSVC 14.0 x64 shell (Visual Studio 2015) and `cd` to the Palladio git repository +1. ```mkdir build/relTest``` +1. ```cd build/relTest``` +1. ```cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DPLD_TEST=1 ../../src``` +1. ```nmake palladio_test``` +1. ensure that the `bin` subdirectory of your Houdini installation is in the `PATH` +1. run `bin\palladio_test` + + ## Environment Variables -- CITYENGINE_LOG_LEVEL: controls global (minimal) log level for all assign and generate nodes. valid values are "debug", "info", "warning", "error", "fatal" -- CITYENGINE_LICENSE_SERVER: specify how CityEngine license is acquired. an empty string specifies a node-locked license while "@" indicates a network license server, e.g. "27000@my.server.org". -- HOUDINI_DSO_ERROR: useful to debug loading issues, see http://www.sidefx.com/docs/houdini/ref/env \ No newline at end of file +- `CITYENGINE_LOG_LEVEL`: controls global (minimal) log level for all assign and generate nodes. Valid values are "debug", "info", "warning", "error", "fatal" +- `CITYENGINE_LICENSE_SERVER`: specifies how the CityEngine license is acquired. An empty string specifies a node-locked license while `@` indicates a network license server, e.g. `27000@my.server.org`. +- `HOUDINI_DSO_ERROR`: useful to debug loading issues, see http://www.sidefx.com/docs/houdini/ref/env + diff --git a/doc/changelog.md b/doc/changelog.md index 62be3205..a0ff008a 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,10 @@ # Palladio ChangeLog +## v1.1 (Apr 7, 2018) +* Added support for Windows (#85). +* Raised minimal Houdini version to 16.5.x (#85). +* Added support to reload RPKs (#58). + ## v1.0 (Jan 26, 2018) * Renamed project to "Palladio" (#68). * Updated documentation (#38). diff --git a/doc/usage.md b/doc/usage.md index 7b46f20a..9d39eef6 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -2,14 +2,18 @@ ## Prerequisites * RHEL/CentOS 6/7 (or a compatible distribution) -* Houdini 16.0.x (Apprentice edition is fine) +* or Windows 7/8.1/10 +* Houdini 16.5.x (including Apprentice edition) * CityEngine 2017.x with valid Advanced license (node-locked or network) ## Execute a simple CityEngine Rule -1. Verify that Palladio is installed and all necessary files are present in ``$HOME/houdiniXX/dso``: +1. [Build](build.md) Palladio +1. Verify that Palladio is installed and all necessary files are present in ``/houdini16.5/dso``: ![](img/installation01.png) + +1. Windows only: ensure that the ``/houdini16.5/dso`` and the `bin` subdirectory of your Houdini installation are on the `PATH` 1. In CityEngine, create the following rule file and share it as a rule package (RPK) to disk somewhere: ``` attr height = 1 @@ -24,9 +28,9 @@ ``` 1. Start Houdini in a bash console (adapt to your Houdini installation location): ``` - LD_LIBRARY_PATH=pt/hfs16.0/dsolib /opt/hfs16.0/bin/houdini + /opt/hfs16.5/bin/houdini ``` - (Use ``happrentice`` or ``hindie`` instead of ``houdini``, depending on our license. You might want to create a ``start-houdini`` script or alias with this line.) + (Use ``happrentice`` or ``hindie`` instead of ``houdini``, depending on our license.) 1. In a new scene, add a ``grid`` node. 1. Enter the ``grid`` node and add the two Palladio nodes ``pldAssign`` and ``pldGenerate``. Connect them like this: ![](img/extrude01.png) 1. In the ``pldAssign`` node, set the ``Rule Package`` parameter to the path of the previously exported RPK. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5695f7e6..4ee71713 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,51 +3,29 @@ cmake_minimum_required(VERSION 3.8) project(palladio_root CXX) -### versioning - -set(PLD_VERSION_MAJOR 1) -set(PLD_VERSION_MINOR 0) -set(PLD_VERSION_PATCH 0) -if(NOT PLD_VERSION_BUILD) - set(PLD_VERSION_BUILD DEV) -endif() - -# versioning follows semver.org, Semantic Versioning 2.0.0 -# i.e. ..+b -# TODO: include houdini/prt version into semver metadata? eg. append ".h16.0.705.ce1.9.1234" -set(PLD_VERSION "${PLD_VERSION_MAJOR}.${PLD_VERSION_MINOR}.${PLD_VERSION_PATCH}+b${PLD_VERSION_BUILD}") - - ### platform configuration message(STATUS "CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}") if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") set(PLD_WINDOWS 1) - set(PLD_OS "win32") - add_definitions(-DPLD_WINDOWS) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(PLD_LINUX 1) - set(PLD_OS "rhel6") - add_definitions(-DPLD_LINUX) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") set(PLD_MACOS 1) - set(PLD_OS "macos") endif() -set(PLD_ARCH "x86_64") ### toolchain configuration -if(PLD_WINDOWS) - set(PLD_TC "vc110") - add_definitions(-DPLD_TC_VC) # TODO -elseif(PLD_LINUX) - set(PLD_TC "gcc48") - add_definitions(-DPLD_TC_GCC) # TODO -elseif(PLD_MACOS) - set(PLD_TC "ac73") - add_definitions(-DPLD_TC_CLANG) # TODO -endif() +function(add_toolchain_definition TGT) + if(PLD_WINDOWS) + target_compile_definitions(${TGT} PRIVATE -DPLD_WINDOWS=1 -DPLD_TC_VC=1) + elseif(PLD_LINUX) + target_compile_definitions(${TGT} PRIVATE -DPLD_LINUX=1 -DPLD_TC_GCC=1) + elseif(PLD_MACOS) + target_compile_definitions(${TGT} PRIVATE -DPLD_MACOS=1 -DPLD_TC_CLANG=1) + endif() +endfunction() ### dependencies @@ -55,38 +33,51 @@ endif() include(${CMAKE_CURRENT_LIST_DIR}/dependencies.cmake) +### versioning + +set(PLD_VERSION_MAJOR 1) +set(PLD_VERSION_MINOR 1) +set(PLD_VERSION_PATCH 0) +if(NOT PLD_VERSION_BUILD) + set(PLD_VERSION_BUILD DEV) +endif() + +# we use semver.org, Semantic Versioning 2.0.0 +# i.e. ..+b.hdn.prt +set(PLD_VERSION "${PLD_VERSION_MAJOR}.${PLD_VERSION_MINOR}.${PLD_VERSION_PATCH}\ ++b${PLD_VERSION_BUILD}\ +.hdn${Houdini_VERSION_MAJOR}-${Houdini_VERSION_MINOR}-${Houdini_VERSION_PATCH}\ +.prt${PRT_VERSION_MAJOR}-${PRT_VERSION_MINOR}-${PRT_VERSION_MICRO}") +message(STATUS "Using PLD_VERSION = ${PLD_VERSION}") + + ### setup sub-projects add_subdirectory(codec) add_subdirectory(palladio) -add_subdirectory(test) - add_dependencies(palladio palladio_codec) +add_subdirectory(test EXCLUDE_FROM_ALL) + ### setup installation target if (NOT HOUDINI_DSO_PATH) if(PLD_WINDOWS) - set(HOUDINI_DSO_PATH "$ENV{HOMEDRIVE}$ENV{HOMEPATH}/Documents/houdini${HOUDINI_MAJOR_VERSION}.${HOUDINI_MINOR_VERSION}/dso") + set(HOUDINI_DSO_PATH "$ENV{HOMEDRIVE}$ENV{HOMEPATH}/Documents/houdini${Houdini_VERSION_MAJOR}.${Houdini_VERSION_MINOR}/dso") else() - set(HOUDINI_DSO_PATH "$ENV{HOME}/houdini${HOUDINI_MAJOR_VERSION}.${HOUDINI_MINOR_VERSION}/dso") + set(HOUDINI_DSO_PATH "$ENV{HOME}/houdini${Houdini_VERSION_MAJOR}.${Houdini_VERSION_MINOR}/dso") endif() endif() message(STATUS "HOUDINI_DSO_PATH = ${HOUDINI_DSO_PATH}") if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set (CMAKE_INSTALL_PREFIX "${HOUDINI_DSO_PATH}" CACHE PATH "default install path" FORCE ) - message(STATUS "set default install prefix: ${CMAKE_INSTALL_PREFIX}") + message(STATUS "Set default install prefix: ${CMAKE_INSTALL_PREFIX}") endif() -add_custom_target(install_palladio - make install - DEPENDS palladio - COMMENT "Installing palladio") - -### package targets +### setup package target set(CPACK_PACKAGE_NAME "palladio") set(CPACK_PACKAGE_VENDOR "Esri R&D Zurich / VRBN") @@ -95,7 +86,15 @@ set(CPACK_PACKAGE_VERSION_MAJOR ${PLD_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${PLD_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${PLD_VERSION_PATCH}) set(CPACK_PACKAGE_INSTALL_DIRECTORY "palladio-${PLD_VERSION}") -set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PLD_VERSION}-${PLD_OS}-h${HOUDINI_VERSION}") + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + set(PLD_PKG_OS "windows") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set(PLD_PKG_OS "linux") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + set(PLD_PKG_OS "macos") +endif() +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PLD_VERSION}-${PLD_PKG_OS}") if(PLD_WINDOWS) set(CPACK_GENERATOR ZIP) @@ -105,7 +104,14 @@ endif() include(CPack) -add_custom_target(package_palladio - make package - DEPENDS install_palladio - COMMENT "Packaging palladio") +# not strictly necessary, useful for IDEs like CLion without direct support to run "make package" +add_custom_target(palladio_package + ${CMAKE_MAKE_PROGRAM} package + DEPENDS palladio + COMMENT "Packaging Palladio") + + +### setup test target + +enable_testing () +add_test (NAME palladio_test COMMAND palladio_test) \ No newline at end of file diff --git a/src/codec/CMakeLists.txt b/src/codec/CMakeLists.txt index db0e2b78..85c42b2f 100644 --- a/src/codec/CMakeLists.txt +++ b/src/codec/CMakeLists.txt @@ -14,25 +14,32 @@ add_library(${PROJECT_NAME} SHARED encoder/HoudiniEncoder.cpp encoder/HoudiniCallbacks.h) +add_toolchain_definition(${PROJECT_NAME}) + if(PLD_LINUX) target_compile_options(${PROJECT_NAME} PRIVATE -std=c++11 -march=nocona - -fvisibility=hidden -fvisibility-inlines-hidden) # TODO: use cmake tools to set these + -fvisibility=hidden -fvisibility-inlines-hidden) + + if(${CMAKE_BUILD_TYPE} STREQUAL "Release") + target_compile_options(${PROJECT_NAME} PRIVATE -O3 -flto) + target_compile_definitions(${PROJECT_NAME} PRIVATE -DNDEBUG) + elseif(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") + target_compile_options(${PROJECT_NAME} PRIVATE -O3 -ggdb -pg) + target_compile_definitions(${PROJECT_NAME} PRIVATE -DNDEBUG) + elseif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + target_compile_options(${PROJECT_NAME} PRIVATE -O0 -ggdb -pg) + target_compile_definitions(${PROJECT_NAME} PRIVATE -DDEBUG) + endif() + elseif(PLD_MACOS) target_compile_options(${PROJECT_NAME} PRIVATE -std=c++14 - -fvisibility=hidden -fvisibility-inlines-hidden) # TODO: dito -endif() + -fvisibility=hidden -fvisibility-inlines-hidden) -if(${CMAKE_BUILD_TYPE} STREQUAL "Release") - target_compile_options(${PROJECT_NAME} PRIVATE -O3 -flto) - target_compile_definitions(${PROJECT_NAME} PRIVATE -DNDEBUG) -elseif(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") - target_compile_options(${PROJECT_NAME} PRIVATE -O3 -ggdb -pg) - target_compile_definitions(${PROJECT_NAME} PRIVATE -DNDEBUG) -elseif(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - target_compile_options(${PROJECT_NAME} PRIVATE -O0 -ggdb -pg) - target_compile_definitions(${PROJECT_NAME} PRIVATE -DDEBUG) +elseif(PLD_WINDOWS) + target_compile_options(${PROJECT_NAME} PRIVATE + /bigobj /GR /EHsc /MD) endif() diff --git a/src/codec/encoder/HoudiniEncoder.cpp b/src/codec/encoder/HoudiniEncoder.cpp index 3d24b023..1f02aea4 100644 --- a/src/codec/encoder/HoudiniEncoder.cpp +++ b/src/codec/encoder/HoudiniEncoder.cpp @@ -203,7 +203,7 @@ void HoudiniEncoder::encode(prtx::GenerateContext& context, size_t initialShapeI } case prtx::Attributable::PT_BOOL: { const auto v = shape->getBool(key); - cb->attrBool(initialShapeIndex, shape->getID(), key.c_str(), v); + cb->attrBool(initialShapeIndex, shape->getID(), key.c_str(), (v == prtx::PRTX_TRUE)); break; } default: @@ -245,17 +245,17 @@ void serializeGeometry(SerializedGeometry& sg, const prtx::GeometryPtrVector& ge const uint32_t numUVSets = mesh->getUVSetsCount(); std::vector uvSetIndexBases(sg.uvSets, 0u); // first value is always 0 - const uint32_t uvsBefore = sg.uvCoords.size(); - for (size_t uvSet = 0; uvSet < numUVSets; uvSet++) { + const uint32_t uvsBefore = (uint32_t)sg.uvCoords.size(); + for (uint32_t uvSet = 0; uvSet < numUVSets; uvSet++) { if (uvSet > 0) - uvSetIndexBases[uvSet] = uvSetIndexBases[uvSet-1] + mesh->getUVCoords(uvSet-1).size() / 2u; + uvSetIndexBases[uvSet] = uvSetIndexBases[uvSet-1] + (uint32_t)mesh->getUVCoords(uvSet-1).size() / 2u; const prtx::DoubleVector& uvs = mesh->getUVCoords(uvSet); if (!uvs.empty()) sg.uvCoords.insert(sg.uvCoords.end(), uvs.begin(), uvs.end()); } - const uint32_t uvsDelta = sg.uvCoords.size() - uvsBefore; + const uint32_t uvsDelta = (uint32_t)sg.uvCoords.size() - uvsBefore; sg.counts.reserve(sg.counts.size() + mesh->getFaceCount()); @@ -268,7 +268,7 @@ void serializeGeometry(SerializedGeometry& sg, const prtx::GeometryPtrVector& ge for (uint32_t vi = 0; vi < vtxCnt; vi++) sg.indices.push_back(vertexIndexBase + vtxIdx[vtxCnt-vi-1]); // reverse winding - for (size_t uvSet = 0; uvSet < sg.uvSets; uvSet++) { + for (uint32_t uvSet = 0; uvSet < sg.uvSets; uvSet++) { const uint32_t uvCount = (uvSet < numUVSets) ? mesh->getFaceUVCount(fi, uvSet) : 0u; if (uvCount == vtxCnt) { const uint32_t* uvIdx = mesh->getFaceUVIndices(fi, uvSet); @@ -279,7 +279,7 @@ void serializeGeometry(SerializedGeometry& sg, const prtx::GeometryPtrVector& ge } } - vertexIndexBase += verts.size() / 3u; + vertexIndexBase += (uint32_t)verts.size() / 3u; uvIndexBase += uvsDelta / 2u; // TODO: directly add to per uv set index bases } } diff --git a/src/conanfile.py b/src/conanfile.py new file mode 100644 index 00000000..b1de0503 --- /dev/null +++ b/src/conanfile.py @@ -0,0 +1,14 @@ +from conans import ConanFile + +class PalladioConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + requires = "cesdk/1.9.3786@esri-rd-zurich/stable",\ + "houdini/[>16.5.0,<17.0.0]@sidefx/stable",\ + "boost/1.66.0@conan/stable", \ + "catch2/2.0.1@bincrafters/stable" + generators = "cmake" + default_options = "boost:shared=False" + + def configure(self): + if self.settings.os == "Linux": + self.options["boost"].fPIC=True diff --git a/src/conanfile.txt b/src/conanfile.txt deleted file mode 100644 index 3ddf9480..00000000 --- a/src/conanfile.txt +++ /dev/null @@ -1,7 +0,0 @@ -[requires] -cesdk/1.9.3786@esri-rd-zurich/stable -houdini/[>16.0.0,<16.5.0]@sidefx/stable -catch2/2.0.1@bincrafters/stable - -[generators] -cmake \ No newline at end of file diff --git a/src/dependencies.cmake b/src/dependencies.cmake index c6928cf2..31f3c020 100644 --- a/src/dependencies.cmake +++ b/src/dependencies.cmake @@ -2,168 +2,46 @@ if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake") message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan") - file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.9/conan.cmake" + file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.10/conan.cmake" "${CMAKE_BINARY_DIR}/conan.cmake") endif() include(${CMAKE_BINARY_DIR}/conan.cmake) -conan_cmake_run(CONANFILE conanfile.txt BASIC_SETUP CMAKE_TARGETS BUILD missing) +conan_cmake_run(CONANFILE conanfile.py BASIC_SETUP CMAKE_TARGETS BUILD missing) ### PRT dependency -function(pld_add_dependency_prt TGT) - find_package(prt CONFIG) - - #set(CESDK_VERSION "cesdk_${PRT_VERSION_MAJOR}_${PRT_VERSION_MINOR}_${PRT_VERSION_MICRO}") - #message(STATUS "CESDK_VERSION = ${CESDK_VERSION}") - #message(STATUS "PRT_INSTALL_PATH = ${PRT_INSTALL_PATH}") +find_package(prt CONFIG REQUIRED) +function(pld_add_dependency_prt TGT) target_compile_definitions(${TGT} PRIVATE -DPRT_VERSION_MAJOR=${PRT_VERSION_MAJOR} -DPRT_VERSION_MINOR=${PRT_VERSION_MINOR}) target_include_directories(${TGT} PRIVATE ${PRT_INCLUDE_PATH}) - target_link_libraries(${TGT} PRIVATE ${PRT_LINK_LIBRARIES}) - - # promote the PRT library paths so we can use them for the install command - set( PRT_LIBRARIES ${PRT_LIBRARIES} PARENT_SCOPE ) - set( PRT_EXT_LIBRARIES ${PRT_EXT_LIBRARIES} PARENT_SCOPE ) + target_link_libraries(${TGT} PRIVATE ${PRT_LIBRARY}) endfunction() ### HOUDINI dependency -# get Houdini fundamentals from conan as global variables -set(HOUDINI_ROOT ${CONAN_HOUDINI_ROOT}) -set(HOUDINI_VERSION ${CONAN_USER_HOUDINI_version}) -message(STATUS "HOUDINI_VERSION = ${HOUDINI_VERSION}") - -string(REPLACE "." ";" VL ${HOUDINI_VERSION}) -list(GET VL 0 HOUDINI_MAJOR_VERSION) -list(GET VL 1 HOUDINI_MINOR_VERSION) -list(GET VL 2 HOUDINI_BUILD_VERSION) +list(APPEND CMAKE_PREFIX_PATH "${CONAN_HOUDINI_ROOT}/toolkit/cmake") +find_package(Houdini REQUIRED) function(pld_add_dependency_houdini TGT) - # setup paths - if(PLD_WINDOWS) - # TODO - elseif(PLD_LINUX) - set(HOUDINI_BINARY_DIR ${HOUDINI_ROOT}/bin) - set(HOUDINI_INCLUDE_DIR ${HOUDINI_ROOT}/toolkit/include) - set(HOUDINI_LIBRARY_DIR ${HOUDINI_ROOT}/dsolib) - elseif(PLD_MACOS) - set(HOUDINI_ROOT /Applications/Houdini/Houdini${HOUDINI_VERSION}) - set(HOUDINI_BINARY_DIR ${HOUDINI_FRAMEWORK}/Resources/bin) - set(HOUDINI_FRAMEWORK ${HOUDINI_ROOT}/Frameworks/Houdini.framework/Versions/${HOUDINI_VERSION}) - set(HOUDINI_INCLUDE_DIR ${HOUDINI_FRAMEWORK}/Resources/toolkit/include) - set(HOUDINI_LIBRARY_DIR ${HOUDINI_FRAMEWORK}/Libraries) - #set(HOUDINI_TOOLKIT_DIR ${HOUDINI_ROOT}/Frameworks/Houdini.framework/Versions/${HOUDINI_VERSION}/Resources/toolkit) - endif() - - message(STATUS "HOUDINI_ROOT = ${HOUDINI_ROOT}") - message(STATUS "HOUDINI_BINARY_DIR = ${HOUDINI_BINARY_DIR}") - message(STATUS "HOUDINI_FRAMEWORK = ${HOUDINI_FRAMEWORK}") - message(STATUS "HOUDINI_INCLUDE_DIR = ${HOUDINI_INCLUDE_DIR}") - message(STATUS "HOUDINI_LIBRARY_DIR = ${HOUDINI_LIBRARY_DIR}") - - # configure sesi tag define - string(TIMESTAMP DATE "%Y-%m-%d") - string(TIMESTAMP TIME "%H:%M") - site_name(HOSTNAME) - if(PLD_WINDOWS) - SET(UN $ENV{USERNAME}) - else() - SET(UN $ENV{USER}) - endif() - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/taginfo "Compiled on:\n${DATE}\n${TIME}\nby: ${UN}@${HOSTNAME}") - execute_process( - COMMAND ${HOUDINI_BINARY_DIR}/sesitag -c -f taginfo - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - OUTPUT_VARIABLE PLD_SESI_TAG - ) - message(STATUS "Houdini: generated sesi tag: ${PLD_SESI_TAG}") - - if(PLD_WINDOWS) - # TODO - - elseif(PLD_LINUX) - #target_compile_options(${TGT} PRIVATE - # -Wl,-rpath=\$ORIGIN:${HOUDINI_ROOT}/dsolib) - - # below has been extracted from "HFS=/opt/hfs16.0 bin/hcustom -c" - # TODO: ideally call hcustom at configuration time - # OR maybe sidefx will provide cmake scripts eventually... - target_compile_definitions(${TGT} PRIVATE - ${PLD_SESI_TAG} -DMAKING_DSO -DGCC3 -DGCC4 -DAMD64 - -DSIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P} -DVERSION=\"${HOUDINI_VERSION}\" -DDLLEXPORT="" - -D_GNU_SOURCE -DLINUX -DSESI_LITTLE_ENDIAN -DENABLE_THREADS -DUSE_PTHREADS -DENABLE_UI_THREADS - -DFBX_ENABLED=1 -DOPENCL_ENABLED=1 -DOPENVDB_ENABLED=1 -D_FILE_OFFSET_BITS=64) - - target_include_directories(${TGT} PRIVATE - ${HOUDINI_ROOT}/toolkit/include) - - # find main Houdini libraries - find_library(HOUDINI_UI_LIBRARY HoudiniUI PATHS ${HOUDINI_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH) - find_library(HOUDINI_OPZ_LIBRARY HoudiniOPZ PATHS ${HOUDINI_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH) - find_library(HOUDINI_OP3_LIBRARY HoudiniOP3 PATHS ${HOUDINI_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH) - find_library(HOUDINI_OP2_LIBRARY HoudiniOP2 PATHS ${HOUDINI_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH) - find_library(HOUDINI_OP1_LIBRARY HoudiniOP1 PATHS ${HOUDINI_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH) - find_library(HOUDINI_GEO_LIBRARY HoudiniGEO PATHS ${HOUDINI_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH) - find_library(HOUDINI_PRM_LIBRARY HoudiniPRM PATHS ${HOUDINI_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH) - find_library(HOUDINI_UT_LIBRARY HoudiniUT PATHS ${HOUDINI_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH) - - # using boost included in Houdini - find_library(BOOST_SYSTEM boost_system PATHS ${HOUDINI_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH) - find_library(BOOST_FILESYSTEM boost_filesystem PATHS ${HOUDINI_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH) - - target_link_libraries(${TGT} PRIVATE - ${HOUDINI_UI_LIBRARY} - ${HOUDINI_OPZ_LIBRARY} - ${HOUDINI_OP3_LIBRARY} - ${HOUDINI_OP2_LIBRARY} - ${HOUDINI_OP1_LIBRARY} - ${HOUDINI_GEO_LIBRARY} - ${HOUDINI_PRM_LIBRARY} - ${HOUDINI_UT_LIBRARY} - ${BOOST_FILESYSTEM} - ${BOOST_SYSTEM}) - - elseif(PLD_MACOS) - # TODO - target_compile_definitions(${TGT} PRIVATE - ${PLD_SESI_TAG} -DMBSD_INTEL -DGCC3 -DGCC4 -DMBSD -DMAKING_DSO - -DSIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P} -DVERSION=\"${HOUDINI_VERSION}\" -DDLLEXPORT="" - -DSESI_LITTLE_ENDIAN -DENABLE_THREADS -DUSE_PTHREADS -DENABLE_UI_THREADS - -DFBX_ENABLED=1 -DOPENCL_ENABLED=1 -DOPENVDB_ENABLED=1 -D_FILE_OFFSET_BITS=64) - - target_include_directories(${TGT} PRIVATE - ${HOUDINI_INCLUDE_DIR}) - - find_library(HOUDINI_UI_LIBRARY NAMES HoudiniUI PATHS ${HOUDINI_LIBRARY_DIR}) - find_library(HOUDINI_OPZ_LIBRARY HoudiniOPZ PATHS ${HOUDINI_LIBRARY_DIR}) - find_library(HOUDINI_OP3_LIBRARY HoudiniOP3 PATHS ${HOUDINI_LIBRARY_DIR}) - find_library(HOUDINI_OP2_LIBRARY HoudiniOP2 PATHS ${HOUDINI_LIBRARY_DIR}) - find_library(HOUDINI_OP1_LIBRARY HoudiniOP1 PATHS ${HOUDINI_LIBRARY_DIR}) - find_library(HOUDINI_GEO_LIBRARY HoudiniGEO PATHS ${HOUDINI_LIBRARY_DIR}) - find_library(HOUDINI_PRM_LIBRARY HoudiniPRM PATHS ${HOUDINI_LIBRARY_DIR}) - find_library(HOUDINI_UT_LIBRARY NAMES HoudiniUT PATHS ${HOUDINI_LIBRARY_DIR}) - - target_link_libraries(${TGT} PRIVATE - ${HOUDINI_UI_LIBRARY} - ${HOUDINI_OPZ_LIBRARY} - ${HOUDINI_OP3_LIBRARY} - ${HOUDINI_OP2_LIBRARY} - ${HOUDINI_OP1_LIBRARY} - ${HOUDINI_GEO_LIBRARY} - ${HOUDINI_PRM_LIBRARY} - ${HOUDINI_UT_LIBRARY} - ${BOOST_FILESYSTEM} - ${BOOST_SYSTEM}) - - add_custom_command(TARGET ${TGT} POST_BUILD - COMMAND ${CMAKE_INSTALL_NAME_TOOL} - -change @rpath/libcom.esri.prt.core.dylib @loader_path/libcom.esri.prt.core.dylib - $) - endif() + target_link_libraries(${TGT} PRIVATE Houdini) + # houdini_configure_target(${TGT}) + # note: the above disabled function (provided by sidefx) does weird things with the install prefix +endfunction() + + +### boost dependency +function(pld_add_dependency_boost TGT) + target_link_libraries(${TGT} PRIVATE CONAN_PKG::boost) endfunction() +### catch2 dependency + +function(pld_add_dependency_catch2 TGT) + target_link_libraries(${TGT} PRIVATE CONAN_PKG::catch2) +endfunction() diff --git a/src/palladio/AttributeConversion.cpp b/src/palladio/AttributeConversion.cpp index 0adc79f6..29772581 100644 --- a/src/palladio/AttributeConversion.cpp +++ b/src/palladio/AttributeConversion.cpp @@ -22,6 +22,7 @@ #include "boost/algorithm/string.hpp" #include +#include namespace { diff --git a/src/palladio/AttributeConversion.h b/src/palladio/AttributeConversion.h index 8dfe4c7e..1da38ccc 100644 --- a/src/palladio/AttributeConversion.h +++ b/src/palladio/AttributeConversion.h @@ -16,6 +16,7 @@ #pragma once +#include "PalladioMain.h" #include "Utils.h" #include "GU/GU_Detail.h" @@ -56,7 +57,7 @@ struct ProtoHandle { using HandleMap = std::unordered_map; -void extractAttributeNames(HandleMap& handleMap, const prt::AttributeMap* attrMap); +PLD_TEST_EXPORTS_API void extractAttributeNames(HandleMap& handleMap, const prt::AttributeMap* attrMap); void createAttributeHandles(GU_Detail* detail, HandleMap& handleMap); void setAttributeValues(HandleMap& handleMap, const prt::AttributeMap* attrMap, const GA_IndexMap& primIndexMap, const GA_Offset rangeStart, @@ -69,7 +70,7 @@ namespace NameConversion { std::wstring addStyle(const std::wstring& n, const std::wstring& style); std::wstring removeStyle(const std::wstring& n); -void separate(const std::wstring& fqName, std::wstring& style, std::wstring& name); +PLD_TEST_EXPORTS_API void separate(const std::wstring& fqName, std::wstring& style, std::wstring& name); UT_String toPrimAttr(const std::wstring& name); std::wstring toRuleAttr(const std::wstring& style, const UT_StringHolder& name); diff --git a/src/palladio/CMakeLists.txt b/src/palladio/CMakeLists.txt index ab13656c..4824003e 100644 --- a/src/palladio/CMakeLists.txt +++ b/src/palladio/CMakeLists.txt @@ -29,20 +29,21 @@ add_library(${PROJECT_NAME} SHARED LRUCache.h) target_include_directories(${PROJECT_NAME} PRIVATE - ${palladio_codec_SOURCE_DIR}) + ${palladio_codec_SOURCE_DIR} + $) ### compiler settings -if(PLD_WINDOWS) - # TODO: outdated, move houdini-specific stuff to pld_add_dependency_houdini - set(CMAKE_CXX_FLAGS "-EHsc -nologo -TP -Zc:forScope -wd4355 -w14996") - set(CMAKE_CXX_FLAGS_Release "-O2 -DNDEBUG -MD -GR -bigobj") - target_comipile_definitions(${PROJECT_NAME} PRIVATE ${PLD_SESI_TAG} -DMAKING_DSO -DI386 -DWIN32 -DSWAP_BITFIELDS -D_WIN32_WINNT=0x0502 -DNOMINMAX -DSTRICT -DWIN32_LEAN_AND_MEAN -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -DBOOST_ALL_NO_LIB -DSESI_LITTLE_ENDIAN -DAMD64 -DSIZEOF_VOID_P=8 -DFBX_ENABLED=1 -DOPENCL_ENABLED=1 -DOPENVDB_ENABLED=1) +add_toolchain_definition(${PROJECT_NAME}) + +if(PLD_TEST) + message(STATUS "Enabling test exports...") + target_compile_definitions(palladio PRIVATE -DPLD_TEST_EXPORTS) +endif() - file(GLOB_RECURSE HOUDINI_LIBS - "${HOUDINI_ROOT}/custom/houdini/dsolib/*.a" - "${HOUDINI_ROOT}/custom/houdini/dsolib/*.lib") +if(PLD_WINDOWS) + # nothing, inheriting compiler flags from houdini elseif(PLD_LINUX) target_compile_options(${PROJECT_NAME} PRIVATE @@ -81,8 +82,9 @@ endif() ### dependencies +pld_add_dependency_boost(${PROJECT_NAME}) pld_add_dependency_prt(${PROJECT_NAME}) -pld_add_dependency_houdini(${PROJECT_NAME}) # also provides boost +pld_add_dependency_houdini(${PROJECT_NAME}) ### setup install target @@ -90,3 +92,5 @@ pld_add_dependency_houdini(${PROJECT_NAME}) # also provides boost install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION . LIBRARY DESTINATION .) install(FILES ${PRT_LIBRARIES} DESTINATION .) install(FILES ${PRT_EXT_LIBRARIES} DESTINATION prtlib) +install(DIRECTORY ${PROJECT_SOURCE_DIR}/../../doc DESTINATION .) +install(FILES ${PROJECT_SOURCE_DIR}/../../README.md ${PROJECT_SOURCE_DIR}/../../LICENSE DESTINATION .) diff --git a/src/palladio/ModelConverter.cpp b/src/palladio/ModelConverter.cpp index d7239a5f..0c243bf0 100644 --- a/src/palladio/ModelConverter.cpp +++ b/src/palladio/ModelConverter.cpp @@ -131,7 +131,7 @@ void setUVs(GA_RWHandleV3& handle, const GA_Detail::OffsetMarker& marker, } } -GA_Offset createPrimitives(GU_Detail* mDetail, GenerateNodeParams::GroupCreation gc, const wchar_t* name, +GA_Offset createPrimitives(GU_Detail* mDetail, GroupCreation gc, const wchar_t* name, const double* vtx, size_t vtxSize, const double* nrm, size_t nrmSize, const double* uvs, size_t uvsSize, @@ -173,7 +173,7 @@ GA_Offset createPrimitives(GU_Detail* mDetail, GenerateNodeParams::GroupCreation } // -- optionally create primitive groups - if (gc == GenerateNodeParams::GroupCreation::PRIMCLS) { + if (gc == GroupCreation::PRIMCLS) { const std::string nName = toOSNarrowFromUTF16(name); auto& elemGroupTable = mDetail->getElementGroupTable(GA_ATTRIB_PRIMITIVE); GA_PrimitiveGroup* primGroup = static_cast(elemGroupTable.newGroup(nName.c_str(), false)); @@ -186,7 +186,7 @@ GA_Offset createPrimitives(GU_Detail* mDetail, GenerateNodeParams::GroupCreation } // namespace ModelConversion -ModelConverter::ModelConverter(GU_Detail* detail, GenerateNodeParams::GroupCreation gc, std::vector& statuses, UT_AutoInterrupt* autoInterrupt) +ModelConverter::ModelConverter(GU_Detail* detail, GroupCreation gc, std::vector& statuses, UT_AutoInterrupt* autoInterrupt) : mDetail(detail), mGroupCreation(gc), mStatuses(statuses), mAutoInterrupt(autoInterrupt) { } void ModelConverter::add(const wchar_t* name, diff --git a/src/palladio/ModelConverter.h b/src/palladio/ModelConverter.h index d012e4af..26282c5b 100644 --- a/src/palladio/ModelConverter.h +++ b/src/palladio/ModelConverter.h @@ -16,7 +16,8 @@ #pragma once -#include "NodeParameter.h" +#include "PalladioMain.h" +#include "ShapeConverter.h" #include "Utils.h" #include "encoder/HoudiniCallbacks.h" @@ -44,7 +45,7 @@ namespace ModelConversion { -void getUVSet( +PLD_TEST_EXPORTS_API void getUVSet( std::vector& uvIndicesPerSet, const uint32_t* counts, size_t countsSize, const uint32_t* uvCounts, size_t uvCountsSize, @@ -65,7 +66,7 @@ void setUVs( class ModelConverter : public HoudiniCallbacks { public: - explicit ModelConverter(GU_Detail* gdp, GenerateNodeParams::GroupCreation gc, std::vector& statuses, UT_AutoInterrupt* autoInterrupt = nullptr); + explicit ModelConverter(GU_Detail* gdp, GroupCreation gc, std::vector& statuses, UT_AutoInterrupt* autoInterrupt = nullptr); protected: void add( @@ -103,7 +104,7 @@ class ModelConverter : public HoudiniCallbacks { private: GU_Detail* mDetail; - GenerateNodeParams::GroupCreation mGroupCreation; + GroupCreation mGroupCreation; std::vector& mStatuses; UT_AutoInterrupt* mAutoInterrupt; std::map mShapeAttributeBuilders; diff --git a/src/palladio/MultiWatch.cpp b/src/palladio/MultiWatch.cpp index 955ec254..1c8a059d 100644 --- a/src/palladio/MultiWatch.cpp +++ b/src/palladio/MultiWatch.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace { diff --git a/src/palladio/NodeParameter.h b/src/palladio/NodeParameter.h index f2385ca5..cb2cb3a9 100644 --- a/src/palladio/NodeParameter.h +++ b/src/palladio/NodeParameter.h @@ -38,13 +38,13 @@ static PRM_Name PRIM_CLS("primClsAttr", "Primitive Classifier"); const std::string PRIM_CLS_HELP = "Classifies primitives into input shapes and sets value for primitive attribute '" + PLD_PRIM_CLS_NAME.toStdString() + "'"; static PRM_Default PRIM_CLS_DEFAULT(0.0f, "primCls", CH_STRING_LITERAL); -auto getPrimClsName = [](const OP_Node* node, fpreal t) -> UT_String { +const auto getPrimClsName = [](const OP_Node* node, fpreal t) -> UT_String { UT_String s; node->evalString(s, PRIM_CLS.getToken(), 0, t); return s; }; -auto setPrimClsName = [](OP_Node* node, const UT_String& name, fpreal t) { +const auto setPrimClsName = [](OP_Node* node, const UT_String& name, fpreal t) { node->setString(name, CH_STRING_LITERAL, PRIM_CLS.getToken(), 0, t); }; @@ -57,7 +57,7 @@ static PRM_Default RPK_DEFAULT(0, ""); int updateRPK(void* data, int index, fpreal32 time, const PRM_Template*); static PRM_Callback rpkCallback(&updateRPK); -auto getRPK = [](const OP_Node* node, fpreal t) -> boost::filesystem::path { +const auto getRPK = [](const OP_Node* node, fpreal t) -> boost::filesystem::path { UT_String s; node->evalString(s, RPK.getToken(), 0, t); return s.toStdString(); @@ -76,13 +76,13 @@ void buildRuleFileMenu(void *data, PRM_Name *theMenu, int theMaxSize, const PRM_ static PRM_ChoiceList ruleFileMenu(static_cast(PRM_CHOICELIST_REPLACE), &buildRuleFileMenu); -auto getRuleFile = [](const OP_Node* node, fpreal t) -> std::wstring { +const auto getRuleFile = [](const OP_Node* node, fpreal t) -> std::wstring { UT_String s; node->evalString(s, RULE_FILE.getToken(), 0, t); return toUTF16FromOSNarrow(s.toStdString()); }; -auto setRuleFile = [](OP_Node* node, const std::wstring& ruleFile, fpreal t) { +const auto setRuleFile = [](OP_Node* node, const std::wstring& ruleFile, fpreal t) { const UT_String val(toOSNarrowFromUTF16(ruleFile)); node->setString(val, CH_STRING_LITERAL, RULE_FILE.getToken(), 0, t); }; @@ -96,13 +96,13 @@ void buildStyleMenu(void *data, PRM_Name *theMenu, int theMaxSize, const PRM_Spa static PRM_ChoiceList styleMenu(static_cast(PRM_CHOICELIST_REPLACE), &buildStyleMenu); -auto getStyle = [](const OP_Node* node, fpreal t) -> std::wstring { +const auto getStyle = [](const OP_Node* node, fpreal t) -> std::wstring { UT_String s; node->evalString(s, STYLE.getToken(), 0, t); return toUTF16FromOSNarrow(s.toStdString()); }; -auto setStyle = [](OP_Node* node, const std::wstring& s, fpreal t) { +const auto setStyle = [](OP_Node* node, const std::wstring& s, fpreal t) { const UT_String val(toOSNarrowFromUTF16(s)); node->setString(val, CH_STRING_LITERAL, STYLE.getToken(), 0, t); }; @@ -116,13 +116,13 @@ void buildStartRuleMenu(void *data, PRM_Name *theMenu, int theMaxSize, const PRM static PRM_ChoiceList startRuleMenu(static_cast(PRM_CHOICELIST_REPLACE), &buildStartRuleMenu); -auto getStartRule = [](const OP_Node* node, fpreal t) -> std::wstring { +const auto getStartRule = [](const OP_Node* node, fpreal t) -> std::wstring { UT_String s; node->evalString(s, START_RULE.getToken(), 0, t); return toUTF16FromOSNarrow(s.toStdString()); }; -auto setStartRule = [](OP_Node* node, const std::wstring& s, fpreal t) { +const auto setStartRule = [](OP_Node* node, const std::wstring& s, fpreal t) { const UT_String val(toOSNarrowFromUTF16(s)); node->setString(val, CH_STRING_LITERAL, START_RULE.getToken(), 0, t); }; @@ -159,13 +159,12 @@ static PRM_ChoiceList groupCreationMenu((PRM_ChoiceListType)(PRM_CHOICELIST_EXCL const size_t DEFAULT_GROUP_CREATION_ORDINAL = 0; static PRM_Default DEFAULT_GROUP_CREATION(0, GROUP_CREATION_TOKENS[DEFAULT_GROUP_CREATION_ORDINAL]); -enum class GroupCreation { NONE, PRIMCLS }; -auto getGroupCreation = [](const OP_Node* node, fpreal t) -> GroupCreation { +const auto getGroupCreation = [](const OP_Node* node, fpreal t) -> GroupCreation { const auto ord = node->evalInt(GROUP_CREATION.getToken(), 0, t); switch (ord) { - case 0: return GroupCreation::NONE; break; - case 1: return GroupCreation::PRIMCLS; break; - default: return GroupCreation::NONE; break; + case 0: return GroupCreation::NONE; + case 1: return GroupCreation::PRIMCLS; + default: return GroupCreation::NONE; } }; diff --git a/src/palladio/PRTContext.cpp b/src/palladio/PRTContext.cpp index 3d11495f..39e8bc57 100644 --- a/src/palladio/PRTContext.cpp +++ b/src/palladio/PRTContext.cpp @@ -114,8 +114,10 @@ void scheduleRecook(const boost::filesystem::path& rpk) { return false; }; - OP_Network* objMgr = OPgetDirector()->getManager("obj"); - objMgr->traverseChildren(visit, const_cast(reinterpret_cast(&rpk)), true); + if (OPgetDirector() != nullptr) { + OP_Network* objMgr = OPgetDirector()->getManager("obj"); + objMgr->traverseChildren(visit, const_cast(reinterpret_cast(&rpk)), true); + } } } // namespace diff --git a/src/palladio/PRTContext.h b/src/palladio/PRTContext.h index dd606f64..8d008eb6 100644 --- a/src/palladio/PRTContext.h +++ b/src/palladio/PRTContext.h @@ -16,6 +16,7 @@ #pragma once +#include "PalladioMain.h" #include "ResolveMapCache.h" #include "Utils.h" @@ -35,7 +36,7 @@ using LogHandlerPtr = std::unique_ptr; /** * manage PRT "lifetime" (actually, its license lifetime) */ -struct PRTContext final { +struct PLD_TEST_EXPORTS_API PRTContext final { explicit PRTContext(const std::vector& addExtDirs = {}); PRTContext(const PRTContext&) = delete; PRTContext(PRTContext&&) = delete; diff --git a/src/palladio/PalladioMain.cpp b/src/palladio/PalladioMain.cpp index 2dc86082..36b22413 100644 --- a/src/palladio/PalladioMain.cpp +++ b/src/palladio/PalladioMain.cpp @@ -24,8 +24,8 @@ #include "OP/OP_OperatorTable.h" #include "UT/UT_Exit.h" -#undef major // fixes warning regarding duplicate macros in and -#undef minor +//#undef major // fixes warning regarding duplicate macros in and +//#undef minor #include "UT/UT_DSOVersion.h" diff --git a/src/palladio/PalladioMain.h b/src/palladio/PalladioMain.h index 7b16a3a1..cd219b8a 100644 --- a/src/palladio/PalladioMain.h +++ b/src/palladio/PalladioMain.h @@ -1,4 +1,14 @@ #pragma once +#ifdef _WIN32 +# ifdef PLD_TEST_EXPORTS +# define PLD_TEST_EXPORTS_API __declspec(dllexport) +# else +# define PLD_TEST_EXPORTS_API +# endif +#else +# define PLD_TEST_EXPORTS_API __attribute__ ((visibility ("default"))) +#endif + constexpr const char* OP_PLD_ASSIGN = "pldAssign"; constexpr const char* OP_PLD_GENERATE = "pldGenerate"; diff --git a/src/palladio/ResolveMapCache.cpp b/src/palladio/ResolveMapCache.cpp index 75ca74ff..d267c13e 100644 --- a/src/palladio/ResolveMapCache.cpp +++ b/src/palladio/ResolveMapCache.cpp @@ -9,15 +9,9 @@ namespace { const ResolveMapUPtr RESOLVE_MAP_NONE; -const timespec NO_MODIFICATION_TIME{0, 0}; -timespec getFileModificationTime(const boost::filesystem::path& p) { - struct stat result; - if (stat(p.c_str(), &result) == 0) { - return result.st_mtim; - } - else - return NO_MODIFICATION_TIME; +std::chrono::system_clock::time_point getFileModificationTime(const boost::filesystem::path& p) { + return std::chrono::system_clock::from_time_t(boost::filesystem::last_write_time(p)); } } // namespace @@ -36,13 +30,13 @@ ResolveMapCache::LookupResult ResolveMapCache::get(const boost::filesystem::path return { RESOLVE_MAP_NONE, CacheStatus::MISS }; const auto timeStamp = getFileModificationTime(rpk); - LOG_DBG << "rpk: current timestamp: " << timeStamp.tv_sec << "s " << timeStamp.tv_nsec << "ns"; + LOG_DBG << "rpk: current timestamp: " << std::chrono::duration_cast(timeStamp.time_since_epoch()).count() << "ns"; CacheStatus cs = CacheStatus::HIT; auto it = mCache.find(rpk); if (it != mCache.end()) { - LOG_DBG << "rpk: cache timestamp: " << it->second.mTimeStamp.tv_sec << "s " << it->second.mTimeStamp.tv_nsec << "ns"; - if (it->second.mTimeStamp.tv_sec != timeStamp.tv_sec || it->second.mTimeStamp.tv_nsec != timeStamp.tv_nsec) { + LOG_DBG << "rpk: cache timestamp: " << std::chrono::duration_cast(it->second.mTimeStamp.time_since_epoch()).count() << "ns"; + if (it->second.mTimeStamp != timeStamp) { mCache.erase(it); const auto cnt = boost::filesystem::remove_all(mRPKUnpackPath / rpk.leaf()); LOG_INF << "RPK change detected, forcing reload and clearing cache for " << rpk << " (removed " << cnt << " files)"; diff --git a/src/palladio/ResolveMapCache.h b/src/palladio/ResolveMapCache.h index 33eec05d..5ecc42ab 100644 --- a/src/palladio/ResolveMapCache.h +++ b/src/palladio/ResolveMapCache.h @@ -4,11 +4,8 @@ #include "boost/filesystem.hpp" -#include -#include -#ifndef WIN32 -# include -#endif +#include +#include class ResolveMapCache { @@ -26,7 +23,7 @@ class ResolveMapCache { private: struct ResolveMapCacheEntry { ResolveMapUPtr mResolveMap; - timespec mTimeStamp; + std::chrono::system_clock::time_point mTimeStamp; }; using Cache = std::map; Cache mCache; diff --git a/src/palladio/ShapeConverter.h b/src/palladio/ShapeConverter.h index 34492e73..851c6b1f 100644 --- a/src/palladio/ShapeConverter.h +++ b/src/palladio/ShapeConverter.h @@ -19,6 +19,8 @@ #include "PRTContext.h" #include "Utils.h" +#include "UT/UT_String.h" + #include "boost/filesystem/path.hpp" #include @@ -38,6 +40,8 @@ const UT_String PLD_START_RULE = "pldStartRule"; const UT_String PLD_STYLE = "pldStyle"; const UT_String PLD_RANDOM_SEED = "pldRandomSeed"; +enum class GroupCreation { NONE, PRIMCLS }; + class ShapeConverter { public: virtual void get(const GU_Detail* detail, const PrimitiveClassifier& primCls, diff --git a/src/palladio/ShapeData.cpp b/src/palladio/ShapeData.cpp index d4477afe..9f22d9b5 100644 --- a/src/palladio/ShapeData.cpp +++ b/src/palladio/ShapeData.cpp @@ -65,7 +65,7 @@ void ShapeData::addBuilder(InitialShapeBuilderUPtr&& isb, int32_t randomSeed, mRandomSeeds.push_back(randomSeed); mPrimitiveMapping.emplace_back(primMappings); - if (mGroupCreation == GenerateNodeParams::GroupCreation::PRIMCLS) { + if (mGroupCreation == GroupCreation::PRIMCLS) { std::wstring name; NameFromPrimPart npp(name, mNamePrefix); boost::apply_visitor(npp, clsVal); @@ -81,7 +81,7 @@ void ShapeData::addShape(const prt::InitialShape* is, AttributeMapBuilderUPtr&& const std::wstring& ShapeData::getInitialShapeName(size_t isIdx) const { if (mInitialShapeNames.empty()) { - assert(mGroupCreation == GenerateNodeParams::GroupCreation::NONE); + assert(mGroupCreation == GroupCreation::NONE); return DEFAULT_SHAPE_NAME; } else diff --git a/src/palladio/ShapeData.h b/src/palladio/ShapeData.h index bded15ab..1c3a42ee 100644 --- a/src/palladio/ShapeData.h +++ b/src/palladio/ShapeData.h @@ -24,7 +24,7 @@ class ShapeData final { public: ShapeData() = default; - ShapeData(const GenerateNodeParams::GroupCreation& gc, const std::wstring& namePrefix) : mGroupCreation(gc), mNamePrefix(namePrefix) { } + ShapeData(const GroupCreation& gc, const std::wstring& namePrefix) : mGroupCreation(gc), mNamePrefix(namePrefix) { } ShapeData(const ShapeData&) = delete; ShapeData(ShapeData&&) = delete; ~ShapeData(); @@ -56,7 +56,7 @@ class ShapeData final { AttributeMapBuilderVector mRuleAttributeBuilders; AttributeMapVector mRuleAttributes; - GenerateNodeParams::GroupCreation mGroupCreation = GenerateNodeParams::GroupCreation::NONE; + GroupCreation mGroupCreation = GroupCreation::NONE; std::vector mInitialShapeNames; std::wstring mNamePrefix; diff --git a/src/palladio/ShapeGenerator.h b/src/palladio/ShapeGenerator.h index 9abed7cb..73e92f0c 100644 --- a/src/palladio/ShapeGenerator.h +++ b/src/palladio/ShapeGenerator.h @@ -20,7 +20,6 @@ #include "ShapeConverter.h" #include "Utils.h" - class GU_Detail; struct ShapeGenerator final : ShapeConverter { diff --git a/src/palladio/Utils.cpp b/src/palladio/Utils.cpp index d46d238a..b823e200 100644 --- a/src/palladio/Utils.cpp +++ b/src/palladio/Utils.cpp @@ -94,7 +94,7 @@ std::string objectToXML(prt::Object const* obj) { void getLibraryPath(boost::filesystem::path& path, const void* func) { #ifdef _WIN32 HMODULE dllHandle = 0; - if(!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)getPathToCurrentModule, &dllHandle)) { + if(!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)getLibraryPath, &dllHandle)) { DWORD c = GetLastError(); char msg[255]; FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, 0, c, 0, msg, 255, 0); diff --git a/src/palladio/Utils.h b/src/palladio/Utils.h index 9885e1b5..9c094cb8 100644 --- a/src/palladio/Utils.h +++ b/src/palladio/Utils.h @@ -16,6 +16,8 @@ #pragma once +#include "PalladioMain.h" + #include "prt/Object.h" #include "prt/AttributeMap.h" #include "prt/InitialShape.h" @@ -25,8 +27,9 @@ #include "GA/GA_Primitive.h" +#include #include - +#include namespace boost { namespace filesystem { class path; } } @@ -54,20 +57,20 @@ using RuleFileInfoUPtr = std::unique_ptr; using OcclusionSetUPtr = std::unique_ptr; -void getCGBs(const ResolveMapUPtr& rm, std::vector>& cgbs); -const prt::AttributeMap* createValidatedOptions(const wchar_t* encID, const prt::AttributeMap* unvalidatedOptions); -std::string objectToXML(prt::Object const* obj); +PLD_TEST_EXPORTS_API void getCGBs(const ResolveMapUPtr& rm, std::vector>& cgbs); +PLD_TEST_EXPORTS_API const prt::AttributeMap* createValidatedOptions(const wchar_t* encID, const prt::AttributeMap* unvalidatedOptions); +PLD_TEST_EXPORTS_API std::string objectToXML(prt::Object const* obj); void getLibraryPath(boost::filesystem::path& path, const void* func); std::string getSharedLibraryPrefix(); std::string getSharedLibrarySuffix(); -std::string toOSNarrowFromUTF16(const std::wstring& osWString); +PLD_TEST_EXPORTS_API std::string toOSNarrowFromUTF16(const std::wstring& osWString); std::wstring toUTF16FromOSNarrow(const std::string& osString); std::string toUTF8FromOSNarrow(const std::string& osString); -std::wstring toFileURI(const boost::filesystem::path& p); -std::wstring percentEncode(const std::string& utf8String); +PLD_TEST_EXPORTS_API std::wstring toFileURI(const boost::filesystem::path& p); +PLD_TEST_EXPORTS_API std::wstring percentEncode(const std::string& utf8String); inline void replace_all_not_of(std::wstring& s, const std::wstring& allowedChars) { std::wstring::size_type pos = 0; diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index ffef2693..52e0ed2a 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -5,20 +5,33 @@ project(palladio_test CXX) add_executable(${PROJECT_NAME} tests.cpp TestUtils.cpp TestCallbacks.h) -target_compile_options(${PROJECT_NAME} PRIVATE - -std=c++11) +add_toolchain_definition(${PROJECT_NAME}) + +target_compile_definitions(${PROJECT_NAME} PRIVATE + -DPLD_TEST_EXPORTS + -DHOUDINI_CODEC_PATH="$" + -DTEST_DATA_PATH="${CMAKE_CURRENT_SOURCE_DIR}/data") + +if(PLD_LINUX) + target_compile_options(${PROJECT_NAME} PRIVATE -std=c++11) +endif() target_include_directories(${PROJECT_NAME} PRIVATE ${palladio_codec_SOURCE_DIR}) target_link_libraries(${PROJECT_NAME} PRIVATE palladio - palladio_codec - CONAN_PKG::catch2) - -target_compile_definitions(${PROJECT_NAME} PRIVATE - -DHOUDINI_CODEC_PATH="$" - -DTEST_DATA_PATH="${CMAKE_CURRENT_SOURCE_DIR}/data") + palladio_codec) +pld_add_dependency_catch2(${PROJECT_NAME}) +pld_add_dependency_boost(${PROJECT_NAME}) pld_add_dependency_prt(${PROJECT_NAME}) pld_add_dependency_houdini(${PROJECT_NAME}) + +if(PLD_WINDOWS) + # copy libraries next to test excutable so they can be found + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy ${PRT_LIBRARIES} ${CMAKE_BINARY_DIR}/bin + COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory ${PRT_INSTALL_PATH}/lib ${CMAKE_BINARY_DIR}/bin/lib + COMMAND ${CMAKE_COMMAND} ARGS -E copy $ ${CMAKE_BINARY_DIR}/bin/lib) +endif() \ No newline at end of file diff --git a/src/test/tests.cpp b/src/test/tests.cpp index b179dba9..358bd9e9 100644 --- a/src/test/tests.cpp +++ b/src/test/tests.cpp @@ -58,7 +58,14 @@ int main( int argc, char* argv[] ) { TEST_CASE("create file URI from path", "[utils]" ) { - CHECK(toFileURI(boost::filesystem::path("/tmp/foo.txt")) == L"file:/tmp/foo.txt"); +#ifdef PLD_LINUX + const auto u = toFileURI(boost::filesystem::path("/tmp/foo.txt")); + CHECK(u.compare(L"file:/tmp/foo.txt") == 0); +#elif defined(PLD_WINDOWS) + const auto u = toFileURI(boost::filesystem::path("c:\\tmp\\foo.txt")); + INFO(toOSNarrowFromUTF16(u)); + CHECK(u.compare(L"file:/c:/tmp/foo.txt") == 0); +#endif } TEST_CASE("percent-encode a UTF-8 string", "[utils]") {