@@ -845,6 +845,53 @@ std::vector<Eigen::Vector3i> remapFaces(
845845 return remappedFaces;
846846}
847847
848+ template <typename T>
849+ void remapPolyFaces (
850+ MeshT<T>& newMesh,
851+ const MeshT<T>& mesh,
852+ const std::vector<bool >& activeVertices,
853+ const std::vector<size_t >& reverseVertexMapping,
854+ const std::vector<size_t >& reverseTexcoordMapping) {
855+ if (mesh.polyFaces .empty ()) {
856+ return ;
857+ }
858+
859+ newMesh.polyFaceSizes .reserve (mesh.polyFaceSizes .size ());
860+ newMesh.polyFaces .reserve (mesh.polyFaces .size ());
861+ if (!mesh.polyTexcoordFaces .empty ()) {
862+ newMesh.polyTexcoordFaces .reserve (mesh.polyTexcoordFaces .size ());
863+ }
864+
865+ uint32_t offset = 0 ;
866+ for (const auto polySize : mesh.polyFaceSizes ) {
867+ // Check if all vertices of this polygon are active
868+ bool allActive = true ;
869+ for (uint32_t i = 0 ; i < polySize; ++i) {
870+ const auto vtx = mesh.polyFaces [offset + i];
871+ if (vtx >= activeVertices.size () || !activeVertices[vtx]) {
872+ allActive = false ;
873+ break ;
874+ }
875+ }
876+
877+ if (allActive) {
878+ newMesh.polyFaceSizes .push_back (polySize);
879+ for (uint32_t i = 0 ; i < polySize; ++i) {
880+ newMesh.polyFaces .push_back (
881+ static_cast <uint32_t >(reverseVertexMapping[mesh.polyFaces [offset + i]]));
882+ }
883+ if (!mesh.polyTexcoordFaces .empty ()) {
884+ for (uint32_t i = 0 ; i < polySize; ++i) {
885+ newMesh.polyTexcoordFaces .push_back (
886+ static_cast <uint32_t >(reverseTexcoordMapping[mesh.polyTexcoordFaces [offset + i]]));
887+ }
888+ }
889+ }
890+
891+ offset += polySize;
892+ }
893+ }
894+
848895std::vector<std::vector<int32_t >> remapLines (
849896 const std::vector<std::vector<int32_t >>& lines,
850897 const std::vector<size_t >& mapping) {
@@ -923,6 +970,57 @@ std::vector<bool> facesToVertices(
923970 return activeVertices;
924971}
925972
973+ std::vector<bool > verticesToPolys (
974+ const std::vector<uint32_t >& polyFaces,
975+ const std::vector<uint32_t >& polyFaceSizes,
976+ const std::vector<bool >& activeVertices) {
977+ if (polyFaceSizes.empty ()) {
978+ return {};
979+ }
980+ MT_CHECK (!polyFaceSizes.empty ());
981+ std::vector<bool > activePolys (polyFaceSizes.size (), false );
982+ uint32_t offset = 0 ;
983+ for (size_t polyIdx = 0 ; polyIdx < polyFaceSizes.size (); ++polyIdx) {
984+ const auto polySize = polyFaceSizes[polyIdx];
985+ bool allActive = true ;
986+ for (uint32_t i = 0 ; i < polySize; ++i) {
987+ const auto vtx = polyFaces[offset + i];
988+ if (vtx >= activeVertices.size () || !activeVertices[vtx]) {
989+ allActive = false ;
990+ break ;
991+ }
992+ }
993+ activePolys[polyIdx] = allActive;
994+ offset += polySize;
995+ }
996+ return activePolys;
997+ }
998+
999+ std::vector<bool > polysToVertices (
1000+ const std::vector<uint32_t >& polyFaces,
1001+ const std::vector<uint32_t >& polyFaceSizes,
1002+ const std::vector<bool >& activePolys,
1003+ size_t vertexCount) {
1004+ std::vector<bool > activeVertices (vertexCount, false );
1005+ if (activePolys.empty ()) {
1006+ return activeVertices;
1007+ }
1008+ uint32_t offset = 0 ;
1009+ for (size_t polyIdx = 0 ; polyIdx < polyFaceSizes.size (); ++polyIdx) {
1010+ const auto polySize = polyFaceSizes[polyIdx];
1011+ if (activePolys[polyIdx]) {
1012+ for (uint32_t i = 0 ; i < polySize; ++i) {
1013+ const auto vtx = polyFaces[offset + i];
1014+ if (vtx < vertexCount) {
1015+ activeVertices[vtx] = true ;
1016+ }
1017+ }
1018+ }
1019+ offset += polySize;
1020+ }
1021+ return activeVertices;
1022+ }
1023+
9261024// Internal mesh reduction function used by both reduceMeshComponents and
9271025// the public reduceMeshByFaces/reduceMeshByVertices for Mesh.
9281026template <typename T>
@@ -954,22 +1052,26 @@ MeshT<T> reduceMeshInternal(
9541052 newMesh.lines = remapLines (mesh.lines , reverseVertexMapping);
9551053 }
9561054
1055+ std::vector<size_t > reverseTextureVertexMapping;
9571056 if (!mesh.texcoord_faces .empty () && !mesh.texcoords .empty ()) {
9581057 std::vector<bool > activeTextureTriangles = activeFaces;
9591058 activeTextureTriangles.resize (mesh.texcoord_faces .size (), false );
9601059
9611060 const std::vector<bool > activeTextureVertices =
9621061 facesToVertices (mesh.texcoord_faces , activeTextureTriangles, mesh.texcoords .size ());
9631062
964- auto [forwardTextureVertexMapping, reverseTextureVertexMapping ] =
965- createIndexMapping (activeTextureVertices );
1063+ auto [forwardTextureVertexMapping, revTexMapping ] = createIndexMapping (activeTextureVertices);
1064+ reverseTextureVertexMapping = std::move (revTexMapping );
9661065
9671066 newMesh.texcoords = selectVertices (mesh.texcoords , forwardTextureVertexMapping);
9681067 newMesh.texcoord_faces =
9691068 remapFaces (mesh.texcoord_faces , reverseTextureVertexMapping, activeTextureTriangles);
9701069 newMesh.texcoord_lines = remapLines (mesh.texcoord_lines , reverseTextureVertexMapping);
9711070 }
9721071
1072+ // Remap polygon face data
1073+ remapPolyFaces (newMesh, mesh, activeVertices, reverseVertexMapping, reverseTextureVertexMapping);
1074+
9731075 return newMesh;
9741076}
9751077
@@ -1185,6 +1287,61 @@ std::vector<bool> facesToVertices(const MeshT<T>& mesh, const std::vector<bool>&
11851287 return facesToVertices (mesh.faces , activeFaces, mesh.vertices .size ());
11861288}
11871289
1290+ template <typename T>
1291+ std::vector<bool > verticesToPolys (const MeshT<T>& mesh, const std::vector<bool >& activeVertices) {
1292+ MT_CHECK (
1293+ activeVertices.size () == mesh.vertices .size (),
1294+ " Active vertices size ({}) does not match mesh vertex count ({})" ,
1295+ activeVertices.size (),
1296+ mesh.vertices .size ());
1297+
1298+ return verticesToPolys (mesh.polyFaces , mesh.polyFaceSizes , activeVertices);
1299+ }
1300+
1301+ template <typename T>
1302+ std::vector<bool > polysToVertices (const MeshT<T>& mesh, const std::vector<bool >& activePolys) {
1303+ MT_CHECK (
1304+ activePolys.size () == mesh.polyFaceSizes .size (),
1305+ " Active polys size ({}) does not match polygon count ({})" ,
1306+ activePolys.size (),
1307+ mesh.polyFaceSizes .size ());
1308+
1309+ return polysToVertices (mesh.polyFaces , mesh.polyFaceSizes , activePolys, mesh.vertices .size ());
1310+ }
1311+
1312+ template <typename T>
1313+ MeshT<T> reduceMeshByPolys (const MeshT<T>& mesh, const std::vector<bool >& activePolys) {
1314+ MT_CHECK (
1315+ activePolys.size () == mesh.polyFaceSizes .size (),
1316+ " Active polys size ({}) does not match polygon count ({})" ,
1317+ activePolys.size (),
1318+ mesh.polyFaceSizes .size ());
1319+
1320+ // Convert polygon selection to vertex selection, then to face selection
1321+ const auto activeVertices = polysToVertices (mesh, activePolys);
1322+ const auto activeFaces = verticesToFaces (mesh, activeVertices);
1323+
1324+ return reduceMeshInternal (mesh, activeVertices, activeFaces);
1325+ }
1326+
1327+ template <typename T>
1328+ CharacterT<T> reduceMeshByPolys (
1329+ const CharacterT<T>& character,
1330+ const std::vector<bool >& activePolys) {
1331+ MT_CHECK (character.mesh , " Cannot reduce mesh: character has no mesh" );
1332+ MT_CHECK (
1333+ activePolys.size () == character.mesh ->polyFaceSizes .size (),
1334+ " Active polys size ({}) does not match polygon count ({})" ,
1335+ activePolys.size (),
1336+ character.mesh ->polyFaceSizes .size ());
1337+
1338+ // Convert polygon selection to vertex selection, then to face selection
1339+ const auto activeVertices = polysToVertices (*character.mesh , activePolys);
1340+ const auto activeFaces = verticesToFaces (*character.mesh , activeVertices);
1341+
1342+ return reduceMeshComponents (character, activeVertices, activeFaces);
1343+ }
1344+
11881345// Explicit instantiations for commonly used types
11891346template CharacterT<float > reduceMeshByVertices<float >(
11901347 const CharacterT<float >& character,
@@ -1234,4 +1391,36 @@ template std::vector<bool> facesToVertices<double>(
12341391 const MeshT<double >& mesh,
12351392 const std::vector<bool >& activeFaces);
12361393
1394+ template std::vector<bool > verticesToPolys<float >(
1395+ const MeshT<float >& mesh,
1396+ const std::vector<bool >& activeVertices);
1397+
1398+ template std::vector<bool > verticesToPolys<double >(
1399+ const MeshT<double >& mesh,
1400+ const std::vector<bool >& activeVertices);
1401+
1402+ template std::vector<bool > polysToVertices<float >(
1403+ const MeshT<float >& mesh,
1404+ const std::vector<bool >& activePolys);
1405+
1406+ template std::vector<bool > polysToVertices<double >(
1407+ const MeshT<double >& mesh,
1408+ const std::vector<bool >& activePolys);
1409+
1410+ template MeshT<float > reduceMeshByPolys<float >(
1411+ const MeshT<float >& mesh,
1412+ const std::vector<bool >& activePolys);
1413+
1414+ template MeshT<double > reduceMeshByPolys<double >(
1415+ const MeshT<double >& mesh,
1416+ const std::vector<bool >& activePolys);
1417+
1418+ template CharacterT<float > reduceMeshByPolys<float >(
1419+ const CharacterT<float >& character,
1420+ const std::vector<bool >& activePolys);
1421+
1422+ template CharacterT<double > reduceMeshByPolys<double >(
1423+ const CharacterT<double >& character,
1424+ const std::vector<bool >& activePolys);
1425+
12371426} // namespace momentum
0 commit comments