mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
Manage GeomSubset as a child Prim of GeomMesh.
This commit is contained in:
@@ -2652,10 +2652,12 @@ std::string to_string(const GeomMesh &mesh, const uint32_t indent,
|
||||
|
||||
ss << print_gprim_predefined(mesh, indent + 1);
|
||||
|
||||
#if 0
|
||||
// GeomSubset.
|
||||
for (const auto &subset : mesh.geom_subset_children) {
|
||||
ss << to_string(subset, indent + 1, /* closing_brace */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
ss << print_props(mesh.props, indent + 1);
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@ nonstd::expected<VertexAttribute, std::string> GetTextureCoordinate(
|
||||
return std::move(vattr);
|
||||
}
|
||||
|
||||
#if 0 // not used at the moment.
|
||||
///
|
||||
/// For GeomSubset. Build offset table to corresponding array index in
|
||||
/// mesh.faceVertexIndices. No need to use this function for triangulated mesh,
|
||||
@@ -189,6 +190,7 @@ bool BuildFaceVertexIndexOffsets(const std::vector<uint32_t> &faceVertexCounts,
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Input: points, faceVertexCounts, faceVertexIndices
|
||||
@@ -681,13 +683,13 @@ bool RenderSceneConverter::ConvertMesh(const int64_t rmaterial_id,
|
||||
for (size_t i = 0; i < faceVertexIndexMap.size(); i++) {
|
||||
size_t fvIdx = faceVertexIndexMap[i];
|
||||
triangulatedFacevaryingNormals.push_back(dst.facevaryingNormals[fvIdx]);
|
||||
}
|
||||
}
|
||||
|
||||
dst.facevaryingNormals = std::move(triangulatedFacevaryingNormals);
|
||||
}
|
||||
|
||||
if (dst.facevaryingTexcoords.size()) {
|
||||
|
||||
|
||||
std::unordered_map<uint32_t, std::vector<tydra::vec2>> triangulatedFacevaryingTexcoords;
|
||||
|
||||
for (auto &slot : dst.facevaryingTexcoords) {
|
||||
@@ -696,7 +698,7 @@ bool RenderSceneConverter::ConvertMesh(const int64_t rmaterial_id,
|
||||
size_t fvIdx = faceVertexIndexMap[i];
|
||||
|
||||
texcoords.push_back(slot.second[fvIdx]);
|
||||
}
|
||||
}
|
||||
triangulatedFacevaryingTexcoords[slot.first] = texcoords;
|
||||
|
||||
}
|
||||
@@ -708,6 +710,7 @@ bool RenderSceneConverter::ConvertMesh(const int64_t rmaterial_id,
|
||||
|
||||
} // triangulate
|
||||
|
||||
#if 0 // TODO: GeomSubsets.
|
||||
// for GeomSubsets
|
||||
if (mesh.geom_subset_children.size()) {
|
||||
std::vector<size_t> faceVertexIndexOffsets;
|
||||
@@ -717,6 +720,7 @@ bool RenderSceneConverter::ConvertMesh(const int64_t rmaterial_id,
|
||||
PUSH_ERROR_AND_RETURN("Build faceVertexIndexOffsets failed.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
(*dstMesh) = std::move(dst);
|
||||
return true;
|
||||
|
||||
@@ -795,18 +795,20 @@ void GeomMesh::Initialize(const GPrim &gprim) {
|
||||
nonstd::expected<bool, std::string> GeomMesh::ValidateGeomSubset() {
|
||||
std::stringstream ss;
|
||||
|
||||
#if 0
|
||||
if (geom_subset_children.empty()) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto CheckFaceIds = [](const size_t nfaces, const std::vector<int32_t> ids) {
|
||||
if (std::any_of(ids.begin(), ids.end(),
|
||||
[&nfaces](int32_t id) { return (id < 0) && uint32_t(id) >= nfaces; })) {
|
||||
return false;
|
||||
}
|
||||
//auto CheckFaceIds = [](const size_t nfaces, const std::vector<int32_t> ids) {
|
||||
// if (std::any_of(ids.begin(), ids.end(),
|
||||
// [&nfaces](int32_t id) { return (id < 0) && uint32_t(id) >= nfaces; })) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
return true;
|
||||
};
|
||||
// return true;
|
||||
//};
|
||||
|
||||
if (!faceVertexCounts.authored()) {
|
||||
// No `faceVertexCounts` definition
|
||||
@@ -830,6 +832,7 @@ nonstd::expected<bool, std::string> GeomMesh::ValidateGeomSubset() {
|
||||
return nonstd::make_unexpected("Failed to get faceVertexCounts data.");
|
||||
}
|
||||
|
||||
#if 0 // TODO
|
||||
size_t n = fvc.size();
|
||||
|
||||
// Currently we only check if face ids are valid.
|
||||
@@ -853,6 +856,7 @@ nonstd::expected<bool, std::string> GeomMesh::ValidateGeomSubset() {
|
||||
return nonstd::make_unexpected(ss.str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
@@ -596,6 +596,7 @@ struct GeomMesh : GPrim {
|
||||
// - int[] primvars:skel:jointIndices
|
||||
// - float[] primvars:skel:jointWeights
|
||||
|
||||
#if 0 // GeomSubset Prim is now managed as a child Prim
|
||||
//
|
||||
// GeomSubset
|
||||
//
|
||||
@@ -605,8 +606,18 @@ struct GeomMesh : GPrim {
|
||||
|
||||
std::vector<GeomSubset> geom_subset_children;
|
||||
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Validate GeomSubset data whose are attached to this GeomMesh.
|
||||
/// Get GeomSubset list assgied to this GeomMesh(child Prim).
|
||||
///
|
||||
/// The pointer points to the address of child Prim,
|
||||
/// so should not free it and this GeomMesh object must be valid during using the pointer to GeomSubset.
|
||||
///
|
||||
std::vector<const GeomSubset *> GetGeomSubsets();
|
||||
|
||||
///
|
||||
/// Validate GeomSubset data whose are attached(as a child Prim) to this GeomMesh.
|
||||
///
|
||||
nonstd::expected<bool, std::string> ValidateGeomSubset();
|
||||
};
|
||||
|
||||
@@ -96,6 +96,7 @@ RECONSTRUCT_PRIM_DECL(CylinderLight);
|
||||
RECONSTRUCT_PRIM_DECL(DiskLight);
|
||||
RECONSTRUCT_PRIM_DECL(DistantLight);
|
||||
RECONSTRUCT_PRIM_DECL(GeomMesh);
|
||||
RECONSTRUCT_PRIM_DECL(GeomSubset);
|
||||
RECONSTRUCT_PRIM_DECL(GeomSphere);
|
||||
RECONSTRUCT_PRIM_DECL(GeomPoints);
|
||||
RECONSTRUCT_PRIM_DECL(GeomCone);
|
||||
@@ -1543,6 +1544,7 @@ bool USDAReader::Impl::RegisterReconstructCallback<GPrim>() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
template <>
|
||||
bool USDAReader::Impl::RegisterReconstructCallback<GeomSubset>() {
|
||||
_parser.RegisterPrimConstructFunction(
|
||||
@@ -1561,6 +1563,7 @@ bool USDAReader::Impl::RegisterReconstructCallback<GeomSubset>() {
|
||||
|
||||
(void)primTypeName;
|
||||
|
||||
|
||||
#if 0
|
||||
if (parent.IsRootPrim()) {
|
||||
return nonstd::make_unexpected(
|
||||
@@ -1583,208 +1586,12 @@ bool USDAReader::Impl::RegisterReconstructCallback<GeomSubset>() {
|
||||
return nonstd::make_unexpected("Failed to process Prim metadataum.");
|
||||
}
|
||||
|
||||
// TODO: Construct GeomMesh first
|
||||
#if 0
|
||||
const std::string parent_primpath = parent.prim_part();
|
||||
|
||||
const PrimNode &pnode = _prim_nodes[size_t(parentPrimIdx)];
|
||||
auto pmesh = pnode.prim.get_value<GeomMesh>();
|
||||
if (!pmesh) {
|
||||
return nonstd::make_unexpected(
|
||||
"Parent Prim must be GeomMesh, but got " +
|
||||
pnode.prim.type_name());
|
||||
}
|
||||
GeomMesh &mesh = pmesh.value();
|
||||
|
||||
GeomSubset subset;
|
||||
|
||||
// uniform token elementType
|
||||
// uniform token familyName
|
||||
// int[] indices
|
||||
// rel material:binding
|
||||
|
||||
if (references.size()) {
|
||||
PUSH_WARN("`references` support in GeomSubset is TODO");
|
||||
}
|
||||
|
||||
// Update props;
|
||||
for (auto item : properties) {
|
||||
if (item.first == "elementType") {
|
||||
if (item.second.is_relationship()) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`elementType` property as Relation is not supported.");
|
||||
}
|
||||
if (auto pv = item.second.get_attribute().var.get_value<value::token>()) {
|
||||
if (item.second.get_attribute().uniform) {
|
||||
auto e = subset.SetElementType(pv.value().str());
|
||||
if (!e) {
|
||||
PUSH_ERROR_AND_RETURN(e.error());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`elementType` property must be `uniform token` type.");
|
||||
} else if (item.first == "familyType") {
|
||||
if (item.second.is_relationship()) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`familyType` property as Relation is not supported.");
|
||||
}
|
||||
|
||||
if (auto pv = item.second.get_attribute().var.get_value<value::token>()) {
|
||||
if (item.second.get_attribute().uniform) {
|
||||
auto e = subset.SetFamilyType(pv.value().str());
|
||||
if (!e) {
|
||||
PUSH_ERROR_AND_RETURN(e.error());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`familyType` property must be `uniform token` type.");
|
||||
|
||||
} else if (item.first == "indices") {
|
||||
if (item.second.is_relationship()) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`indices` property as Relation is not supported.");
|
||||
}
|
||||
|
||||
if (auto pv =
|
||||
item.second.get_attribute().var.get_value<std::vector<int>>()) {
|
||||
// int -> uint
|
||||
std::transform(pv.value().begin(), pv.value().end(),
|
||||
std::back_inserter(subset.indices),
|
||||
[](int a) { return uint32_t(a); });
|
||||
}
|
||||
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`indices` property must be `int[]` type, but got `" +
|
||||
item.second.get_attribute().var.type_name() + "`");
|
||||
|
||||
} else if (item.first == "material:binding") {
|
||||
if (!item.second.is_relationship()) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`material:binding` property as Attribute is not "
|
||||
"supported.");
|
||||
}
|
||||
} else {
|
||||
PUSH_WARN("GeomSubset: TODO: " + item.first);
|
||||
}
|
||||
}
|
||||
|
||||
mesh.geom_subset_children.emplace_back(subset);
|
||||
#else
|
||||
|
||||
// Add GeomSubset to _prim_nodes.
|
||||
|
||||
GeomSubset subset;
|
||||
|
||||
for (auto item : properties) {
|
||||
if (item.first == "elementType") {
|
||||
if (item.second.is_relationship()) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`elementType` property as Relation is not supported.");
|
||||
}
|
||||
if (auto pv = item.second.get_attribute().get_value<value::token>()) {
|
||||
if (item.second.get_attribute().variability() == Variability::Uniform) {
|
||||
auto e = subset.SetElementType(pv.value().str());
|
||||
if (!e) {
|
||||
PUSH_ERROR_AND_RETURN(e.error());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`elementType` property must be `uniform token` type.");
|
||||
} else if (item.first == "familyType") {
|
||||
if (item.second.is_relationship()) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`familyType` property as Relation is not supported.");
|
||||
}
|
||||
|
||||
if (auto pv = item.second.get_attribute().get_value<value::token>()) {
|
||||
if (item.second.get_attribute().variability() == Variability::Uniform) {
|
||||
auto e = subset.SetFamilyType(pv.value().str());
|
||||
if (!e) {
|
||||
PUSH_ERROR_AND_RETURN(e.error());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`familyType` property must be `uniform token` type.");
|
||||
|
||||
} else if (item.first == "indices") {
|
||||
if (item.second.is_relationship()) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`indices` property as Relation is not supported.");
|
||||
}
|
||||
|
||||
if (auto pv =
|
||||
item.second.get_attribute().get_value<std::vector<int>>()) {
|
||||
subset.indices.set_value( *pv );
|
||||
} else {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`indices` property must be `int[]` type, but got `" +
|
||||
item.second.get_attribute().type_name() + "`");
|
||||
}
|
||||
|
||||
} else if (item.first == "material:binding") {
|
||||
if (!item.second.is_relationship()) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`material:binding` property as Attribute is not "
|
||||
"supported.");
|
||||
}
|
||||
} else if (item.first == "familyName") {
|
||||
if (item.second.is_relationship()) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`familyName` property as Relation is not supported.");
|
||||
}
|
||||
|
||||
if (auto pv = item.second.get_attribute().get_value<value::token>()) {
|
||||
subset.familyName = pv.value();
|
||||
} else {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"`familyName` property must be `token` type, but got `" +
|
||||
item.second.get_attribute().type_name() + "`");
|
||||
}
|
||||
} else {
|
||||
PUSH_WARN("GeomSubset: TODO: " + item.first);
|
||||
}
|
||||
}
|
||||
|
||||
subset.name = prim_name.prim_part();
|
||||
subset.spec = spec;
|
||||
subset.meta = meta;
|
||||
|
||||
// Add to scene graph.
|
||||
// NOTE: Scene graph is constructed from bottom up manner(Children
|
||||
// first), so add this primIdx to parent's children.
|
||||
if (size_t(primIdx) >= _prim_nodes.size()) {
|
||||
_prim_nodes.resize(size_t(primIdx) + 1);
|
||||
}
|
||||
DCOUT("sz " << std::to_string(_prim_nodes.size())
|
||||
<< ", primIdx = " << primIdx);
|
||||
|
||||
_prim_nodes[size_t(primIdx)].prim = std::move(subset);
|
||||
DCOUT("prim[" << primIdx << "].ty = "
|
||||
<< _prim_nodes[size_t(primIdx)].prim.type_name());
|
||||
_prim_nodes[size_t(primIdx)].parent = parentPrimIdx;
|
||||
|
||||
if (parentPrimIdx == -1) {
|
||||
_toplevel_prims.push_back(size_t(primIdx));
|
||||
} else {
|
||||
_prim_nodes[size_t(parentPrimIdx)].children.push_back(
|
||||
size_t(primIdx));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <>
|
||||
bool USDAReader::Impl::ReconstructPrim(
|
||||
|
||||
7
tests/usda/geomsubset-001.usda
Normal file
7
tests/usda/geomsubset-001.usda
Normal file
@@ -0,0 +1,7 @@
|
||||
#usda 1.0
|
||||
|
||||
def Mesh "bora" {
|
||||
def GeomSubset "subset0" {
|
||||
float x = 1.2
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user