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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,11 @@
*.app

# Build artifacts
*build*/
build-meta
/build/

# Python
/.venv*
/venv*
**/.venv*
**/venv*

# ide folder
.vscode/*
Expand All @@ -52,12 +51,11 @@ build-meta
docs
Testing
bin
install
test/output
test/assets/fbx/*.usd
test/assets/gltf/*.usd
test/assets/obj/*/*.usd
test/assets/ply/*.usd
test/assets/stl/*.usd
test/assets/**/*
test/refs
test/test_output.txt

# macOS system files
.DS_Store
Expand Down
80 changes: 56 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ set(VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPAC
message(STATUS "PROJECT VERSION IS: ${VERSION}")
configure_file(version.h.in "${CMAKE_CURRENT_BINARY_DIR}/version.h")

# CMP0077 is used to set the default policy for the third party packages so that
# we can set the options without explicitly creating CACHE variables.
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)

get_directory_property(HAS_PARENT PARENT_DIRECTORY)
if (HAS_PARENT)
set(usd_fileformats_standalone_default FALSE)
else ()
Expand All @@ -24,6 +29,9 @@ if(USD_FILEFORMATS_STANDALONE)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
endif()
include(cmake/compiler_config.cmake)
include(cmake/register_plugins.cmake)
include(GNUInstallDirs)
include(CMakeDependentOption)

option(USD_FILEFORMATS_BUILD_TESTS "Build the unit tests" ON)
option(USD_FILEFORMATS_ENABLE_FBX "Enables fbx plugin" ON)
Expand All @@ -34,6 +42,13 @@ option(USD_FILEFORMATS_ENABLE_PLY "Enables ply plugin" ON)
option(USD_FILEFORMATS_ENABLE_STL "Enables stl plugin" ON)
option(USD_FILEFORMATS_ENABLE_SBSAR "Enables sbsar plugin" OFF)
option(USD_FILEFORMATS_ENABLE_DRACO "Enables draco for the gltf plugin" OFF)

option(USD_FILEFORMATS_FBX_SANDBOX "Enables fbx sandboxing" OFF)
option(USD_FILEFORMATS_GLTF_SANDBOX "Enables gltf sandboxing" OFF)
option(USD_FILEFORMATS_OBJ_SANDBOX "Enables obj sandboxing" OFF)
option(USD_FILEFORMATS_PLY_SANDBOX "Enables ply sandboxing" OFF)
option(USD_FILEFORMATS_SPZ_SANDBOX "Enables spz sandboxing" OFF)
option(USD_FILEFORMATS_STL_SANDBOX "Enables stl sandboxing" OFF)
option(USD_FILEFORMATS_FETCH_GTEST "Forces FetchContent for GTest" ON)
option(USD_FILEFORMATS_FETCH_TINYGLTF "Forces FetchContent for TinyGLTF" ON)
option(USD_FILEFORMATS_FETCH_DRACO "Forces FetchContent for Draco" OFF)
Expand All @@ -54,6 +69,10 @@ option(USD_FILEFORMATS_FETCH_SPHERICAL_HARMONICS "Forces FetchContent for Spheri
# NOTE: These MaterialX shaders are not compatible with Reality Composer.
option(USD_FILEFORMATS_ENABLE_MTLX "Enables MaterialX material representation" OFF)

option(USD_FILEFORMATS_ENABLE_INSTALL "Enable installation rules" ON)
cmake_dependent_option(USD_FILEFORMATS_ENABLE_INSTALL_PLUGINFO_ROOT "Enable installation of `plugInfo.root.json` files" ON "USD_FILEFORMATS_ENABLE_INSTALL" OFF)
option(PRODUCT_STRING "Define the product string which is appended to the generated usd comment" "")

# unary_function and binary_function are no longer provided in C++17 and newer Standard modes.
# They can be re-enabled with _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION
add_compile_definitions(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION)
Expand All @@ -64,6 +83,10 @@ if (USD_FILEFORMATS_BUILD_TESTS AND USD_FILEFORMATS_STANDALONE)
enable_testing()
endif ()

if (USD_FILEFORMATS_BUILD_TESTS)
add_subdirectory(test/gtest_common)
endif ()

if (USD_FILEFORMATS_ENABLE_ASM)
message("Building with ASM")
add_definitions(-DUSD_FILEFORMATS_ENABLE_ASM)
Expand Down Expand Up @@ -98,46 +121,55 @@ if (USD_FILEFORMATS_STANDALONE)
endif ()
endif ()

if(APPLE)
set(plugin_install_rpath_root @loader_path)
else()
set(plugin_install_rpath_root $ORIGIN)
endif()

if(PRODUCT_STRING)
add_definitions(-DPRODUCT_STRING="${PRODUCT_STRING}")
endif()

add_subdirectory(utils)

# Add a new file format to the build. This macro will add the relevant subdirectory and set the
# installation destination needed by that plugin's CMakeLists.txt so it installs into
# usd-fileformats-plugins/bin/plugin/usd
#
# New variables:
# - USD${FILEFORMAT}_DESTINATION: Where the fileformat libraries will be installed. This will
# typically be "plugin/usd"
# Example: USDFBX_DESTINATION
#
# @param SUBDIRECTORY_NAME The name of the subdirectory to add. This should be the same name as
# directory of the plugin, and will typically be all lowercase
macro(add_usd_fileformat SUBDIRECTORY_NAME)
string(TOUPPER ${SUBDIRECTORY_NAME} FILEFORMAT)

set(USD${FILEFORMAT}_DESTINATION "plugin/usd")
add_subdirectory(${SUBDIRECTORY_NAME})
endmacro()
# Generic, protocol-free libraries reused by the sandbox protocol layer (and,
# later, other out-of-process work). Built unconditionally; tiny and dependency-light.
add_subdirectory(serialization)

add_subdirectory(ipc)

include(cmake/AddUsdFileformat.cmake)

# Initialize the list for all the plugins
set_property(GLOBAL PROPERTY USD_FILEFORMATS_ENABLED_PLUGINS "")
set_property(GLOBAL PROPERTY USD_FILEFORMATS_SANDBOXED_PLUGINS "")

if (USD_FILEFORMATS_ENABLE_FBX)
add_usd_fileformat(fbx)
add_usd_fileformat(fbx USD_FILEFORMATS_FBX_SANDBOX)
endif()
if (USD_FILEFORMATS_ENABLE_GLTF)
add_usd_fileformat(gltf)
add_usd_fileformat(gltf USD_FILEFORMATS_GLTF_SANDBOX)
endif()
if (USD_FILEFORMATS_ENABLE_OBJ)
add_usd_fileformat(obj)
add_usd_fileformat(obj USD_FILEFORMATS_OBJ_SANDBOX)
endif()
if (USD_FILEFORMATS_ENABLE_PLY)
add_usd_fileformat(ply)
add_usd_fileformat(ply USD_FILEFORMATS_PLY_SANDBOX)
endif()
if (USD_FILEFORMATS_ENABLE_SBSAR)
add_usd_fileformat(sbsar)
# SBSAR does not support sandboxing
add_usd_fileformat(sbsar FALSE)
endif()
if (USD_FILEFORMATS_ENABLE_SPZ)
add_usd_fileformat(spz)
add_usd_fileformat(spz USD_FILEFORMATS_SPZ_SANDBOX)
endif()
if (USD_FILEFORMATS_ENABLE_STL)
add_usd_fileformat(stl)
add_usd_fileformat(stl USD_FILEFORMATS_STL_SANDBOX)
endif()

if (USD_FILEFORMATS_SANDBOXED_EXTENSIONS) # Only build sandbox if there are sandboxed extensions
add_subdirectory(sandbox)
endif()

if (UNIX AND NOT APPLE)
Expand Down
43 changes: 41 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ The following dependencies are needed:
| [Happly](https://github.com/nmwsharp/happly.git) | cfa2611 | usdply | no |
| [Spherical Harmonics](https://github.com/google/spherical-harmonics) | ccb6c7f | usdply, usdspz | no |
| [Spz](https://github.com/nianticlabs/spz) | fd4e2a5 | usdspz | no |
| [Substance](https://developer.adobe.com/substance3d-sdk/) | 9.1.2 | usdsbsar | no |
| [Substance](https://developer.adobe.com/substance3d-sdk/) | 9.4.1 | usdsbsar | no |


## Coding Standards
Expand Down Expand Up @@ -98,7 +98,7 @@ If USD was built with Python (default behavior with the build script), ensure th

* Substance SDK Integration
1. Download the SDK: Visit the [Adobe Developer Console](https://developer.adobe.com/console/servicesandapis#) and log in or create an account if necessary.
2. Locate the SDK: Use the search bar to find the ‘Adobe Substance 3D Materials SDK’. Version 9.1.2
2. Locate the SDK: Use the search bar to find the ‘Adobe Substance 3D Materials SDK’. Version 9.4.1

### 2. Get it
```
Expand Down Expand Up @@ -127,6 +127,7 @@ where:
| -DGTest_ROOT | Points to the GTest installation | empty | all tests |
| -DFBXSDK_ROOT | Points to the Fbx installation | empty | usdfbx |
| -Dsubstance_DIR | Points to the Substance SDK installation | empty | usdsbsar |
| -DCMAKE_OSX_ARCHITECTURES | Target arch on macOS; set to `arm64` so an arm64-only Substance SDK links (selects `neon_blend`, not the universal `cpu_blend`) | empty | usdsbsar (macOS) |
| -DZLIB_ROOT | Points to the ZLIB installation | empty | usdfbx |
| -DLibXml2_ROOT | Points to the LibXml2 installation | empty | usdfbx |
| -DTinyGLTF_ROOT | Points to the TinyGLTF installation | empty | usdgltf |
Expand Down Expand Up @@ -270,6 +271,44 @@ stage.Export("cube.usd")

Refer to each plugin's README for more details.

## Material networks

When converting to USD, the plugins can write up to three material network representations per material: **UsdPreviewSurface**, **OpenPBR** (authored as a MaterialX network), and **Adobe Standard Material (ASM)**. OpenPBR is now written by default alongside UsdPreviewSurface.

### Current defaults

| Representation | Flag | Default | Status |
|---|---|---|---|
| UsdPreviewSurface | `USD_FILEFORMATS_WRITE_USDPREVIEWSURFACE` | on | Deprecated, still supported |
| OpenPBR | `USD_FILEFORMATS_WRITE_OPENPBR` | on | Default |
| Adobe Standard Material (ASM) | `USD_FILEFORMATS_WRITE_ASM` | off | Deprecated, still supported |
| Native OpenPBR processing | `USD_FILEFORMATS_NATIVE_OPENPBR_PROCESSING` | on | |

ASM and UsdPreviewSurface are **deprecated** and will be removed in a future release, but they remain fully supported for now. Enabling either emits a one-time deprecation warning.

### Enabling and disabling

Each representation can be toggled three ways, listed highest priority first:

1. **Per file**, via `SDF_FORMAT_ARGS` on the asset path (affects a single open). Arguments are `writeUsdPreviewSurface`, `writeASM`, and `writeOpenPBR`, each `true` or `false`:
```
usdcat "cube.fbx:SDF_FORMAT_ARGS:writeOpenPBR=false&writeUsdPreviewSurface=true" -o cube.usd
```
2. **Per process**, via environment variables (values `0` or `1`):
```
export USD_FILEFORMATS_WRITE_OPENPBR=0
```
Available variables: `USD_FILEFORMATS_WRITE_USDPREVIEWSURFACE`, `USD_FILEFORMATS_WRITE_ASM`, `USD_FILEFORMATS_WRITE_OPENPBR`, `USD_FILEFORMATS_NATIVE_OPENPBR_PROCESSING`.
3. **At build time**, via the compile-time defaults:
```
-DUSD_FILEFORMATS_DEFAULT_WRITE_OPENPBR=OFF
```
(`-DUSD_FILEFORMATS_ENABLE_ASM=ON` is a convenience option that turns the ASM default on.)

### Known issue: OpenPBR requires a recent USD

OpenPBR is authored as a **MaterialX** network. These networks are not supported by older versions of USD: **USD 26.03 and below** will fail to render OpenPBR materials (for example, shader compilation errors). When targeting an older USD, disable OpenPBR and rely on UsdPreviewSurface using any mechanism above, for example `USD_FILEFORMATS_WRITE_OPENPBR=0`.

## Documentation

To generate the documentation go to the project root folder and enter:
Expand Down
84 changes: 82 additions & 2 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,90 @@
v2026.5 May 22nd, 2026
v2026.07 July 17th, 2026

Features
all
- Flip writer defaults to native OpenPBR
- Deprecate ASM and UsdPreviewSurface writers in favor of native OpenPBR
- Replace the default ASM material struct with OpenPBR using a feature flag
fbx
- Import OpenPBR materials from Maya and 3ds Max exports
- add support for new SDF_FORMAT_ARGS:importLights option
gltf
- Add various OpenPBR features to glTF import
- add support for new SDF_FORMAT_ARGS:importLights option
sandbox
- added sandbox module alongside ipc and serialization modules
sbsar
- Create shader graph to convert sbsar tangent input to geometry_tangent
- Add API to get resolved path from image cache for SBSAR SAL interop
utils
- UTF-8-aware MakeValidUsdIdentifier prim-name sanitizer
- Per-node custom properties as prim customData

Fixes
all
- Move normalScale from texture reader scale/bias to ND_normalmap scale input
- Use constants to initialize normal scale/bias
fbx
- Preserve material assignment for InstanceProxy models
- Preserve rotation on FBX nodes with near-zero scale
- Resolve sibling textures when GetRelativeFileName returns absolute-looking path
- Work around FBX SDK 2020.3.9 triangulate crash on skinned meshes
- Preserve per-GeomSubset material bindings on export
- Import Phong materials as dielectric by default
- Matte Lambert roughness and reflectivity-gated Phong metalness
- Preserve roughness when converting Phong FBX materials to USD
- Zero specular_weight and transfer Lambert Diffuse weight to base_weight
- Attach materials to every shared-mesh instance node
- Triangulate meshes with untriangulated n-gon polygons
gltf
- Do proper conversion of gltf anisotropy to OpenPBR on import
- Fix for crash caused by failing to check value validity
- Skip UsdLuxDomeLight on export instead of converting to point light
- Reject animation samplers with mismatched accessor counts
- Avoid duplicate tinygltf symbols with Xcode 26 linker
- Author mesh extent on import to keep bbox queries O(1)
- Validate vertex attribute accessor types to prevent heap overflow
- Fold OpenPBR base_weight into baseColorFactor on export
obj
- Fix missing materials with combineGroups and separateGroupsAsSubsets
- Parse ZBrush #MRGB vertex colors in OBJ import
- Defer parser warnings from TBB workers to main thread
- Removing stale obj test
- Derive roughness from Phong shininess on import
- Keep map_Kd texture when Kd is a placeholder zero
- Escape untrusted bytes in OBJ parser diagnostics
ply
- One-liner fix to narrow opacity filtering with std::isnan
- Write per-face color/opacity at submesh offset and guard property size
sbsar
- Various improvements to the SBSAR render thread
- Incorrect mapping of asm 'scatteringColor' and added missing mapping of 'scatteringDistance'
- Fix intermittent null-deref crash in render thread on startup
- Fix mapping of sbsar outputs using OpenPBR material model to openpbr material inputs
- Default-initialize RenderResultCache members and guard against nullptr
- Guard against null mRenderResultImage in _OpenForReading
- Join render thread before static teardown
- Suppress error for empty path in SBSAR image input
- Fix reading of sbsar images
stl
- Reject non-3D-model files sharing the .stl extension
utils
- Uniquify meshes, curves, and child nodes in shared prim namespace
- Post a coding error when authoring duplicate prim children
- Uniquify node names (especially synthesized Materials node)
- Guard Image::allocate/read against integer overflow

Docs
fbx
- Add FBX SDK update process documentation

v2026.05 May 22nd, 2026

Fixes
gltf
- add input validation to NGP extension to prevent memory corruption vulnerabilities

v2026.3 March 6th, 2026
v2026.03 March 6th, 2026

General Changes:
- Fixed compatibility with USD 25.x
Expand Down
44 changes: 44 additions & 0 deletions cmake/AddUsdFileformat.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Empty list that will be populated with the sandboxed file formats
set(USD_FILEFORMATS_SANDBOXED_EXTENSIONS)

# Add a new file format to the build. This macro will add the relevant subdirectory and determine
# if the format should be sandboxed. If it is, it will add the extensions to the
# USD_FILEFORMATS_SANDBOXED_EXTENSIONS list and create relevant variables.
#
# New variables:
# - USD${FILEFORMAT}_DESTINATION: Where the fileformat libraries will be installed. This will be
# either bin/plugin/usd (for regular fileformats) or
# bin/plugin_sandboxed/usd (for sandboxed fileformats).
# Example: USDFBX_DESTINATION
#
# This function also requires the fileformat CMakeLists.txt to set ${FILEFORMAT}_EXT_LIST to a
# list of extensions that the format supports. These must be case sensitive, so the sandbox proxy
# resolver can find all variants of a file extension.
#
# @param SUBDIRECTORY_NAME The name of the subdirectory to add.
# @param SANDBOXED True if the fileformat should be sandboxed, false otherwise.
macro(add_usd_fileformat SUBDIRECTORY_NAME SANDBOXED)
# Ensure the format name is uppercase for use in variables
string(TOUPPER ${SUBDIRECTORY_NAME} FILEFORMAT)
if(NOT DEFINED USD${FILEFORMAT}_DESTINATION)
if (${SANDBOXED})
set(USD${FILEFORMAT}_DESTINATION "plugin_sandboxed/usd")
# Set before add_subdirectory so the child scope can read it
set(_FILEFORMAT_SANDBOXED TRUE)
else()
set(USD${FILEFORMAT}_DESTINATION "plugin/usd")
set(_FILEFORMAT_SANDBOXED FALSE)
endif()
endif()

add_subdirectory(${SUBDIRECTORY_NAME})

# The fileformat CMakeLists.txt should have set ${FILEFORMAT}_EXT_LIST, so we can save it
if (${SANDBOXED})
if (NOT DEFINED ${FILEFORMAT}_EXT_LIST)
message(FATAL_ERROR "The fileformat ${FILEFORMAT} does not define the "
"${FILEFORMAT}_EXT_LIST variable required for sandboxing.")
endif()
list(APPEND USD_FILEFORMATS_SANDBOXED_EXTENSIONS ${${FILEFORMAT}_EXT_LIST})
endif()
endmacro()
Loading
Loading