cmake_minimum_required(VERSION 3.20) project(UsdLayerManager VERSION 1.0.0 LANGUAGES C CXX) # Set C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # Add cmake modules path list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules") # Find dependencies find_package(OpenGL REQUIRED) find_package(OpenUSD REQUIRED) find_package(Imgui REQUIRED) find_package(Glad REQUIRED) # USD build that includes hdEmbree (built with PXR_ENABLE_EMBREE_PLUGIN=ON). # Can be a separate install from OpenUSD_ROOT_DIR; leave empty to search there instead. set(HDEMBREE_USD_ROOT "" CACHE PATH "USD build containing hdEmbree plugin (separate from OpenUSD_ROOT_DIR)") # Only needed if embree*.dll are not inside HDEMBREE_USD_ROOT/bin. set(EMBREE_LOCATION "" CACHE PATH "Embree SDK bin/ directory (leave empty if bundled in HDEMBREE_USD_ROOT/bin)") # ── hdEmbree detection ─────────────────────────────────────────────────────── if(HDEMBREE_USD_ROOT AND EXISTS "${HDEMBREE_USD_ROOT}") set(_hdembree_root "${HDEMBREE_USD_ROOT}") else() set(_hdembree_root "${OpenUSD_ROOT_DIR}") endif() # hdEmbree.dll lives at plugin/usd/hdEmbree.dll; the subdir holds only plugin metadata. set(HDEMBREE_PLUGIN_DIR "${_hdembree_root}/plugin/usd/hdEmbree") set(HDEMBREE_DLL "${_hdembree_root}/plugin/usd/hdEmbree.dll") if(EXISTS "${HDEMBREE_PLUGIN_DIR}") set(OPENUSD_HAS_EMBREE TRUE) if(EMBREE_LOCATION AND EXISTS "${EMBREE_LOCATION}") set(_embree_dll_dir "${EMBREE_LOCATION}") else() set(_embree_dll_dir "${_hdembree_root}/bin") endif() # Skip tbb*.dll — already supplied by the main USD install to avoid conflicts. file(GLOB EMBREE_DLLS "${_embree_dll_dir}/embree*.dll") else() set(OPENUSD_HAS_EMBREE FALSE) message(STATUS "hdEmbree: NOT found — set HDEMBREE_USD_ROOT to a USD build with PXR_ENABLE_EMBREE_PLUGIN=ON") endif() # ── hdArnold detection ─────────────────────────────────────────────────────── # HDARNOLD_ROOT: CMAKE_INSTALL_PREFIX used when building arnold-usd set(HDARNOLD_ROOT "" CACHE PATH "arnold-usd install directory (the one containing plugin/hdArnold.dll)") # ARNOLD_LOCATION: Arnold SDK root (MtoA dir) — needed to deploy ai.dll set(ARNOLD_LOCATION "" CACHE PATH "Arnold SDK root (e.g. C:/Autodesk/mtoa/5.5.0/2026) for ai.dll deployment") if(HDARNOLD_ROOT AND EXISTS "${HDARNOLD_ROOT}/plugin/hdArnold.dll") set(OPENUSD_HAS_ARNOLD TRUE) set(HDARNOLD_DLL "${HDARNOLD_ROOT}/plugin/hdArnold.dll") set(NDRARNOLD_DLL "${HDARNOLD_ROOT}/plugin/ndrArnold.dll") set(HDARNOLD_PLUGIN_DIR "${HDARNOLD_ROOT}/plugin/hdArnold") set(NDRARNOLD_PLUGIN_DIR "${HDARNOLD_ROOT}/plugin/ndrArnold") if(ARNOLD_LOCATION AND EXISTS "${ARNOLD_LOCATION}/bin/ai.dll") set(ARNOLD_AI_DLL "${ARNOLD_LOCATION}/bin/ai.dll") else() set(ARNOLD_AI_DLL "") endif() else() set(OPENUSD_HAS_ARNOLD FALSE) message(STATUS "hdArnold: NOT found — set HDARNOLD_ROOT to the arnold-usd install dir and ARNOLD_LOCATION to the MtoA root") endif() # Collect source files file(GLOB_RECURSE CORE_SOURCES "src/core/*.cpp") file(GLOB_RECURSE UI_SOURCES "src/ui/*.cpp") file(GLOB_RECURSE UTILS_SOURCES "src/utils/*.cpp") set(MAIN_SOURCE "src/main.cpp") # Create executable add_executable(UsdLayerManager ${MAIN_SOURCE} ${CORE_SOURCES} ${UI_SOURCES} ${UTILS_SOURCES} ) # Include directories target_include_directories(UsdLayerManager PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party/fontawesome ${CMAKE_SOURCE_DIR}/third_party/nanosvg ) # Link libraries target_link_libraries(UsdLayerManager PRIVATE OpenUSD::OpenUSD Imgui::Imgui Glad::Glad ) # Platform-specific settings if(WIN32) # Windows-specific settings target_compile_definitions(UsdLayerManager PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX _CRT_SECURE_NO_WARNINGS ) # Copy runtime DLLs to output directory for each configuration add_custom_command(TARGET UsdLayerManager POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "$" # OpenUSD lib/ — usd_*.dll, boost_*.dll, Alembic.dll, etc. COMMAND ${CMAKE_COMMAND} -E copy_directory "${OpenUSD_BIN_DIR}" "$" # OpenUSD bin/ — tbb.dll, MaterialX, OpenEXR, OpenImageIO, etc. COMMAND ${CMAKE_COMMAND} -E copy_directory "${OpenUSD_ROOT_DIR}/bin" "$" COMMAND ${CMAKE_COMMAND} -E copy_directory "${OpenUSD_ROOT_DIR}/lib/usd" "$/usd" COMMAND ${CMAKE_COMMAND} -E copy_directory "${OpenUSD_ROOT_DIR}/plugin/usd" "$/usd" COMMAND ${CMAKE_COMMAND} -E copy_if_different "$ENV{LOCALAPPDATA}/Programs/Python/Python312/python312.dll" "$" COMMAND ${CMAKE_COMMAND} -E copy_if_different "$ENV{LOCALAPPDATA}/Programs/Python/Python312/python3.dll" "$" COMMENT "Copying runtime DLLs and USD plugins..." ) if(OPENUSD_HAS_EMBREE) add_custom_command(TARGET UsdLayerManager POST_BUILD # plugInfo.json has LibraryPath "../hdEmbree.dll" relative to usd/hdEmbree/, # which resolves to usd/hdEmbree.dll — so the DLL must live in usd/, not exe root. COMMAND ${CMAKE_COMMAND} -E copy_if_different "${HDEMBREE_DLL}" "$/usd/hdEmbree.dll" COMMAND ${CMAKE_COMMAND} -E copy_directory "${HDEMBREE_PLUGIN_DIR}" "$/usd/hdEmbree" COMMENT "Copying hdEmbree plugin..." ) if(EMBREE_DLLS) add_custom_command(TARGET UsdLayerManager POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EMBREE_DLLS} "$" COMMENT "Copying Embree runtime DLLs..." ) endif() endif() if(OPENUSD_HAS_ARNOLD) add_custom_command(TARGET UsdLayerManager POST_BUILD # DLLs go in usd/ alongside their metadata dirs (LibraryPath "../hdArnold.dll") COMMAND ${CMAKE_COMMAND} -E copy_if_different "${HDARNOLD_DLL}" "$/usd/hdArnold.dll" COMMAND ${CMAKE_COMMAND} -E copy_if_different "${NDRARNOLD_DLL}" "$/usd/ndrArnold.dll" COMMAND ${CMAKE_COMMAND} -E copy_directory "${HDARNOLD_PLUGIN_DIR}" "$/usd/hdArnold" COMMAND ${CMAKE_COMMAND} -E copy_directory "${NDRARNOLD_PLUGIN_DIR}" "$/usd/ndrArnold" COMMENT "Copying hdArnold plugin..." ) if(ARNOLD_AI_DLL) add_custom_command(TARGET UsdLayerManager POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${ARNOLD_AI_DLL}" "$" COMMENT "Copying Arnold runtime ai.dll..." ) endif() endif() endif() # Compiler warnings if(MSVC) target_compile_options(UsdLayerManager PRIVATE /W4) else() target_compile_options(UsdLayerManager PRIVATE -Wall -Wextra -Wpedantic) endif() # Install rules install(TARGETS UsdLayerManager RUNTIME DESTINATION bin ) # Install all OpenUSD runtime DLLs (same set that POST_BUILD copies to build/Release). # Without these the exe cannot start from install/bin. install(DIRECTORY ${OpenUSD_BIN_DIR}/ DESTINATION bin FILES_MATCHING PATTERN "*.dll" ) # Install OpenUSD bin/ DLLs — tbb.dll, tbbmalloc.dll, MaterialX, OpenEXR, # OpenImageIO, zlib, etc. These are separate from lib/ and also required at runtime. install(DIRECTORY ${OpenUSD_ROOT_DIR}/bin/ DESTINATION bin FILES_MATCHING PATTERN "*.dll" ) install(DIRECTORY ${OpenUSD_ROOT_DIR}/lib/usd DESTINATION bin ) install(DIRECTORY ${OpenUSD_ROOT_DIR}/plugin/usd DESTINATION bin/usd ) install(FILES ${OpenUSD_ROOT_DIR}/plugin/usd/hdStorm.dll DESTINATION bin ) if(OPENUSD_HAS_EMBREE) # Install to bin/usd/ so plugInfo.json's LibraryPath "../hdEmbree.dll" resolves correctly. install(FILES "${HDEMBREE_DLL}" DESTINATION bin/usd OPTIONAL ) install(DIRECTORY "${HDEMBREE_PLUGIN_DIR}" DESTINATION bin/usd OPTIONAL ) if(EMBREE_DLLS) install(FILES ${EMBREE_DLLS} DESTINATION bin OPTIONAL ) endif() endif() if(OPENUSD_HAS_ARNOLD) install(FILES "${HDARNOLD_DLL}" "${NDRARNOLD_DLL}" DESTINATION bin/usd OPTIONAL ) install(DIRECTORY "${HDARNOLD_PLUGIN_DIR}" DESTINATION bin/usd OPTIONAL ) install(DIRECTORY "${NDRARNOLD_PLUGIN_DIR}" DESTINATION bin/usd OPTIONAL ) if(ARNOLD_AI_DLL) install(FILES "${ARNOLD_AI_DLL}" DESTINATION bin OPTIONAL ) endif() endif() # Install Python runtime DLLs required by OpenUSD. install(FILES "$ENV{LOCALAPPDATA}/Programs/Python/Python312/python312.dll" "$ENV{LOCALAPPDATA}/Programs/Python/Python312/python3.dll" DESTINATION bin OPTIONAL # OPTIONAL so the install doesn't fail on machines with a # system-wide Python; in that case the DLL is on PATH already. ) # Copy resources to build directory file(COPY ${CMAKE_SOURCE_DIR}/resources DESTINATION ${CMAKE_BINARY_DIR} ) # Copy font and SVG icons to build directory add_custom_command(TARGET UsdLayerManager POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "$/../resources/font" COMMAND ${CMAKE_COMMAND} -E make_directory "$/resources/icons" COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/third_party/Inter/Inter.ttc" "$/resources/font/Inter.ttc" COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/resources/icons" "$/resources/icons" COMMENT "Copying fonts and SVG icons to build output" ) # Install resources (icons, fonts placeholder) next to the exe so the # exe-relative path "resources/..." resolves correctly from install/bin/. install(DIRECTORY ${CMAKE_SOURCE_DIR}/resources DESTINATION bin ) # Install Inter font next to the exe under resources/font/ # ImGuiContext tries "resources/font/Inter.ttf" then "resources/font/Inter.ttc". install(FILES ${CMAKE_SOURCE_DIR}/third_party/Inter/Inter.ttc DESTINATION bin/resources/font ) # Print configuration summary message(STATUS "") message(STATUS "=== USD Layer Manager Configuration ===") message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") message(STATUS "C++ standard: ${CMAKE_CXX_STANDARD}") message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") message(STATUS "OpenUSD found: ${OpenUSD_FOUND}") message(STATUS "ImGui found: ${Imgui_FOUND}") message(STATUS "OpenGL found: ${OPENGL_FOUND}") message(STATUS "Glad found: ${Glad_FOUND}") message(STATUS "Build tests: ${BUILD_TESTS}") message(STATUS "hdEmbree support: ${OPENUSD_HAS_EMBREE}") if(OPENUSD_HAS_EMBREE AND EMBREE_DLLS) message(STATUS "Embree DLLs: ${EMBREE_DLLS}") elseif(OPENUSD_HAS_EMBREE) message(WARNING "hdEmbree found but no Embree DLLs detected — set EMBREE_LOCATION to the Embree SDK bin/ dir or check HDEMBREE_USD_ROOT/bin") endif() message(STATUS "hdArnold support: ${OPENUSD_HAS_ARNOLD}") if(OPENUSD_HAS_ARNOLD) message(STATUS "hdArnold DLL: ${HDARNOLD_DLL}") message(STATUS "Arnold ai.dll: ${ARNOLD_AI_DLL}") if(NOT ARNOLD_AI_DLL) message(WARNING "hdArnold found but ai.dll not located — set ARNOLD_LOCATION to the MtoA root (e.g. C:/Autodesk/mtoa/5.5.0/2026)") endif() endif() message(STATUS "=======================================") message(STATUS "") # === Test build option === option(BUILD_TESTS "Build test executables" OFF) if(BUILD_TESTS) # === Viewport Display Test === add_executable(ViewportDisplayTest tests/viewport_display_test.cpp ${CORE_SOURCES} ${UTILS_SOURCES} ) target_include_directories(ViewportDisplayTest PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/include ) target_link_libraries(ViewportDisplayTest PRIVATE OpenUSD::OpenUSD Glad::Glad ) if(WIN32) target_compile_definitions(ViewportDisplayTest PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX _CRT_SECURE_NO_WARNINGS ) add_custom_command(TARGET ViewportDisplayTest POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${OpenUSD_BIN_DIR}" "$" COMMAND ${CMAKE_COMMAND} -E copy_directory "${OpenUSD_ROOT_DIR}/lib/usd" "$/usd" COMMAND ${CMAKE_COMMAND} -E copy_directory "${OpenUSD_ROOT_DIR}/plugin/usd" "$/usd" COMMAND ${CMAKE_COMMAND} -E copy_if_different "$ENV{LOCALAPPDATA}/Programs/Python/Python312/python312.dll" "$" COMMAND ${CMAKE_COMMAND} -E copy_if_different "$ENV{LOCALAPPDATA}/Programs/Python/Python312/python3.dll" "$" COMMENT "Copying runtime DLLs and USD plugins for test..." ) endif() enable_testing() add_test(NAME ViewportDisplayTest COMMAND ViewportDisplayTest) add_executable(RendererDiagnosticTest tests/renderer_diagnostic_test.cpp ${CORE_SOURCES} ${UTILS_SOURCES} ) target_include_directories(RendererDiagnosticTest PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/include ) target_link_libraries(RendererDiagnosticTest PRIVATE OpenUSD::OpenUSD Glad::Glad ) if(WIN32) target_compile_definitions(RendererDiagnosticTest PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX _CRT_SECURE_NO_WARNINGS ) add_custom_command(TARGET RendererDiagnosticTest POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${OpenUSD_BIN_DIR}" "$" COMMAND ${CMAKE_COMMAND} -E copy_directory "${OpenUSD_ROOT_DIR}/lib/usd" "$/usd" COMMAND ${CMAKE_COMMAND} -E copy_directory "${OpenUSD_ROOT_DIR}/plugin/usd" "$/usd" COMMAND ${CMAKE_COMMAND} -E copy_if_different "$ENV{LOCALAPPDATA}/Programs/Python/Python312/python312.dll" "$" COMMAND ${CMAKE_COMMAND} -E copy_if_different "$ENV{LOCALAPPDATA}/Programs/Python/Python312/python3.dll" "$" COMMENT "Copying runtime DLLs and USD plugins for diagnostic test..." ) endif() endif() # BUILD_TESTS