Skip to content

Commit

Permalink
W.I.P.
Browse files Browse the repository at this point in the history
  • Loading branch information
syoyo committed Dec 4, 2023
1 parent d092358 commit 98f2d98
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 45 deletions.
34 changes: 25 additions & 9 deletions src/pprinter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1459,21 +1459,37 @@ std::string print_material_binding(const MaterialBinding *mb, const uint32_t ind
if (mb->materialBinding) {
ss << print_relationship(mb->materialBinding.value(),
mb->materialBinding.value().get_listedit_qual(),
/* custom */ false, "material:binding", indent);
}

if (mb->materialBindingCollection) {
ss << print_relationship(
mb->materialBindingCollection.value(),
mb->materialBindingCollection.value().get_listedit_qual(),
/* custom */ false, "material:binding:collection", indent);
/* custom */ false, kMaterialBinding, indent);
}

if (mb->materialBindingPreview) {
ss << print_relationship(
mb->materialBindingPreview.value(),
mb->materialBindingPreview.value().get_listedit_qual(),
/* custom */ false, "material:binding:preview", indent);
/* custom */ false, kMaterialBindingPreview, indent);
}

if (mb->materialBindingFull) {
ss << print_relationship(
mb->materialBindingFull.value(),
mb->materialBindingFull.value().get_listedit_qual(),
/* custom */ false, kMaterialBindingFull, indent);
}

// NOTE: matb does not include "material:binding", "material:binding:preview" and "material:binding:full"
for (const auto &matb : mb->materialBindingMap()) {
if (matb.first.empty()) {
// this should not happen
continue;
}

std::string matb_name = kMaterialBinding + std::string(":") + matb.first;

ss << print_relationship(
matb.second,
matb.second.get_listedit_qual(),
/* custom */ false, matb_name, indent);

}

for (const auto &collection : mb->materialBindingCollectionMap()) {
Expand Down
18 changes: 17 additions & 1 deletion src/prim-reconstruct.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2091,7 +2091,23 @@ bool ReconstructMaterialBindingProperties(
PARSE_SINGLE_TARGET_PATH_RELATION(table, prop, kMaterialBindingPreview, mb->materialBindingPreview)
PARSE_SINGLE_TARGET_PATH_RELATION(table, prop, kMaterialBindingPreview, mb->materialBindingFull)
// material:binding:collection
PARSE_SINGLE_TARGET_PATH_RELATION(table, prop, kMaterialBindingCollection, mb->materialBindingCollection)
if (prop.first == kMaterialBindingCollection) {

if (table.count(prop.first)) {
continue;
}

if (!prop.second.is_relationship()) {
PUSH_ERROR_AND_RETURN(fmt::format("`{}` must be a Relationship", prop.first));
}

const Relationship &rel = prop.second.get_relationship();

mb->set_materialBindingCollection(value::token(""), value::token(""), rel);

table.insert(prop.first);
continue;
}
// material:binding:collection[:PURPOSE]:NAME
if (startsWith(prop.first, kMaterialBindingCollection + std::string(":"))) {

Expand Down
83 changes: 83 additions & 0 deletions src/prim-types.hh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,89 @@

namespace tinyusdz {

// Simple Python-like OrderedDict
template <typename T>
class ordered_dict {
public:
bool at(const size_t idx, T *dst) const {
if (idx >= _keys.size()) {
return false;
}

if (!_m.count(_keys[idx])) {
// This should not happen though.
return false;
}

(*dst) = _m.at(_keys[idx]);

return true;
}

bool count(const std::string &key) const {
return _m.count(key);
}

void insert(const std::string &key, const T &value) {
if (_m.count(key)) {
// overwrite existing value
} else {
_keys.push_back(key);
}

_m[key] = value;
}

bool erase(const std::string &key) {

if (!_m.count(key)) {
return false;
}

// linear search
bool erased = false;
size_t idx = 0;
for (size_t i = 0; i < _keys.size(); i++) {
if (key == _keys[i]) {
idx = i;
erased = true;
}
}

if (!erased) {
return false;
}

_keys.erase(_keys.begin() + idx);
_m.erase(key);

return true;
}


bool at(const std::string &key, T *dst) const {
if (!_m.count(key)) {
// This should not happen though.
return false;
}

(*dst) = _m.at(key);

return true;
}

const std::vector<std::string> &keys() const {
return _keys;
}

size_t size() const { return _m.size(); }

private:
std::vector<std::string> _keys;
std::map<std::string, T> _m;
};


// SpecType enum must be same order with pxrUSD's SdfSpecType(since enum value
// is stored in Crate directly)
enum class SpecType {
Expand Down
54 changes: 19 additions & 35 deletions src/usdShade.hh
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,11 @@ class MaterialBinding {

// Some frequently used materialBindings
nonstd::optional<Relationship> materialBinding; // material:binding
nonstd::optional<Relationship> materialBindingCollection; // material:binding:collection TODO: deprecate?(seems `material:binding:collection` without leaf NAME seems ignored in pxrUSD.
nonstd::optional<Relationship> materialBindingPreview; // material:binding:preview
nonstd::optional<Relationship> materialBindingFull; // material:binding:full

//nonstd::optional<Relationship> materialBindingCollection; // material:binding:collection Deprecated. use _materialBindingCollectionMap[""][""] instead.

bool has_materialBinding() const {
return materialBinding.has_value();
}
Expand Down Expand Up @@ -181,7 +182,7 @@ class MaterialBinding {

auto &m = _materialBindingCollectionMap[tok.str()];

m[mat_purpose.str()] = rel;
m.insert(mat_purpose.str(), rel);
}

void clear_materialBindingCollection(const value::token &tok, const value::token &mat_purpose) {
Expand All @@ -193,12 +194,17 @@ class MaterialBinding {
void set_materialBindingCollection(const value::token &tok, const value::token &mat_purpose, const Relationship &rel, MaterialBindingStrength strength) {
value::token strength_tok(to_string(strength));

_materialBindingCollectionMap[tok.str()][mat_purpose.str()] = rel;
_materialBindingCollectionMap[tok.str()][mat_purpose.str()].metas().bindMaterialAs = strength_tok;
Relationship r = rel;
r.metas().bindMaterialAs = strength_tok;

_materialBindingCollectionMap[tok.str()].insert(mat_purpose.str(), r);
}

const std::map<std::string, Relationship> &materialBindingMap() const {
return _materialBindingMap;
}

const std::map<std::string, std::map<std::string, Relationship>> materialBindingCollectionMap() const {
const std::map<std::string, ordered_dict<Relationship>> &materialBindingCollectionMap() const {
return _materialBindingCollectionMap;
}

Expand Down Expand Up @@ -238,44 +244,22 @@ class MaterialBinding {
}
}

bool get_materialBindingCollection(const value::token &tok, const value::token &mat_purpose, Relationship *relOut) {
if (!relOut) {
return false;
}

if (tok.str().empty() && mat_purpose.str().empty()) {
if (materialBindingCollection.has_value()) {
(*relOut) = materialBindingCollection.value();
} else {
return false;
}
}

if (!_materialBindingCollectionMap.count(tok.str())) {
return false;
}

const auto &mbcMap = _materialBindingCollectionMap.at(tok.str());

if (!mbcMap.count(mat_purpose.str())) {
return false;
}

(*relOut) = mbcMap.at(mat_purpose.str());
return true;

}

private:

// For material:binding(excludes frequently used `material:binding`, `material:binding:full` and `material:binding:preview`)
// key = PURPOSE, value = rel
std::map<std::string, Relationship> _materialBindingMap;

// For material:binding:collection
// key = NAME, value = map<PURPOSE, Rel>
// Use ordered dict since the requests:
//
// https://openusd.org/release/wp_usdshade.html#basic-proposal-for-collection-based-assignment
//
// `...with the earliest ordered binding relationship the strongest`
//
// key = PURPOSE, value = map<NAME, Rel>
// TODO: Use multi-index map
std::map<std::string, std::map<std::string, Relationship>> _materialBindingCollectionMap;
std::map<std::string, ordered_dict<Relationship>> _materialBindingCollectionMap;
};

// TODO: Inherit from Prim?
Expand Down

0 comments on commit 98f2d98

Please sign in to comment.