Skip to content

Commit

Permalink
save some state for AssetResolution to Layer and PrimSpec.
Browse files Browse the repository at this point in the history
  • Loading branch information
syoyo committed Oct 28, 2023
1 parent fe8af50 commit ecfacac
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 13 deletions.
16 changes: 16 additions & 0 deletions src/asset-resolution.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,17 @@ bool AssetResolutionResolver::find(const std::string &assetPath) const {
}
}


// TODO: Only find when input path is relative.
std::string rpath = io::FindFile(assetPath, {_current_working_path});
if (rpath.size()) {
return true;
}

// TODO: Cache resolition.
std::string fpath = io::FindFile(assetPath, _search_paths);
return fpath.size();

}

std::string AssetResolutionResolver::resolve(
Expand Down Expand Up @@ -88,8 +96,16 @@ std::string AssetResolutionResolver::resolve(
}
}

DCOUT("cwd = " << _current_working_path);
DCOUT("search_paths = " << _search_paths);
DCOUT("assetPath = " << assetPath);

// TODO: Only find when input path is relative.
std::string rpath = io::FindFile(assetPath, {_current_working_path});
if (rpath.size()) {
return rpath;
}

// TODO: Cache resolition.
return io::FindFile(assetPath, _search_paths);
}
Expand Down
14 changes: 13 additions & 1 deletion src/asset-resolution.hh
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,21 @@ class AssetResolutionResolver {
_search_paths = paths;
}

void add_seartch_path(const std::string &path) {
void add_search_path(const std::string &path) {
_search_paths.push_back(path);
}

//
// Asset is first seeked from the current working path(directory) when the Asset's path is a relative path.
//
void set_current_working_path(const std::string &cwp) {
_current_working_path = cwp;
}

const std::string &current_working_path_str() const {
return _current_working_path;
}

const std::vector<std::string> &search_paths() const { return _search_paths; }

std::string search_paths_str() const;
Expand Down Expand Up @@ -278,6 +289,7 @@ class AssetResolutionResolver {
private:
//ResolvePathHandler _resolve_path_handler{nullptr};
void *_userdata{nullptr};
std::string _current_working_path{"./"};
std::vector<std::string> _search_paths;
mutable size_t _max_asset_bytes_in_mb{1024*1024}; // default 1 TB

Expand Down
50 changes: 38 additions & 12 deletions src/composition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ bool IsBuiltinFileFormat(const std::string &name) {

// TODO: support loading non-USD asset
bool LoadAsset(AssetResolutionResolver &resolver,
const std::vector<std::string> &search_paths,
const std::map<std::string, FileFormatHandler> &fileformats,
const value::AssetPath &assetPath, const Path &primPath,
Layer *dst_layer, const PrimSpec **dst_primspec_root,
Expand Down Expand Up @@ -169,11 +170,16 @@ bool LoadAsset(AssetResolutionResolver &resolver,
}
}

resolver.set_search_paths(search_paths);

// Use resolved asset_path's basedir for current working path.
// Add resolved asset_path's basedir to search path.
std::string base_dir = io::GetBaseDir(resolved_path);
if (base_dir.size()) {
DCOUT(fmt::format("Add {} to asset search path.", base_dir));
resolver.add_seartch_path(base_dir);
DCOUT(fmt::format("Set `{}' to current working path.", base_dir));
DCOUT(fmt::format("Add `{}' to asset search path.", base_dir));
resolver.set_current_working_path(base_dir);
resolver.add_search_path(base_dir);
}

Asset asset;
Expand Down Expand Up @@ -295,18 +301,20 @@ bool LoadAsset(AssetResolutionResolver &resolver,
std::string default_prim;
if (primPath.is_valid()) {
default_prim = primPath.prim_part();
DCOUT("primPath = " << default_prim);
} else {
// Use `defaultPrim` metadatum
if (layer.metas().defaultPrim.valid()) {
default_prim = "/" + layer.metas().defaultPrim.str();
DCOUT("layer.meta.defaultPrim = " << default_prim);
} else {
// Use the first Prim in the layer.
default_prim = "/" + layer.primspecs().begin()->first;
DCOUT("layer.primspecs[0].name = " << default_prim);
}
}

if (!layer.find_primspec_at(Path(default_prim, ""), &src_ps, err)) {
DCOUT("layer = " << to_string(layer));
PUSH_ERROR_AND_RETURN(
fmt::format("Failed to find PrimSpec `{}` in layer `{}`(resolved path: `{}`)", default_prim,
asset_path, resolved_path));
Expand All @@ -319,6 +327,13 @@ bool LoadAsset(AssetResolutionResolver &resolver,
(*dst_primspec_root) = src_ps;
}

// save assetresolution state for nested composition.
layer.set_asset_resolution_state(
resolver.current_working_path_str(),
resolver.search_paths(),
resolver.get_userdata()
);

(*dst_layer) = std::move(layer);

return true;
Expand Down Expand Up @@ -362,7 +377,7 @@ bool CompositeSublayersRec(AssetResolutionResolver &resolver,
}

tinyusdz::Layer sublayer;
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)) {
if (!LoadAsset(resolver, in_layer.get_asset_search_paths(), 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 @@ -483,6 +498,7 @@ bool CompositeSublayers(AssetResolutionResolver &resolver,
namespace {

bool CompositeReferencesRec(uint32_t depth, AssetResolutionResolver &resolver,
const std::vector<std::string> &asset_search_paths,
PrimSpec &primspec /* [inout] */, std::string *warn,
std::string *err,
const ReferencesCompositionOptions &options) {
Expand All @@ -492,7 +508,7 @@ bool CompositeReferencesRec(uint32_t depth, AssetResolutionResolver &resolver,

// Traverse children first.
for (auto &child : primspec.children()) {
if (!CompositeReferencesRec(depth + 1, resolver, child, warn, err,
if (!CompositeReferencesRec(depth + 1, resolver, asset_search_paths, child, warn, err,
options)) {
return false;
}
Expand All @@ -508,7 +524,8 @@ bool CompositeReferencesRec(uint32_t depth, AssetResolutionResolver &resolver,
Layer layer;
const PrimSpec *src_ps{nullptr};

if (!LoadAsset(resolver, options.fileformats, reference.asset_path, reference.prim_path,
DCOUT("reference.prim_path = " << reference.prim_path);
if (!LoadAsset(resolver, asset_search_paths, 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 @@ -552,7 +569,7 @@ bool CompositeReferencesRec(uint32_t depth, AssetResolutionResolver &resolver,
Layer layer;
const PrimSpec *src_ps{nullptr};

if (!LoadAsset(resolver, options.fileformats, reference.asset_path, reference.prim_path,
if (!LoadAsset(resolver, asset_search_paths, 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 @@ -590,6 +607,7 @@ bool CompositeReferencesRec(uint32_t depth, AssetResolutionResolver &resolver,
}

bool CompositePayloadRec(uint32_t depth, AssetResolutionResolver &resolver,
const std::vector<std::string> &asset_search_paths,
PrimSpec &primspec /* [inout] */, std::string *warn,
std::string *err,
const PayloadCompositionOptions &options) {
Expand All @@ -599,7 +617,7 @@ bool CompositePayloadRec(uint32_t depth, AssetResolutionResolver &resolver,

// Traverse children first.
for (auto &child : primspec.children()) {
if (!CompositePayloadRec(depth + 1, resolver, child, warn, err, options)) {
if (!CompositePayloadRec(depth + 1, resolver, asset_search_paths, child, warn, err, options)) {
return false;
}
}
Expand All @@ -620,7 +638,7 @@ bool CompositePayloadRec(uint32_t depth, AssetResolutionResolver &resolver,

Layer layer;
const PrimSpec *src_ps{nullptr};
if (!LoadAsset(resolver, options.fileformats, pl.asset_path, pl.prim_path,
if (!LoadAsset(resolver, asset_search_paths, 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 @@ -670,7 +688,7 @@ bool CompositePayloadRec(uint32_t depth, AssetResolutionResolver &resolver,

Layer layer;
const PrimSpec *src_ps{nullptr};
if (!LoadAsset(resolver, options.fileformats, pl.asset_path, pl.prim_path,
if (!LoadAsset(resolver, asset_search_paths, 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 @@ -812,10 +830,12 @@ bool CompositeReferences(AssetResolutionResolver &resolver,
return false;
}

std::vector<std::string> search_paths = in_layer.get_asset_search_paths();

Layer dst = in_layer; // deep copy

for (auto &item : dst.primspecs()) {
if (!CompositeReferencesRec(/* depth */ 0, resolver, item.second, warn, err,
if (!CompositeReferencesRec(/* depth */ 0, resolver, search_paths, item.second, warn, err,
options)) {
PUSH_ERROR_AND_RETURN("Composite `references` failed.");
}
Expand All @@ -834,10 +854,12 @@ bool CompositePayload(AssetResolutionResolver &resolver, const Layer &in_layer,
return false;
}

std::vector<std::string> search_paths = in_layer.get_asset_search_paths();;

Layer dst = in_layer; // deep copy

for (auto &item : dst.primspecs()) {
if (!CompositePayloadRec(/* depth */ 0, resolver, item.second, warn, err,
if (!CompositePayloadRec(/* depth */ 0, resolver, search_paths, item.second, warn, err,
options)) {
PUSH_ERROR_AND_RETURN("Composite `payload` failed.");
}
Expand Down Expand Up @@ -1116,6 +1138,7 @@ bool InheritPrimSpec(PrimSpec &dst, const PrimSpec &src, std::string *warn,
return detail::InheritPrimSpecImpl(dst, src, warn, err);
}

#if 0
bool ReferenceLayerToPrimSpec(PrimSpec &dst, const Layer &layer,
const Path primPath,
const LayerOffset layerOffset) {
Expand Down Expand Up @@ -1143,7 +1166,9 @@ bool ReferenceLayerToPrimSpec(PrimSpec &dst, const Layer &layer,

return false;
}
#endif

#if 0
bool HasReferences(const Layer &layer, const bool force_check,
const ReferencesCompositionOptions options) {
if (!force_check) {
Expand Down Expand Up @@ -1171,6 +1196,7 @@ bool HasOver(const Layer &layer) { return layer.check_over_primspec(); }
bool HasSpecializes(const Layer &layer) {
return layer.check_unresolved_specializes();
}
#endif

namespace {

Expand Down
68 changes: 68 additions & 0 deletions src/prim-types.hh
Original file line number Diff line number Diff line change
Expand Up @@ -3252,6 +3252,28 @@ class PrimSpec {
return _properties;
}

const std::string &get_current_working_path() const {
return _current_working_path;
}

const std::vector<std::string> &get_asset_search_paths() const {
return _asset_search_paths;
}

void set_current_working_path(const std::string &s) {
_current_working_path = s;
}

void set_asset_search_paths(const std::vector<std::string> &search_paths) {
_asset_search_paths = search_paths;
}

void set_asset_resolution_state(
const std::string &cwp, const std::vector<std::string> &search_paths) {
_current_working_path = cwp;
_asset_search_paths = search_paths;
}

private:
void CopyFrom(const PrimSpec &rhs) {
_specifier = rhs._specifier;
Expand All @@ -3272,6 +3294,9 @@ class PrimSpec {
_variantChildren = rhs._variantChildren;

_metas = rhs._metas;

_current_working_path = rhs._current_working_path;
_asset_search_paths = rhs._asset_search_paths;
}

void MoveFrom(PrimSpec &rhs) {
Expand All @@ -3293,6 +3318,9 @@ class PrimSpec {
_variantChildren = rhs._variantChildren;

_metas = std::move(rhs._metas);

_current_working_path = rhs._current_working_path;
_asset_search_paths = rhs._asset_search_paths;
}

Specifier _specifier{Specifier::Def};
Expand Down Expand Up @@ -3321,6 +3349,15 @@ class PrimSpec {
std::vector<value::token> _variantChildren;

PrimMeta _metas;

///
/// For solving asset path in nested composition.
/// Keep asset resolution state.
/// TODO: Use struct. Store userdata pointer.
///
std::string _current_working_path{"./"};
std::vector<std::string> _asset_search_paths;

};

struct SubLayer
Expand Down Expand Up @@ -3576,6 +3613,28 @@ struct Layer {
///
bool find_primspec_at(const Path &path, const PrimSpec **ps, std::string *err) const;


///
/// Set state for AssetResolution in the subsequent composition operation.
///
void set_asset_resolution_state(
const std::string &cwp, const std::vector<std::string> &search_paths, void *userdata=nullptr) {
_current_working_path = cwp;
_asset_search_paths = search_paths;
_asset_resolution_userdata = userdata;
}

void get_asset_resolution_state(
std::string &cwp, std::vector<std::string> &search_paths, void *&userdata) {
cwp = _current_working_path;
search_paths = _asset_search_paths;
userdata = _asset_resolution_userdata;
}

const std::vector<std::string> get_asset_search_paths() const {
return _asset_search_paths;
}

private:
std::string _name; // layer name ~= USD filename

Expand All @@ -3601,6 +3660,15 @@ struct Layer {
mutable bool _has_unresolved_specializes{true};
mutable bool _has_over_primspec{true};
mutable bool _has_class_primspec{true};

//
// Record AssetResolution state(search paths, current working directory)
// when this layer is opened by compostion(`references`, `payload`, `subLayers`)
//
mutable std::string _current_working_path{"./"};
mutable std::vector<std::string> _asset_search_paths;
mutable void *_asset_resolution_userdata{nullptr};

};


Expand Down

0 comments on commit ecfacac

Please sign in to comment.