diff --git a/CMakeLists.txt b/CMakeLists.txt index a35425ab..d12e1119 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -787,7 +787,7 @@ endif() if(TINYUSDZ_BUILD_EXAMPLES) add_subdirectory(examples/simple_usdz_dump) - add_subdirectory(examples/tydra_convert) + add_subdirectory(examples/tydra_api) add_subdirectory(examples/api_tutorial) if(TINYUSDZ_WITH_MODULE_USDA_WRITER) add_subdirectory(examples/save_usda) diff --git a/examples/tydra_convert/CMakeLists.txt b/examples/tydra_api/CMakeLists.txt similarity index 86% rename from examples/tydra_convert/CMakeLists.txt rename to examples/tydra_api/CMakeLists.txt index 21322052..9097cdb4 100644 --- a/examples/tydra_convert/CMakeLists.txt +++ b/examples/tydra_api/CMakeLists.txt @@ -1,8 +1,8 @@ # Assume this cmake is called from tinyusdz root(../../) -set(EXAMPLE_TARGET "tydra_convert_example") +set(EXAMPLE_TARGET "tydra_api") set(TINYUSDZ_TYDRA_CONVERT_SOURCES - tydra-convert-main.cc + tydra-api-main.cc ) add_executable(${EXAMPLE_TARGET} ${TINYUSDZ_TYDRA_CONVERT_SOURCES}) diff --git a/examples/tydra_api/README.md b/examples/tydra_api/README.md new file mode 100644 index 00000000..9415fac2 --- /dev/null +++ b/examples/tydra_api/README.md @@ -0,0 +1,9 @@ +# Command line Tydra(Scene/Render delegate) API usage example + +Read USD and call Tydta APIs + +## Status + +Work-in-progress + + diff --git a/examples/tydra_convert/tydra-convert-main.cc b/examples/tydra_api/tydra-api-main.cc similarity index 93% rename from examples/tydra_convert/tydra-convert-main.cc rename to examples/tydra_api/tydra-api-main.cc index a681764c..5bf75528 100644 --- a/examples/tydra_convert/tydra-convert-main.cc +++ b/examples/tydra_api/tydra-api-main.cc @@ -5,6 +5,7 @@ #include "tinyusdz.hh" #include "tydra/render-data.hh" #include "tydra/scene-access.hh" +#include "tydra/shader-network.hh" #include "usdShade.hh" #include "pprinter.hh" #include "prim-pprint.hh" @@ -337,11 +338,35 @@ int main(int argc, char **argv) { } } - std::cout << "EvaluateAttribute example -------------\n"; + + // + // Find bound Material + // + std::cout << "FindBoundMaterial example -------------\n"; + for (const auto &item : meshmap) { + // FindBoundMaterial seaches bound material for parent GPrim. + tinyusdz::Path matPath; + const tinyusdz::Material *material{nullptr}; + std::string err; + bool ret = tinyusdz::tydra::FindBoundMaterial(stage, tinyusdz::Path(item.first, ""), /* suffix */"", &matPath, &material, &err); + + if (ret) { + std::cout << item.first << " has bound Material. Material Path = " << matPath << "\n"; + std::cout << "mat = " << material << "\n"; + if (material) { + std::cout << to_string(*material, /* indent */1) << "\n"; + } + } else { + std::cout << "Bound material not found for Prim path : " << item.first << "\n"; + } + } + + // // Shader attribute evaluation example. // + std::cout << "EvaluateAttribute example -------------\n"; for (const auto &item : preadermap) { // Returned Prim is Shader class nonstd::expected shader = stage.GetPrimAtPath(tinyusdz::Path(item.first, /* prop name */"")); @@ -375,5 +400,6 @@ int main(int argc, char **argv) { } + return 0; } diff --git a/examples/tydra_convert/README.md b/examples/tydra_convert/README.md deleted file mode 100644 index 902ca567..00000000 --- a/examples/tydra_convert/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Command line Tydra(Scene/Render delegate) example - -Read USD and convert to renderer-friendly data structure. - -## Status - -Work-in-progress - - diff --git a/src/prim-reconstruct.cc b/src/prim-reconstruct.cc index f65be13e..6f1e7bd4 100644 --- a/src/prim-reconstruct.cc +++ b/src/prim-reconstruct.cc @@ -1441,6 +1441,15 @@ static nonstd::expected PurposeEnumHandler(const std::stri return EnumHandler("purpose", tok, enums); }; +static nonstd::expected OrientationEnumHandler(const std::string &tok) { + using EnumTy = std::pair; + const std::vector enums = { + std::make_pair(Orientation::RightHanded, "rightHanded"), + std::make_pair(Orientation::LeftHanded, "leftHanded"), + }; + return EnumHandler("orientation", tok, enums); +}; + #if 0 // Animatable enum template @@ -1938,7 +1947,7 @@ bool ReconstructXformOpsFromProperties( template <> -bool ReconstructPrim( +bool ReconstructPrim( const PropertyMap &properties, const ReferenceList &references, Xform *xform, @@ -1954,6 +1963,15 @@ bool ReconstructPrim( } for (const auto &prop : properties) { + PARSE_SINGLE_TARGET_PATH_RELATION(table, prop, kMaterialBinding, xform->materialBinding) + PARSE_SINGLE_TARGET_PATH_RELATION(table, prop, kProxyPrim, xform->proxyPrim) + PARSE_ENUM_PROPETY(table, prop, "visibility", VisibilityEnumHandler, Xform, + xform->visibility) + PARSE_ENUM_PROPETY(table, prop, "purpose", PurposeEnumHandler, Xform, + xform->purpose) + PARSE_ENUM_PROPETY(table, prop, "orientation", OrientationEnumHandler, Xform, + xform->orientation) + PARSE_EXTENT_ATTRIBUTE(table, prop, "extent", Xform, xform->extent) ADD_PROPERTY(table, prop, Xform, xform->props) PARSE_PROPERTY_END_MAKE_WARN(table, prop) } @@ -2956,6 +2974,8 @@ bool ReconstructPrim( mesh->faceVaryingLinearInterpolation) PARSE_ENUM_PROPETY(table, prop, "purpose", PurposeEnumHandler, GeomMesh, mesh->purpose) + PARSE_ENUM_PROPETY(table, prop, "orientation", OrientationEnumHandler, GeomMesh, + mesh->orientation) PARSE_EXTENT_ATTRIBUTE(table, prop, "extent", GeomMesh, mesh->extent) // blendShape names PARSE_TYPED_ATTRIBUTE(table, prop, kSkelBlendShapes, GeomMesh, mesh->blendShapes) @@ -3060,6 +3080,8 @@ bool ReconstructPrim( camera->stereoRole) PARSE_ENUM_PROPETY(table, prop, "purpose", PurposeEnumHandler, GeomCamera, camera->purpose) + PARSE_ENUM_PROPETY(table, prop, "orientation", OrientationEnumHandler, GeomCamera, + camera->orientation) PARSE_EXTENT_ATTRIBUTE(table, prop, "extent", GeomCamera, camera->extent) ADD_PROPERTY(table, prop, GeomCamera, camera->props) PARSE_PROPERTY_END_MAKE_ERROR(table, prop) diff --git a/src/stage.cc b/src/stage.cc index d8083a4f..1a34f98e 100644 --- a/src/stage.cc +++ b/src/stage.cc @@ -177,10 +177,11 @@ nonstd::optional GetPrimAtPathRec(const Prim *parent, nonstd::expected Stage::GetPrimAtPath( const Path &path) const { - DCOUT("GerPrimAtPath : " << path.prim_part() << "(input path: " << path + DCOUT("GetPrimAtPath : " << path.prim_part() << "(input path: " << path << ")"); if (_dirty) { + DCOUT("clear cache."); // Clear cache. _prim_path_cache.clear(); @@ -189,20 +190,24 @@ nonstd::expected Stage::GetPrimAtPath( // First find from a cache. auto ret = _prim_path_cache.find(path.prim_part()); if (ret != _prim_path_cache.end()) { + DCOUT("Found cache."); return ret->second; } } if (!path.is_valid()) { + DCOUT("Invalid path."); return nonstd::make_unexpected("Path is invalid.\n"); } if (path.is_relative_path()) { + DCOUT("Relative path is todo."); // TODO: return nonstd::make_unexpected("Relative path is TODO.\n"); } if (!path.is_absolute_path()) { + DCOUT("Not absolute path."); return nonstd::make_unexpected( "Path is not absolute. Non-absolute Path is TODO.\n"); } @@ -218,6 +223,7 @@ nonstd::expected Stage::GetPrimAtPath( } } + DCOUT("Not found."); return nonstd::make_unexpected("Cannot find path <" + path.full_path_name() + "> int the Stage.\n"); } diff --git a/src/tydra/shader-network.cc b/src/tydra/shader-network.cc index fa94cffd..50984c5d 100644 --- a/src/tydra/shader-network.cc +++ b/src/tydra/shader-network.cc @@ -7,6 +7,7 @@ #include "prim-pprint.hh" #include "value-pprint.hh" #include "stage.hh" +#include "common-macros.inc" namespace tinyusdz { namespace tydra { @@ -158,7 +159,7 @@ bool GetBoundMaterial( const Stage &_stage, const Prim &prim, const std::string &suffix, - tinyusdz::Path *materialPath, + tinyusdz::Path *materialPath, const Material **material, std::string *err) { @@ -167,7 +168,7 @@ bool GetBoundMaterial( } (void)err; - + auto apply_fun = [&](const Stage &stage, const GPrim *gprim) -> bool { if (suffix.empty()) { if (gprim->materialBinding.has_value()) { @@ -181,7 +182,7 @@ bool GetBoundMaterial( (*material) = nullptr; } } - + return true; } } @@ -197,7 +198,7 @@ bool GetBoundMaterial( (*material) = nullptr; } } - + return true; } } @@ -213,13 +214,13 @@ bool GetBoundMaterial( (*material) = nullptr; } } - + return true; } } } else { return false; - } + } return false; }; @@ -233,7 +234,7 @@ bool FindBoundMaterial( const Stage &_stage, const Path &abs_path, const std::string &suffix, - tinyusdz::Path *materialPath, + tinyusdz::Path *materialPath, const Material **material, std::string *err) { @@ -252,18 +253,22 @@ bool FindBoundMaterial( if (suffix.empty()) { if (gprim->materialBinding.has_value()) { if (GetSinglePath(gprim->materialBinding.value(), materialPath)) { - + DCOUT("GPrim has materialBinding."); const Prim *p; if (stage.find_prim_at_path(*materialPath, p, err)) { + DCOUT("material = " << material); if (p->is() && (material != nullptr)) { + DCOUT("Store mat."); (*material) = p->as(); } else { + DCOUT("nullmat."); (*material) = nullptr; } } - return true; } + } else { + DCOUT("GPrim has no materialBinding."); } } else if (suffix == "correction") { if (gprim->materialBindingCorrection.has_value()) { @@ -277,7 +282,7 @@ bool FindBoundMaterial( (*material) = nullptr; } } - + return true; } } @@ -293,13 +298,13 @@ bool FindBoundMaterial( (*material) = nullptr; } } - + return true; } } } else { return false; - } + } return false; }; @@ -313,6 +318,7 @@ bool FindBoundMaterial( int depth = 0; while (depth < 1024*1024*128) { // to avoid infinite loop. Path parentPath = abs_path.get_parent_prim_path(); + DCOUT("search parent: " << parentPath.full_path_name()); if (parentPath.is_valid() && (!parentPath.is_root_path())) { ret = _stage.find_prim_at_path(parentPath, prim, err); @@ -321,6 +327,9 @@ bool FindBoundMaterial( } ret = ApplyToGPrim(_stage, *prim, apply_fun); + if (ret) { + return true; + } } else { return false; diff --git a/tests/usda/material-binding-002.usda b/tests/usda/material-binding-002.usda new file mode 100644 index 00000000..ac09bcc8 --- /dev/null +++ b/tests/usda/material-binding-002.usda @@ -0,0 +1,11 @@ +#usda 1.0 + +def Xform "geom" +{ + # common material + rel material:binding = + + def Mesh "mymesh" + { + } +}