Skip to content

Commit

Permalink
fileformat handler(W.I.P.)
Browse files Browse the repository at this point in the history
  • Loading branch information
syoyo committed Sep 20, 2023
1 parent a9559f0 commit 199d6f4
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 96 deletions.
8 changes: 4 additions & 4 deletions examples/file_format/file-format-example.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ int main(int argc, char **argv) {
my_handler.writer = MyWrite;
my_handler.userdata = nullptr;

tinyusdz::USDLoadOptions options;
options.fileformats["my"] = my_handler;

tinyusdz::Stage stage; // empty scene

std::string input_usd_filepath = "../data/fileformat_my.usda";
Expand All @@ -75,7 +72,7 @@ int main(int argc, char **argv) {
std::string warn, err;

tinyusdz::Layer layer;
bool ret = tinyusdz::LoadLayerFromFile(input_usd_filepath, &layer, &warn, &err, options);
bool ret = tinyusdz::LoadLayerFromFile(input_usd_filepath, &layer, &warn, &err);

if (warn.size()) {
std::cout << "WARN: " << warn << "\n";
Expand All @@ -89,6 +86,9 @@ int main(int argc, char **argv) {
// dummy Asset resolver.
tinyusdz::AssetResolutionResolver resolver;

tinyusdz::ReferencesCompositionOptions options;
options.fileformats["my"] = my_handler;

// Do `references` composition to materialize `references = @***.my@`
tinyusdz::Layer composited_layer;
if (!tinyusdz::CompositeReferences(resolver, layer, &composited_layer, &warn, &err)) {
Expand Down
29 changes: 18 additions & 11 deletions src/composition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ bool IsBuiltinFileFormat(const std::string &name) {

// TODO: support loading non-USD asset
bool LoadAsset(AssetResolutionResolver &resolver,
const std::map<std::string, FileFormatHandler> &fileformats,
const value::AssetPath &assetPath, const Path &primPath,
Layer *dst_layer, const PrimSpec **dst_primspec_root,
const bool error_when_no_prims_found,
Expand Down Expand Up @@ -161,13 +162,19 @@ bool LoadAsset(AssetResolutionResolver &resolver,
}
}
} else {
if (error_when_unsupported_fileformat) {
PUSH_ERROR_AND_RETURN(
fmt::format("Unknown/unsupported asset file format: {}", asset_path));
std::string ext = GetExtension(asset_path);
if (fileformats.count(ext)) {
DCOUT("Fileformat handler found for: " + ext);

} else {
PUSH_WARN(fmt::format(
"Unknown/unsupported asset file format. Skipped: {}", asset_path));
return true;
if (error_when_unsupported_fileformat) {
PUSH_ERROR_AND_RETURN(
fmt::format("Unknown/unsupported asset file format: {}", asset_path));
} else {
PUSH_WARN(fmt::format(
"Unknown/unsupported asset file format. Skipped: {}", asset_path));
return true;
}
}
}

Expand Down Expand Up @@ -301,7 +308,7 @@ bool CompositeSublayersRec(AssetResolutionResolver &resolver,
}

tinyusdz::Layer sublayer;
if (!LoadAsset(resolver, layer.assetPath, /* not_used */Path::make_root_path(), &sublayer, /* primspec_root */nullptr, options.error_when_no_prims_in_sublayer, options.error_when_asset_not_found, options.error_when_unsupported_fileformat, warn, err)) {
if (!LoadAsset(resolver, options.fileformats, layer.assetPath, /* not_used */Path::make_root_path(), &sublayer, /* primspec_root */nullptr, options.error_when_no_prims_in_sublayer, options.error_when_asset_not_found, options.error_when_unsupported_fileformat, warn, err)) {
PUSH_ERROR_AND_RETURN(fmt::format("Load asset in subLayer failed: `{}`", layer.assetPath));
}

Expand Down Expand Up @@ -447,7 +454,7 @@ bool CompositeReferencesRec(uint32_t depth, AssetResolutionResolver &resolver,
Layer layer;
const PrimSpec *src_ps{nullptr};

if (!LoadAsset(resolver, reference.asset_path, reference.prim_path,
if (!LoadAsset(resolver, options.fileformats, reference.asset_path, reference.prim_path,
&layer, &src_ps, /* error_when_no_prims_found */true, options.error_when_asset_not_found,
options.error_when_unsupported_fileformat, warn, err)) {
PUSH_ERROR_AND_RETURN(
Expand Down Expand Up @@ -491,7 +498,7 @@ bool CompositeReferencesRec(uint32_t depth, AssetResolutionResolver &resolver,
Layer layer;
const PrimSpec *src_ps{nullptr};

if (!LoadAsset(resolver, reference.asset_path, reference.prim_path,
if (!LoadAsset(resolver, options.fileformats, reference.asset_path, reference.prim_path,
&layer, &src_ps, /* error_when_no_prims */true, options.error_when_asset_not_found,
options.error_when_unsupported_fileformat, warn, err)) {
PUSH_ERROR_AND_RETURN(
Expand Down Expand Up @@ -559,7 +566,7 @@ bool CompositePayloadRec(uint32_t depth, AssetResolutionResolver &resolver,

Layer layer;
const PrimSpec *src_ps{nullptr};
if (!LoadAsset(resolver, pl.asset_path, pl.prim_path,
if (!LoadAsset(resolver, options.fileformats, pl.asset_path, pl.prim_path,
&layer, &src_ps, /* error_when_no_prims_found */true, options.error_when_asset_not_found,
options.error_when_unsupported_fileformat, warn, err)) {
PUSH_ERROR_AND_RETURN(
Expand Down Expand Up @@ -609,7 +616,7 @@ bool CompositePayloadRec(uint32_t depth, AssetResolutionResolver &resolver,

Layer layer;
const PrimSpec *src_ps{nullptr};
if (!LoadAsset(resolver, pl.asset_path, pl.prim_path,
if (!LoadAsset(resolver, options.fileformats, pl.asset_path, pl.prim_path,
&layer, &src_ps, /* error_when_no_prims_found */true, options.error_when_asset_not_found,
options.error_when_unsupported_fileformat, warn, err)) {
PUSH_ERROR_AND_RETURN(
Expand Down
9 changes: 9 additions & 0 deletions src/composition.hh
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ struct SublayersCompositionOptions {

// Make an error when referenced asset is unsupported(e.g. unknown file extension)
bool error_when_unsupported_fileformat{false};

// File formats
std::map<std::string, FileFormatHandler> fileformats;
};

struct ReferencesCompositionOptions {
Expand All @@ -53,6 +56,9 @@ struct ReferencesCompositionOptions {

// Make an error when referenced asset is unsupported(e.g. unknown file extension)
bool error_when_unsupported_fileformat{false};

// File formats
std::map<std::string, FileFormatHandler> fileformats;
};

struct PayloadCompositionOptions {
Expand All @@ -64,6 +70,9 @@ struct PayloadCompositionOptions {

// Make an error when referenced asset is unsupported(e.g. unknown file extension)
bool error_when_unsupported_fileformat{false};

// File formats
std::map<std::string, FileFormatHandler> fileformats;
};

///
Expand Down
78 changes: 49 additions & 29 deletions src/prim-types.hh
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ struct AssetInfo {
Dictionary _fields;
};


// USDZ AR class?
// Preliminary_Trigger,
// Preliminary_PhysicsGravitationalForce,
Expand Down Expand Up @@ -3586,41 +3587,60 @@ struct Layer {
mutable bool _has_class_primspec{true};
};

#if 0 // TODO: Remove
// Simple bidirectional Path(string) <-> index lookup
struct StringAndIdMap {
void add(int32_t key, const std::string &val) {
_i_to_s[key] = val;
_s_to_i[val] = key;
}

void add(const std::string &key, int32_t val) {
_s_to_i[key] = val;
_i_to_s[val] = key;
}

size_t count(int32_t i) const { return _i_to_s.count(i); }
//
// Fileformat plugin(callback) interface.
// For fileformat which is `reference`ed or `payload`ed.
//
// TinyUSDZ uses C++ callback interface for security.
// (On the contrary, pxrUSD uses `plugInfo.json` + dll).
//
// Texture image/Shader file(e.g. glsl) is not handled in this API.
// (Plese refer T.B.D. for texture/shader)
//
// TODO: Move to another header file?

size_t count(const std::string &s) const { return _s_to_i.count(s); }
// Check if assetInfo is a valid asset(file)
//
// @param[in] asset Asset path(asset path is resolved by AssetResolutionResolver)
// @param[out] warn Warning message
// @param[out] err Error message(when the fuction returns false)
// @param[inout] user_data Userdata. can be nullptr.
// @return true when the given asset is valid.
typedef bool (*FileFormatCheckFunction)(const AssetInfo &asset, std::string *warn, std::string *err, void *user_data);

std::string at(int32_t i) const { return _i_to_s.at(i); }

int32_t at(std::string s) const { return _s_to_i.at(s); }
// Read content of asset into PrimSpec(metadatum, properties, primChildren/variantChildren).
//
// Check if assetInfo is a valid asset(file)
// @param[in] asset Asset path(asset path is resolved by AssetResolutionResolver)
// @param[inout] ps PrimSpec which references/payload this asset.
// @param[out] warn Warning message
// @param[out] err Error message(when the fuction returns false)
// @param[inout] user_data Userdata. can be nullptr.
// @return true when the given asset is valid.
typedef bool (*FileFormatReadFunction)(const AssetInfo &asset, PrimSpec &ps/* inout */, std::string *warn, std::string *err, void *user_data);

// Write corresponding content of PrimSpec to an asset(file)
//
// @param[in] asset Asset path(asset path is resolved by AssetResolutionResolver)
// @param[inout] ps PrimSpec which refers this asset.
// @param[out] warn Warning message
// @param[out] err Error message(when the fuction returns false)
// @param[inout] user_data Userdata. can be nullptr.
// @return true when the given asset is valid.
typedef bool (*FileFormatWriteFunction)(const AssetInfo &asset, const PrimSpec &ps, std::string *err, void *user_data);

struct FileFormatHandler
{
std::string extension; // fileformat extension.
std::string description; // Description of this fileformat. can be empty.

std::map<int32_t, std::string> _i_to_s; // index -> string
std::map<std::string, int32_t> _s_to_i; // string -> index
FileFormatCheckFunction checker{nullptr};
FileFormatReadFunction reader{nullptr};
FileFormatWriteFunction writer{nullptr};
void *userdata{nullptr};
};

struct NodeIndex {
std::string name;

// TypeTraits<T>::type_id
value::TypeId type_id{value::TypeId::TYPE_ID_INVALID};

int64_t index{-1}; // array index to `Scene::xforms`, `Scene::geom_cameras`,
// ... -1 = invlid(or not set)
};
#endif

nonstd::optional<Interpolation> InterpolationFromString(const std::string &v);
nonstd::optional<Orientation> OrientationFromString(const std::string &v);
Expand Down
52 changes: 0 additions & 52 deletions src/tinyusdz.hh
Original file line number Diff line number Diff line change
Expand Up @@ -49,58 +49,6 @@ constexpr int version_minor = 8;
constexpr int version_micro = 0;
constexpr auto version_rev = "rc5"; // extra revision suffix

//
// Fileformat plugin(callback) interface.
// For fileformat which is `reference`ed or `payload`ed.
//
// TinyUSDZ uses C++ callback interface for security.
// (On the contrary, pxrUSD uses `plugInfo.json` + dll).
//
// Texture image/Shader file(e.g. glsl) is not handled in this API.
// (Plese refer T.B.D. for texture/shader)

// Check if assetInfo is a valid asset(file)
//
// @param[in] asset Asset path(asset path is resolved by AssetResolutionResolver)
// @param[out] warn Warning message
// @param[out] err Error message(when the fuction returns false)
// @param[inout] user_data Userdata. can be nullptr.
// @return true when the given asset is valid.
typedef bool (*FileFormatCheckFunction)(const AssetInfo &asset, std::string *warn, std::string *err, void *user_data);


// Read content of asset into PrimSpec(metadatum, properties, primChildren/variantChildren).
//
// Check if assetInfo is a valid asset(file)
// @param[in] asset Asset path(asset path is resolved by AssetResolutionResolver)
// @param[inout] ps PrimSpec which references/payload this asset.
// @param[out] warn Warning message
// @param[out] err Error message(when the fuction returns false)
// @param[inout] user_data Userdata. can be nullptr.
// @return true when the given asset is valid.
typedef bool (*FileFormatReadFunction)(const AssetInfo &asset, PrimSpec &ps/* inout */, std::string *warn, std::string *err, void *user_data);

// Write corresponding content of PrimSpec to an asset(file)
//
// @param[in] asset Asset path(asset path is resolved by AssetResolutionResolver)
// @param[inout] ps PrimSpec which refers this asset.
// @param[out] warn Warning message
// @param[out] err Error message(when the fuction returns false)
// @param[inout] user_data Userdata. can be nullptr.
// @return true when the given asset is valid.
typedef bool (*FileFormatWriteFunction)(const AssetInfo &asset, const PrimSpec &ps, std::string *err, void *user_data);

struct FileFormatHandler
{
std::string extension; // fileformat extension.
std::string description; // Description of this fileformat. can be empty.

FileFormatCheckFunction checker{nullptr};
FileFormatReadFunction reader{nullptr};
FileFormatWriteFunction writer{nullptr};
void *userdata{nullptr};
};

struct USDLoadOptions {
///
/// Set the number of threads to use when parsing USD scene.
Expand Down

0 comments on commit 199d6f4

Please sign in to comment.