Manage GeomSubset as a child Prim of GeomMesh.

This commit is contained in:
Syoyo Fujita
2023-11-17 23:29:20 +09:00
parent 4b795e9acc
commit 03916f17d0
6 changed files with 43 additions and 208 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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();
};

View File

@@ -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(

View File

@@ -0,0 +1,7 @@
#usda 1.0
def Mesh "bora" {
def GeomSubset "subset0" {
float x = 1.2
}
}