mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
7.5 KiB
7.5 KiB
C++ MaterialX Import Support
Overview
TinyUSDZ now includes built-in C++ support for loading MaterialX (.mtlx) files without external dependencies. The implementation uses a secure, dependency-free XML parser specifically designed for MaterialX documents.
Architecture
Components
-
MaterialX Parser (
src/mtlx-*.hh/cc)mtlx-xml-tokenizer: Low-level XML tokenization with security limitsmtlx-simple-parser: Lightweight DOM tree buildermtlx-dom: MaterialX-specific document object modelmtlx-usd-adapter: pugixml-compatible interface
-
USD Integration (
src/usdMtlx.cc/hh)- MaterialX to USD conversion
- Support for multiple shader types
- PrimSpec generation
Supported Shaders
- ✅ OpenPBR Surface (
open_pbr_surface) - Full support - ✅ Autodesk Standard Surface (
standard_surface) - Full support - ✅ USD Preview Surface (
UsdPreviewSurface) - Full support
API Usage
Basic Import
#include "usdMtlx.hh"
// Load from string
std::string xml_content = "...";
tinyusdz::MtlxModel mtlx;
std::string warn, err;
bool success = tinyusdz::ReadMaterialXFromString(
xml_content,
"material.mtlx", // asset name
&mtlx,
&warn,
&err
);
if (success) {
std::cout << "Loaded MaterialX version: " << mtlx.version << std::endl;
}
Load from File
#include "usdMtlx.hh"
tinyusdz::AssetResolutionResolver resolver;
tinyusdz::MtlxModel mtlx;
std::string warn, err;
bool success = tinyusdz::ReadMaterialXFromFile(
resolver,
"path/to/material.mtlx",
&mtlx,
&warn,
&err
);
Convert to USD PrimSpec
// Convert MaterialX model to USD PrimSpec
tinyusdz::PrimSpec ps;
std::string err;
bool success = tinyusdz::ToPrimSpec(mtlx, ps, &err);
if (success) {
// Use PrimSpec in USD Stage
// ...
}
Load as USD Asset Reference
#include "usdMtlx.hh"
tinyusdz::Asset asset;
tinyusdz::PrimSpec ps;
std::string warn, err;
bool success = tinyusdz::LoadMaterialXFromAsset(
asset,
"material.mtlx",
ps, // inout parameter
&warn,
&err
);
OpenPBR Surface Support
The MtlxOpenPBRSurface shader supports all OpenPBR specification parameters:
Base Layer
base_weight(float)base_color(color3)base_metalness(float)base_diffuse_roughness(float)
Specular Layer
specular_weight(float)specular_color(color3)specular_roughness(float)specular_ior(float)specular_anisotropy(float)specular_rotation(float)
Transmission
transmission_weight(float)transmission_color(color3)transmission_depth(float)transmission_scatter(color3)transmission_scatter_anisotropy(float)transmission_dispersion(float)
Subsurface
subsurface_weight(float)subsurface_color(color3)subsurface_radius(color3)subsurface_scale(float)subsurface_anisotropy(float)
Coat (Clearcoat)
coat_weight(float)coat_color(color3)coat_roughness(float)coat_anisotropy(float)coat_rotation(float)coat_ior(float)coat_affect_color(float)coat_affect_roughness(float)
Thin Film
thin_film_thickness(float)thin_film_ior(float)
Emission
emission_luminance(float)emission_color(color3)
Geometry
geometry_opacity(float)geometry_thin_walled(bool)geometry_normal(normal3)geometry_tangent(vector3)
Example MaterialX File
<?xml version="1.0"?>
<materialx version="1.38">
<surfacematerial name="RedMetal" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="RedMetal_shader" />
</surfacematerial>
<open_pbr_surface name="RedMetal_shader" type="surfaceshader">
<input name="base_color" type="color3" value="0.8, 0.2, 0.2" />
<input name="base_weight" type="float" value="1.0" />
<input name="base_metalness" type="float" value="0.8" />
<input name="specular_roughness" type="float" value="0.3" />
<input name="specular_ior" type="float" value="1.5" />
</open_pbr_surface>
</materialx>
Security Features
The built-in parser includes multiple security safeguards:
- Maximum name length: 256 characters
- Maximum string length: 64KB
- Maximum text content: 1MB
- Maximum nesting depth: 1000 levels
- Safe entity handling: HTML entities only (no external entity expansion)
- No external file access: Prevents XXE attacks
- Memory limits: Prevents denial-of-service attacks
Build Configuration
CMake
# Enable MaterialX support (enabled by default)
set(TINYUSDZ_USE_USDMTLX ON CACHE BOOL "Enable MaterialX support")
Compile Flags
# Enable MaterialX in your build
-DTINYUSDZ_USE_USDMTLX
Testing
Run Tests
cd tests/feat/mtlx
make clean
make
./test_mtlx_import
Test with Custom File
./test_mtlx_import path/to/your/material.mtlx
Expected Output
=== TinyUSDZ MaterialX Import Test ===
Test 1: Parsing MaterialX XML from string...
✓ Successfully parsed MaterialX
Parsed MaterialX information:
Asset name: test.mtlx
Version: 1.38
Shader name: TestMaterial_shader
Surface materials: 1
Shaders: 1
Test 2: Converting MaterialX to USD PrimSpec...
✓ Successfully converted to PrimSpec
PrimSpec name: TestMaterial
PrimSpec type: Material
=== All tests passed! ===
Comparison: pugixml vs Built-in Parser
| Feature | pugixml | Built-in Parser |
|---|---|---|
| External Dependency | Yes | No |
| Size | ~200KB | Integrated |
| Security | Basic | Enhanced |
| Memory Limits | Manual | Automatic |
| MaterialX Specific | No | Yes |
| XXE Protection | Manual | Built-in |
| Performance | Fast | Fast |
Migration from pugixml
The migration is automatic - the built-in parser provides a pugixml-compatible adapter:
Before (with external pugixml):
#include "external/pugixml.hpp"
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_string(xml);
After (with built-in parser):
#include "mtlx-usd-adapter.hh"
tinyusdz::mtlx::pugi::xml_document doc;
tinyusdz::mtlx::pugi::xml_parse_result result = doc.load_string(xml);
The API is compatible, so existing code continues to work.
Limitations
- MaterialX versions: Supports 1.36, 1.37, and 1.38
- XML namespaces: Basic support (MaterialX doesn't use them heavily)
- XPath: Not supported (not needed for MaterialX)
- DOM manipulation: Read-only parsing
Error Handling
std::string warn, err;
bool success = tinyusdz::ReadMaterialXFromString(xml, name, &mtlx, &warn, &err);
if (!success) {
std::cerr << "Error: " << err << std::endl;
return 1;
}
if (!warn.empty()) {
std::cout << "Warnings: " << warn << std::endl;
}
Future Enhancements
- MaterialX node graph support beyond surface shaders
- MaterialX standard library includes
- Write support (currently read-only)
- XPath queries for advanced filtering
- Texture node parsing and loading
- MaterialX validation against schema
References
License
Apache 2.0 - Same as TinyUSDZ project