mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
Remove unused displayColor, displayOpacity member variables in GPrim.
Fix SpecType enum ordering. Skip parsing unsupported specifier(`over`, `class`) Skip some composition arcs settings in USDC.
This commit is contained in:
@@ -109,6 +109,7 @@ option(TINYUSDZ_WITH_COLORIO
|
||||
|
||||
# -- optional tool --
|
||||
option(TINYUSDZ_WITH_TOOL_USDA_PARSER "Build with USDA parser program" ON)
|
||||
option(TINYUSDZ_WITH_TOOL_USDC_PARSER "Build with USDC parser program" ON)
|
||||
# --------------
|
||||
|
||||
# -- For developers --
|
||||
@@ -666,6 +667,14 @@ if(TINYUSDZ_WITH_TOOL_USDA_PARSER AND TINYUSDZ_WITH_MODULE_USDA_READER)
|
||||
target_link_libraries(usda_parser PRIVATE ${TINYUSDZ_TARGET_STATIC})
|
||||
endif()
|
||||
|
||||
if(TINYUSDZ_WITH_TOOL_USDC_PARSER AND TINYUSDZ_WITH_MODULE_USDC_READER)
|
||||
add_executable(
|
||||
usdc_parser ${CMAKE_CURRENT_SOURCE_DIR}/examples/usdc_parser/usdc-parser-main.cc)
|
||||
add_sanitizers(usdc_parser)
|
||||
target_include_directories(usdc_parser PRIVATE ${PROJECT_SOURCE_DIR}/src/)
|
||||
target_link_libraries(usdc_parser PRIVATE ${TINYUSDZ_TARGET_STATIC})
|
||||
endif()
|
||||
|
||||
if(TINYUSDZ_WITH_BLENDER_ADDON)
|
||||
pybind11_add_module(${BUILD_TARGET_BLENDER_PY}
|
||||
${TINYUSDZ_BLENDER_PYTHON_BINDING_SOURCES})
|
||||
|
||||
@@ -50,7 +50,21 @@ int main(int argc, char **argv) {
|
||||
std::cerr << "Failed to load USDC file: " << filepath << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else { // assume usdz
|
||||
} else if (ext.compare("usda") == 0) {
|
||||
bool ret = tinyusdz::LoadUSDAFromFile(filepath, &stage, &warn, &err);
|
||||
if (!warn.empty()) {
|
||||
std::cerr << "WARN : " << warn << "\n";
|
||||
}
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR : " << err << "\n";
|
||||
//return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
std::cerr << "Failed to load USDA file: " << filepath << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else if (ext.compare("usdz") == 0) {
|
||||
//std::cout << "usdz\n";
|
||||
bool ret = tinyusdz::LoadUSDZFromFile(filepath, &stage, &warn, &err);
|
||||
if (!warn.empty()) {
|
||||
@@ -65,6 +79,21 @@ int main(int argc, char **argv) {
|
||||
std::cerr << "Failed to load USDZ file: " << filepath << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} else {
|
||||
// try to auto detect format.
|
||||
bool ret = tinyusdz::LoadUSDFromFile(filepath, &stage, &warn, &err);
|
||||
if (!warn.empty()) {
|
||||
std::cerr << "WARN : " << warn << "\n";
|
||||
}
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR : " << err << "\n";
|
||||
//return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
std::cerr << "Failed to load USD file: " << filepath << "\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
std::string s = stage.ExportToString();
|
||||
|
||||
64
examples/usdc_parser/usdc-parser-main.cc
Normal file
64
examples/usdc_parser/usdc-parser-main.cc
Normal file
@@ -0,0 +1,64 @@
|
||||
// simple USDC parser
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "stream-reader.hh"
|
||||
#include "usdc-reader.hh"
|
||||
#include "io-util.hh"
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
std::cout << "Need input.usdc\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
std::string filename = argv[1];
|
||||
|
||||
//std::string base_dir;
|
||||
//base_dir = tinyusdz::io::GetBaseDir(filename);
|
||||
|
||||
if (!tinyusdz::IsUSDC(filename)) {
|
||||
std::cerr << "Input file isn't a USDC file.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
std::string err;
|
||||
if (!tinyusdz::io::ReadWholeFile(&data, &err, filename, /* filesize_max */0)) {
|
||||
std::cerr << "Failed to open file: " << filename << ":" << err << "\n";
|
||||
}
|
||||
|
||||
tinyusdz::StreamReader sr(data.data(), data.size(), /* swap endian */ false);
|
||||
tinyusdz::usdc::USDCReader reader(&sr);
|
||||
|
||||
//std::cout << "Basedir = " << base_dir << "\n";
|
||||
//reader.SetBaseDir(base_dir);
|
||||
|
||||
{
|
||||
bool ret = reader.ReadUSDC();
|
||||
|
||||
if (!ret) {
|
||||
std::cerr << "Failed to parse .usdc: \n";
|
||||
std::cerr << reader.GetError() << "\n";
|
||||
return -1;
|
||||
} else {
|
||||
std::cout << "ok\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Dump
|
||||
{
|
||||
tinyusdz::Stage stage;
|
||||
bool ret = reader.ReconstructStage(&stage);
|
||||
if (!ret) {
|
||||
std::cerr << "Failed to reconstruct Stage: \n";
|
||||
std::cerr << reader.GetError() << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cout << stage.ExportToString() << "\n";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -32,52 +32,23 @@ bool LoadModelFromString(const std::vector<uint8_t> &content,
|
||||
std::string warn;
|
||||
std::string err;
|
||||
|
||||
if (ext.compare("usdc") == 0) {
|
||||
bool ret = tinyusdz::LoadUSDCFromMemory(content.data(), content.size(), filename, stage, &warn, &err);
|
||||
if (!warn.empty()) {
|
||||
std::cerr << "WARN : " << warn << "\n";
|
||||
}
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR : " << err << "\n";
|
||||
}
|
||||
bool ret = tinyusdz::LoadUSDFromMemory(content.data(), content.size(), filename, stage, &warn, &err);
|
||||
if (!warn.empty()) {
|
||||
std::cerr << "WARN : " << warn << "\n";
|
||||
}
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR : " << err << "\n";
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
std::cerr << "Failed to load USDC file: " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
} else if (ext.compare("usda") == 0) {
|
||||
//std::cout << "usda\n";
|
||||
bool ret = tinyusdz::LoadUSDAFromMemory(content.data(), content.size(), filename, stage, &warn, &err);
|
||||
if (!warn.empty()) {
|
||||
std::cerr << "WARN : " << warn << "\n";
|
||||
}
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR : " << err << "\n";
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
std::cerr << "Failed to load USDA file: " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
} else { // assume usdz
|
||||
//std::cout << "usdz\n";
|
||||
bool ret = tinyusdz::LoadUSDZFromMemory(content.data(), content.size(), filename, stage, &warn, &err);
|
||||
if (!warn.empty()) {
|
||||
std::cerr << "WARN : " << warn << "\n";
|
||||
}
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR : " << err << "\n";
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
std::cerr << "Failed to load USDZ file: " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
if (!ret) {
|
||||
std::cerr << "Failed to load USD(USDA, USDC or USDZ) file: " << filename << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// It looks WASI does not provide fopen(), so use open() to read file content.
|
||||
std::vector<uint8_t> ReadFile(const char *arg) {
|
||||
std::ostringstream ss;
|
||||
@@ -108,18 +79,19 @@ std::vector<uint8_t> ReadFile(const char *arg) {
|
||||
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::cout << "bora\n";
|
||||
|
||||
if (argc > 1) {
|
||||
std::string filename = argv[1];
|
||||
#if 0
|
||||
#if 1
|
||||
tinyusdz::Stage stage;
|
||||
{
|
||||
std::string warn;
|
||||
std::string err;
|
||||
tinyusdz::Stage stage;
|
||||
bool ret = tinyusdz::LoadUSDZFromFile(filename, &stage, &warn, &err);
|
||||
bool ret = tinyusdz::LoadUSDFromFile(filename, &stage, &warn, &err);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cerr << "WARN : " << warn << "\n";
|
||||
@@ -132,18 +104,19 @@ int main(int argc, char **argv) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
std::vector<uint8_t> content = ReadFile(filename.c_str());
|
||||
if (content.empty()) {
|
||||
std::cerr << "File is empty or failed to read: " << filename << "\n";
|
||||
}
|
||||
#else
|
||||
//std::vector<uint8_t> content = ReadFile(filename.c_str());
|
||||
//if (content.empty()) {
|
||||
// std::cerr << "File is empty or failed to read: " << filename << "\n";
|
||||
//}
|
||||
|
||||
tinyusdz::Stage stage;
|
||||
bool ret = LoadModelFromString(content, filename, &stage);
|
||||
if (!ret) {
|
||||
std::cerr << "Load failed.\n";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
//tinyusdz::Stage stage;
|
||||
//bool ret = LoadModelFromString(content, filename, &stage);
|
||||
//if (!ret) {
|
||||
// std::cerr << "Load failed.\n";
|
||||
// return EXIT_FAILURE;
|
||||
//}
|
||||
#endif
|
||||
|
||||
std::cout << "Load oK\n";
|
||||
|
||||
|
||||
@@ -1026,6 +1026,118 @@ bool CrateReader::ReadTokenListOp(ListOp<value::token> *d) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CrateReader::ReadStringListOp(ListOp<std::string> *d) {
|
||||
// read ListOpHeader
|
||||
ListOpHeader h;
|
||||
if (!_sr->read1(&h.bits)) {
|
||||
_err += "Failed to read ListOpHeader\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (h.IsExplicit()) {
|
||||
d->ClearAndMakeExplicit();
|
||||
}
|
||||
|
||||
// array data is not compressed
|
||||
auto ReadFn = [this](std::vector<std::string> &result) -> bool {
|
||||
uint64_t n;
|
||||
if (!_sr->read8(&n)) {
|
||||
_err += "Failed to read # of elements in ListOp.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n > _config.maxArrayElements) {
|
||||
_err += "Too many ListOp elements.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECK_MEMORY_USAGE(size_t(n) * sizeof(crate::Index));
|
||||
|
||||
std::vector<crate::Index> ivalue(static_cast<size_t>(n));
|
||||
|
||||
if (!_sr->read(size_t(n) * sizeof(crate::Index),
|
||||
size_t(n) * sizeof(crate::Index),
|
||||
reinterpret_cast<uint8_t *>(ivalue.data()))) {
|
||||
_err += "Failed to read ListOp data.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// reconstruct
|
||||
result.resize(static_cast<size_t>(n));
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (auto v = GetStringToken(ivalue[i])) {
|
||||
result[i] = v.value().str();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (h.HasExplicitItems()) {
|
||||
std::vector<std::string> items;
|
||||
if (!ReadFn(items)) {
|
||||
_err += "Failed to read ListOp::ExplicitItems.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
d->SetExplicitItems(items);
|
||||
}
|
||||
|
||||
if (h.HasAddedItems()) {
|
||||
std::vector<std::string> items;
|
||||
if (!ReadFn(items)) {
|
||||
_err += "Failed to read ListOp::AddedItems.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
d->SetAddedItems(items);
|
||||
}
|
||||
|
||||
if (h.HasPrependedItems()) {
|
||||
std::vector<std::string> items;
|
||||
if (!ReadFn(items)) {
|
||||
_err += "Failed to read ListOp::PrependedItems.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
d->SetPrependedItems(items);
|
||||
}
|
||||
|
||||
if (h.HasAppendedItems()) {
|
||||
std::vector<std::string> items;
|
||||
if (!ReadFn(items)) {
|
||||
_err += "Failed to read ListOp::AppendedItems.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
d->SetAppendedItems(items);
|
||||
}
|
||||
|
||||
if (h.HasDeletedItems()) {
|
||||
std::vector<std::string> items;
|
||||
if (!ReadFn(items)) {
|
||||
_err += "Failed to read ListOp::DeletedItems.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
d->SetDeletedItems(items);
|
||||
}
|
||||
|
||||
if (h.HasOrderedItems()) {
|
||||
std::vector<std::string> items;
|
||||
if (!ReadFn(items)) {
|
||||
_err += "Failed to read ListOp::OrderedItems.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
d->SetOrderedItems(items);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CrateReader::ReadPathListOp(ListOp<Path> *d) {
|
||||
// read ListOpHeader
|
||||
ListOpHeader h;
|
||||
@@ -2871,6 +2983,17 @@ bool CrateReader::UnpackValueRep(const crate::ValueRep &rep,
|
||||
|
||||
return true;
|
||||
}
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_STRING_LIST_OP: {
|
||||
ListOp<std::string> lst;
|
||||
|
||||
if (!ReadStringListOp(&lst)) {
|
||||
PUSH_ERROR("Failed to read StringListOp data");
|
||||
return false;
|
||||
}
|
||||
|
||||
value->Set(lst);
|
||||
return true;
|
||||
}
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_PATH_VECTOR: {
|
||||
COMPRESS_UNSUPPORTED_CHECK(dty)
|
||||
|
||||
@@ -2966,13 +3089,16 @@ bool CrateReader::UnpackValueRep(const crate::ValueRep &rep,
|
||||
|
||||
return true;
|
||||
}
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_STRING_LIST_OP:
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_VARIANT_SELECTION_MAP: {
|
||||
// TODO
|
||||
PUSH_WARN("VariantSelectionMap is not yet supported. Skipping...");
|
||||
return true;
|
||||
}
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_REFERENCE_LIST_OP:
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_INT_LIST_OP:
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_INT64_LIST_OP:
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_UINT_LIST_OP:
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_UINT64_LIST_OP:
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_VARIANT_SELECTION_MAP:
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_PAYLOAD:
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_LAYER_OFFSET_VECTOR:
|
||||
case crate::CrateDataTypeId::CRATE_DATA_TYPE_VALUE_BLOCK:
|
||||
@@ -3760,10 +3886,19 @@ bool CrateReader::ReadSpecs() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (num_specs > _config.maxNumSpecifiers) {
|
||||
PUSH_ERROR("Too many specs in `SPECS` section.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DCOUT("num_specs " << num_specs);
|
||||
|
||||
CHECK_MEMORY_USAGE(size_t(num_specs) * sizeof(Spec));
|
||||
|
||||
_specs.resize(static_cast<size_t>(num_specs));
|
||||
|
||||
// TODO: Memory size check
|
||||
|
||||
// Create temporary space for decompressing.
|
||||
std::vector<char> comp_buffer(Usd_IntegerCompression::GetCompressedBufferSize(
|
||||
static_cast<size_t>(num_specs)));
|
||||
|
||||
@@ -307,8 +307,14 @@ class CrateReader {
|
||||
bool ReadFloatArray(bool is_compressed, std::vector<float> *d);
|
||||
bool ReadDoubleArray(bool is_compressed, std::vector<double> *d);
|
||||
|
||||
// TODO: Templatize
|
||||
bool ReadPathListOp(ListOp<Path> *d);
|
||||
bool ReadTokenListOp(ListOp<value::token> *d);
|
||||
bool ReadStringListOp(ListOp<std::string> *d);
|
||||
bool ReadIntListOp(ListOp<int32_t> *d);
|
||||
bool ReadUIntListOp(ListOp<uint32_t> *d);
|
||||
bool ReadInt64ListOp(ListOp<int64_t> *d);
|
||||
bool ReadUInt64ListOp(ListOp<uint64_t> *d);
|
||||
|
||||
// Read 64bit uint with range check
|
||||
bool ReadNum(uint64_t &n, uint64_t maxnum);
|
||||
|
||||
@@ -424,7 +424,7 @@ std::string print_typed_attr(const TypedAttribute<T> &attr, const std::string &n
|
||||
ss << paths;
|
||||
}
|
||||
} else if (attr.IsValueEmpty()) {
|
||||
// nothing to do
|
||||
// nothing to do
|
||||
|
||||
} else {
|
||||
auto pv = attr.GetValue();
|
||||
@@ -499,7 +499,7 @@ std::string print_typed_attr(const TypedAttributeWithFallback<Animatable<T>> &at
|
||||
}
|
||||
|
||||
} else if (attr.IsValueEmpty()) {
|
||||
// nothing to do
|
||||
// nothing to do
|
||||
} else {
|
||||
auto v = attr.GetValue();
|
||||
|
||||
@@ -695,7 +695,7 @@ std::string print_timesamples(const value::TimeSamples &v, const uint32_t indent
|
||||
std::string print_rel_prop(const Property &prop, const std::string &name, uint32_t indent)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
|
||||
if (!prop.IsRel()) {
|
||||
return ss.str();
|
||||
}
|
||||
@@ -710,7 +710,7 @@ std::string print_rel_prop(const Property &prop, const std::string &name, uint32
|
||||
if (prop.listOpQual != ListEditQual::ResetToExplicit) {
|
||||
ss << to_string(prop.listOpQual) << " ";
|
||||
}
|
||||
|
||||
|
||||
ss << "rel " << name;
|
||||
|
||||
const Relation &rel = prop.rel;
|
||||
@@ -893,10 +893,6 @@ std::string print_gprim_predefined(const T &gprim, const uint32_t indent) {
|
||||
}
|
||||
}
|
||||
|
||||
// primvars
|
||||
ss << print_typed_attr(gprim.displayColor, "primvars:displayColor", indent);
|
||||
ss << print_typed_attr(gprim.displayOpacity, "primvars:displayOpacity", indent);
|
||||
|
||||
ss << print_xformOps(gprim.xformOps, indent);
|
||||
|
||||
return ss.str();
|
||||
@@ -944,7 +940,7 @@ std::string print_customData(const CustomDataType &customData, const std::string
|
||||
ss << dict_name << " = {\n";
|
||||
} else {
|
||||
ss << "{\n";
|
||||
}
|
||||
}
|
||||
for (const auto &item : customData) {
|
||||
ss << print_meta(item.second, indent+1);
|
||||
}
|
||||
@@ -1556,12 +1552,12 @@ std::string to_string(const GeomBasisCurves &geom, const uint32_t indent, bool c
|
||||
ss << pprint::Indent(indent+1) << "uniform token wrap = " << quote(to_string(geom.wrap.value())) << "\n";
|
||||
}
|
||||
|
||||
ss << print_typed_attr(geom.points, "points", indent);
|
||||
ss << print_typed_attr(geom.normals, "normals", indent);
|
||||
ss << print_typed_attr(geom.widths, "widths", indent);
|
||||
ss << print_typed_attr(geom.velocities, "velocites", indent);
|
||||
ss << print_typed_attr(geom.accelerations, "accelerations", indent);
|
||||
ss << print_typed_attr(geom.curveVertexCounts, "curveVertexCounts", indent);
|
||||
ss << print_typed_attr(geom.points, "points", indent+1);
|
||||
ss << print_typed_attr(geom.normals, "normals", indent+1);
|
||||
ss << print_typed_attr(geom.widths, "widths", indent+1);
|
||||
ss << print_typed_attr(geom.velocities, "velocites", indent+1);
|
||||
ss << print_typed_attr(geom.accelerations, "accelerations", indent+1);
|
||||
ss << print_typed_attr(geom.curveVertexCounts, "curveVertexCounts", indent+1);
|
||||
|
||||
ss << print_gprim_predefined(geom, indent+1);
|
||||
|
||||
|
||||
@@ -42,8 +42,10 @@
|
||||
|
||||
namespace tinyusdz {
|
||||
|
||||
// SpecType enum must be same order with pxrUSD's SdfSpecType(since enum value is stored in Crate directly)
|
||||
enum class SpecType {
|
||||
Attribute,
|
||||
Unknown = 0, // must be 0
|
||||
Attribute,
|
||||
Connection,
|
||||
Expression,
|
||||
Mapper,
|
||||
@@ -54,7 +56,7 @@ enum class SpecType {
|
||||
RelationshipTarget,
|
||||
Variant,
|
||||
VariantSet,
|
||||
Invalid,
|
||||
Invalid, // or NumSpecTypes
|
||||
};
|
||||
|
||||
enum class Orientation {
|
||||
|
||||
@@ -189,6 +189,8 @@ bool LoadUSDCFromMemory(const uint8_t *addr, const size_t length,
|
||||
}
|
||||
|
||||
|
||||
DCOUT("Max length = " << max_length);
|
||||
|
||||
if (length > max_length) {
|
||||
if (err) {
|
||||
(*err) += "USDC data [" + filename +
|
||||
@@ -868,10 +870,13 @@ bool LoadUSDFromMemory(const uint8_t *addr, const size_t length,
|
||||
const USDLoadOptions &options) {
|
||||
|
||||
if (IsUSDC(addr, length)) {
|
||||
DCOUT("Detected as USDC.");
|
||||
return LoadUSDCFromMemory(addr, length, base_dir, stage, warn, err, options);
|
||||
} else if (IsUSDA(addr, length)) {
|
||||
DCOUT("Detected as USDA.");
|
||||
return LoadUSDAFromMemory(addr, length, base_dir, stage, warn, err, options);
|
||||
} else {
|
||||
DCOUT("Detected as USDZ.");
|
||||
// Guess USDZ
|
||||
return LoadUSDZFromMemory(addr, length, base_dir, stage, warn, err, options);
|
||||
}
|
||||
|
||||
@@ -169,8 +169,8 @@ void GeomMesh::Initialize(const GPrim &gprim) {
|
||||
extent = gprim.extent;
|
||||
purpose = gprim.purpose;
|
||||
|
||||
displayColor = gprim.displayColor;
|
||||
displayOpacity = gprim.displayOpacity;
|
||||
//displayColor = gprim.displayColor;
|
||||
//displayOpacity = gprim.displayOpacity;
|
||||
|
||||
#if 0 // TODO
|
||||
|
||||
|
||||
@@ -51,9 +51,11 @@ struct GPrim : Xformable {
|
||||
TypedAttributeWithFallback<Purpose> purpose{
|
||||
Purpose::Default}; // "uniform token purpose"
|
||||
|
||||
#if 0 // TODO: Remove. Please use `props["primvars:displayColor"]`
|
||||
TypedAttribute<Animatable<value::color3f>>
|
||||
displayColor; // primvars:displayColor
|
||||
TypedAttribute<Animatable<float>> displayOpacity; // primvars:displaOpacity
|
||||
#endif
|
||||
|
||||
nonstd::optional<Relation> proxyPrim;
|
||||
nonstd::optional<MaterialBindingAPI> materialBinding;
|
||||
|
||||
@@ -615,9 +615,9 @@ bool USDCReader::Impl::BuildPropertyMap(const std::vector<size_t> &pathIndices,
|
||||
|
||||
const crate::Spec &spec = _specs[spec_index];
|
||||
|
||||
// Property must be Connection or RelationshipTarget
|
||||
if ((spec.spec_type == SpecType::Connection) ||
|
||||
(spec.spec_type == SpecType::RelationshipTarget)) {
|
||||
// Property must be Attribute or Relationship
|
||||
if ((spec.spec_type == SpecType::Attribute) ||
|
||||
(spec.spec_type == SpecType::Relationship)) {
|
||||
// OK
|
||||
} else {
|
||||
continue;
|
||||
@@ -1070,7 +1070,7 @@ bool USDCReader::Impl::ParseProperty(const SpecType spec_type,
|
||||
(*prop) = Property(typeName.value().str(), custom);
|
||||
} else {
|
||||
DCOUT("spec_type = " << to_string(spec_type));
|
||||
if (spec_type == SpecType::RelationshipTarget) {
|
||||
if (spec_type == SpecType::Relationship) {
|
||||
// `rel` with no target. e.g. `rel target`
|
||||
rel = Relation();
|
||||
rel.SetEmpty();
|
||||
@@ -1246,7 +1246,7 @@ bool USDCReader::Impl::ReconstrcutStageMeta(
|
||||
std::vector<value::token> *primChildren) {
|
||||
/// Stage(toplevel layer) Meta fieldSet example.
|
||||
///
|
||||
/// specTy = SpecTypeRelationship
|
||||
/// specTy = SpecTypePseudoRoot
|
||||
///
|
||||
/// - customLayerData(dict)
|
||||
/// - defaultPrim(token)
|
||||
@@ -1444,7 +1444,7 @@ nonstd::optional<Prim> USDCReader::Impl::ReconstructPrimFromTypeName(
|
||||
/// Prim(Model) fieldSet example.
|
||||
///
|
||||
///
|
||||
/// specTy = SpecTypePseudoRoot
|
||||
/// specTy = SpecTypePrim
|
||||
///
|
||||
/// - specifier(specifier) : e.g. `def`, `over`, ...
|
||||
/// - kind(token) : kind metadataum
|
||||
@@ -1637,8 +1637,8 @@ bool USDCReader::Impl::ReconstructPrimNode(
|
||||
DCOUT(pprint::Indent(uint32_t(level))
|
||||
<< " fieldSetIndex = " << spec.fieldset_index.value);
|
||||
|
||||
if ((spec.spec_type == SpecType::Connection) ||
|
||||
(spec.spec_type == SpecType::RelationshipTarget)) {
|
||||
if ((spec.spec_type == SpecType::Attribute) ||
|
||||
(spec.spec_type == SpecType::Relationship)) {
|
||||
if (_prim_table.count(parent)) {
|
||||
// This node is a Properties node. These are processed in
|
||||
// ReconstructPrim(), so nothing to do here.
|
||||
@@ -1676,10 +1676,10 @@ bool USDCReader::Impl::ReconstructPrimNode(
|
||||
PUSH_ERROR_AND_RETURN("(Internal error). Root Element Path not found.");
|
||||
}
|
||||
|
||||
// Root layer(Stage) is Relationship for some reaon.
|
||||
if (spec.spec_type != SpecType::Relationship) {
|
||||
// Root layer(Stage) is PseudoRoot spec type.
|
||||
if (spec.spec_type != SpecType::PseudoRoot) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"SpecTypeRelationship expected for root layer(Stage) element.");
|
||||
"SpecTypePseudoRoot expected for root layer(Stage) element.");
|
||||
}
|
||||
|
||||
std::vector<value::token> primChildren;
|
||||
@@ -1708,7 +1708,7 @@ bool USDCReader::Impl::ReconstructPrimNode(
|
||||
|
||||
DCOUT("===");
|
||||
|
||||
if (spec.spec_type == SpecType::PseudoRoot) {
|
||||
if (spec.spec_type == SpecType::Prim) {
|
||||
// Prim
|
||||
|
||||
if (const auto &pv = GetElemPath(crate::Index(uint32_t(current)))) {
|
||||
@@ -1721,14 +1721,22 @@ bool USDCReader::Impl::ReconstructPrimNode(
|
||||
|
||||
// Sanity check
|
||||
if (specifier) {
|
||||
if (specifier.value() != Specifier::Def) {
|
||||
if (specifier.value() == Specifier::Def) {
|
||||
// ok
|
||||
} else if (specifier.value() == Specifier::Class) {
|
||||
PUSH_WARN("TODO: `class` specifier. skipping this model...");
|
||||
return true;
|
||||
} else if (specifier.value() == Specifier::Over) {
|
||||
PUSH_WARN("TODO: `over` specifier. skipping this model...");
|
||||
return true;
|
||||
} else {
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kTag, "Currently TinyUSDZ only supports `def` for `specifier`.");
|
||||
kTag, "Invalid Specifier.");
|
||||
}
|
||||
} else {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kTag,
|
||||
"`specifier` field is missing for FieldSets "
|
||||
"with SpecType::PseudoRoot.");
|
||||
"with SpecType::Prim.");
|
||||
}
|
||||
|
||||
if (!typeName) {
|
||||
@@ -1764,6 +1772,15 @@ bool USDCReader::Impl::ReconstructPrimNode(
|
||||
} else {
|
||||
_prim_table.insert(current);
|
||||
}
|
||||
} else if (spec.spec_type == SpecType::VariantSet) {
|
||||
// TODO
|
||||
PUSH_WARN("TODO: SpecTypeVariantSet");
|
||||
} else if (spec.spec_type == SpecType::Variant) {
|
||||
// TODO
|
||||
PUSH_WARN("TODO: SpecTypeVariant");
|
||||
} else if (spec.spec_type == SpecType::Attribute) {
|
||||
// Maybe parent is Class/Over.
|
||||
PUSH_WARN("TODO: SpecTypeAttribute(in conjunction with Class/Over specifier?)");
|
||||
} else {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kTag,
|
||||
"TODO: specTy = " << to_string(spec.spec_type));
|
||||
@@ -1904,8 +1921,8 @@ bool USDCReader::Impl::ReconstructPrimTree(
|
||||
DCOUT(pprint::Indent(uint32_t(level))
|
||||
<< " fieldSetIndex = " << spec.fieldset_index.value);
|
||||
|
||||
if ((spec.spec_type == SpecType::Connection) ||
|
||||
(spec.spec_type == SpecType::RelationshipTarget)) {
|
||||
if ((spec.spec_type == SpecType::Attribute) ||
|
||||
(spec.spec_type == SpecType::Relationship)) {
|
||||
if (_prim_table.count(parent)) {
|
||||
// This node is a Properties node. These are processed in
|
||||
// ReconstructPrim(), so nothing to do here.
|
||||
@@ -1945,10 +1962,10 @@ bool USDCReader::Impl::ReconstructPrimTree(
|
||||
PUSH_ERROR_AND_RETURN("(Internal error). Root Element Path not found.");
|
||||
}
|
||||
|
||||
// Root layer(Stage) is Relationship for some reaon.
|
||||
if (spec.spec_type != SpecType::Relationship) {
|
||||
// Root layer(Stage) is PseudoRoot.
|
||||
if (spec.spec_type != SpecType::PseudoRoot) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"SpecTypeRelationship expected for root layer(Stage) element.");
|
||||
"SpecTypePseudoRoot expected for root layer(Stage) element.");
|
||||
}
|
||||
|
||||
if (!ReconstrcutStageMeta(fvs, &stage->GetMetas(), &primChildren)) {
|
||||
@@ -1973,7 +1990,7 @@ bool USDCReader::Impl::ReconstructPrimTree(
|
||||
/// Prim(Model) fieldSet example.
|
||||
///
|
||||
///
|
||||
/// specTy = SpecTypePseudoRoot
|
||||
/// specTy = SpecTypePrim
|
||||
///
|
||||
/// - specifier(specifier) : e.g. `def`, `over`, ...
|
||||
/// - kind(token) : kind metadataum
|
||||
@@ -1986,7 +2003,7 @@ bool USDCReader::Impl::ReconstructPrimTree(
|
||||
|
||||
/// Attrib fieldSet example
|
||||
///
|
||||
/// specTyppe = SpecTypeConnection
|
||||
/// specTyppe = SpecTypeAttribute
|
||||
///
|
||||
/// - typeName(token) : type name of Attribute(e.g. `float`)
|
||||
/// - custom(bool) : `custom` qualifier
|
||||
@@ -2150,7 +2167,7 @@ bool USDCReader::Impl::ReconstructPrimTree(
|
||||
/* _prim_nodes.push_back(pnode); */ \
|
||||
} else
|
||||
|
||||
if (spec.spec_type == SpecType::PseudoRoot) {
|
||||
if (spec.spec_type == SpecType::Prim) {
|
||||
// Prim
|
||||
|
||||
if (const auto &pv = GetElemPath(crate::Index(uint32_t(currentPrimIndex)))) {
|
||||
@@ -2170,7 +2187,7 @@ bool USDCReader::Impl::ReconstructPrimTree(
|
||||
} else {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kTag,
|
||||
"`specifier` field is missing for FieldSets "
|
||||
"with SpecType::PseudoRoot.");
|
||||
"with SpecType::Prim.");
|
||||
}
|
||||
|
||||
if (!typeName) {
|
||||
|
||||
Reference in New Issue
Block a user