add Null asset resolution example.

This commit is contained in:
Syoyo Fujita
2025-06-06 11:35:59 +09:00
parent 921c54f871
commit 06d28178b6
2 changed files with 171 additions and 12 deletions

View File

@@ -24,6 +24,56 @@
#include "value-pprint.hh"
#include "value-types.hh"
static int NullARResolve(const char *asset_name,
const std::vector<std::string> &search_paths,
std::string *resolved_asset_name, std::string *err,
void *userdata) {
(void)err;
(void)userdata;
(void)search_paths;
(void)asset_name;
(void)resolved_asset_name;
return -1;
}
static int NullARSize(const char *asset_name, uint64_t *nbytes, std::string *err,
void *userdata) {
(void)userdata;
(void)asset_name;
(void)nbytes;
(void)err;
return -1;
}
static int NullARRead(const char *asset_name, uint64_t req_nbytes, uint8_t *out_buf,
uint64_t *nbytes, std::string *err, void *userdata) {
(void)asset_name;
(void)req_nbytes;
(void)out_buf;
(void)nbytes;
(void)err;
(void)userdata;
return -1;
}
static bool SetupNullAssetResolution(
tinyusdz::AssetResolutionResolver &resolver)
{
tinyusdz::AssetResolutionHandler handler;
handler.resolve_fun = NullARResolve;
handler.size_fun = NullARSize;
handler.read_fun = NullARRead;
handler.write_fun = nullptr;
handler.userdata = nullptr;
resolver.register_wildcard_asset_resolution_handler(handler);
return true;
}
int main(int argc, char **argv) {
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " input.usd [OPTIONS].\n";
@@ -31,6 +81,8 @@ int main(int argc, char **argv) {
std::cout << " --timecode VALUE: Specify timecode value(e.g. 3.14)\n";
std::cout << " --noidxbuild: Do not rebuild vertex indices\n";
std::cout << " --notri: Do not triangulate mesh\n";
std::cout << " --notexload: Do not load textures\n";
std::cout << " --noar: Do not use (default) AssertResolver\n";
std::cout << " --nousdprint: Do not print parsed USD\n";
std::cout
<< " --dumpobj: Dump mesh as wavefront .obj(for visual debugging)\n";
@@ -48,6 +100,8 @@ int main(int argc, char **argv) {
bool export_obj = false;
bool export_usd = false;
bool no_usdprint = false;
bool no_texload = false;
bool no_assetresolver = false;
std::string filepath;
for (int i = 1; i < argc; i++) {
@@ -57,6 +111,10 @@ int main(int argc, char **argv) {
build_indices = false;
} else if (strcmp(argv[i], "--nousdprint") == 0) {
no_usdprint = true;
} else if (strcmp(argv[i], "--notexload") == 0) {
no_texload = true;
} else if (strcmp(argv[i], "--noar") == 0) {
no_assetresolver = true;
} else if (strcmp(argv[i], "--dumpobj") == 0) {
export_obj = true;
} else if (strcmp(argv[i], "--dumpusd") == 0) {
@@ -117,6 +175,9 @@ int main(int argc, char **argv) {
<< "\n";
env.mesh_config.build_vertex_indices = build_indices;
std::cout << "Load texture data : " << (!no_texload ? "true" : "false") << "\n";
env.scene_config.load_texture_assets = !no_texload;
// Add base directory of .usd file to search path.
std::string usd_basedir = tinyusdz::io::GetBaseDir(filepath);
std::cout << "Add seach path: " << usd_basedir << "\n";
@@ -135,22 +196,26 @@ int main(int argc, char **argv) {
tinyusdz::AssetResolutionResolver arr;
// NOTE: Pointer address of usdz_asset must be valid until the call of
// RenderSceneConverter::ConvertToRenderScene.
if (!tinyusdz::SetupUSDZAssetResolution(arr, &usdz_asset)) {
std::cerr << "Failed to setup AssetResolution for USDZ asset\n";
exit(-1);
};
if (no_assetresolver) {
SetupNullAssetResolution(arr);
} else {
// NOTE: Pointer address of usdz_asset must be valid until the call of
// RenderSceneConverter::ConvertToRenderScene.
if (!tinyusdz::SetupUSDZAssetResolution(arr, &usdz_asset)) {
std::cerr << "Failed to setup AssetResolution for USDZ asset\n";
exit(-1);
};
}
env.asset_resolver = arr;
} else {
env.set_search_paths({usd_basedir});
// TODO: Add example to set user-defined AssetResolutionResolver
// AssetResolutionResolver arr;
// ...
// env.asset_resolver(arr);
if (no_assetresolver) {
SetupNullAssetResolution(env.asset_resolver);
std::cout << "Null asset resolver\n";
}
}
if (!tinyusdz::value::TimeCode(timecode).is_default()) {

View File

@@ -54,10 +54,38 @@ bool AssetResolutionResolver::find(const std::string &assetPath) const {
return sz > 0;
} else {
DCOUT("Either Resolve function or Size function is nullptr. Fallback to built-in file handler.");
DCOUT("Either Resolve function or Size function is nullptr. Fallback to wildcard handler or built-in file handler.");
}
}
// wildcard
if (_asset_resolution_handlers.count("*")) {
if (_asset_resolution_handlers.at("*").resolve_fun && _asset_resolution_handlers.at("*").size_fun) {
std::string resolvedPath;
std::string err;
// Use custom handler's userdata
void *userdata = _asset_resolution_handlers.at("*").userdata;
int ret = _asset_resolution_handlers.at("*").resolve_fun(assetPath.c_str(), _search_paths, &resolvedPath, &err, userdata);
if (ret != 0) {
return false;
}
uint64_t sz{0};
ret = _asset_resolution_handlers.at("*").size_fun(resolvedPath.c_str(), &sz, &err, userdata);
if (ret != 0) {
return false;
}
return sz > 0;
}
return false;
}
// default fallback: File-based
if ((_current_working_path == ".") || (_current_working_path == "./")) {
std::string rpath = io::FindFile(assetPath, {});
} else {
@@ -95,10 +123,30 @@ std::string AssetResolutionResolver::resolve(
return resolvedPath;
} else {
DCOUT("Resolve function is nullptr. Fallback to built-in file handler.");
DCOUT("Resolve function is nullptr. Fallback to wildcard handler or built-in file handler.");
}
}
if (_asset_resolution_handlers.count("*")) {
if (_asset_resolution_handlers.at("*").resolve_fun) {
std::string resolvedPath;
std::string err;
// Use custom handler's userdata
void *userdata = _asset_resolution_handlers.at("*").userdata;
int ret = _asset_resolution_handlers.at("*").resolve_fun(assetPath.c_str(), _search_paths, &resolvedPath, &err, userdata);
if (ret != 0) {
return std::string();
}
return resolvedPath;
}
return std::string();
}
DCOUT("cwd = " << _current_working_path);
DCOUT("search_paths = " << _search_paths);
DCOUT("assetPath = " << assetPath);
@@ -181,6 +229,52 @@ bool AssetResolutionResolver::open_asset(const std::string &resolvedPath, const
}
}
if (_asset_resolution_handlers.count("*")) {
if (_asset_resolution_handlers.at("*").size_fun && _asset_resolution_handlers.at("*").read_fun) {
// Use custom handler's userdata
void *userdata = _asset_resolution_handlers.at("*").userdata;
// Get asset size.
uint64_t sz{0};
int ret = _asset_resolution_handlers.at("*").size_fun(resolvedPath.c_str(), &sz, err, userdata);
if (ret != 0) {
if (err) {
(*err) += "Get size of asset through handler failed.\n";
}
return false;
}
DCOUT("asset_size: " << sz);
tinyusdz::Asset asset;
asset.resize(size_t(sz));
uint64_t read_size{0};
ret = _asset_resolution_handlers.at("*").read_fun(resolvedPath.c_str(), /* req_size */asset.size(), asset.data(), &read_size, err, userdata);
if (ret != 0) {
if (err) {
(*err) += "Read asset through handler failed.\n";
}
return false;
}
if (read_size < sz) {
asset.resize(size_t(read_size));
// May optimize memory usage
asset.shrink_to_fit();
}
(*asset_out) = std::move(asset);
return true;
}
return false;
}
// Default: read from a file.
std::vector<uint8_t> data;
size_t max_bytes = 1024 * 1024 * _max_asset_bytes_in_mb;