@@ -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,53 @@ 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+ std::vector<bool > activePolys (polyFaceSizes.size (), false );
981+ uint32_t offset = 0 ;
982+ for (size_t polyIdx = 0 ; polyIdx < polyFaceSizes.size (); ++polyIdx) {
983+ const auto polySize = polyFaceSizes[polyIdx];
984+ bool allActive = true ;
985+ for (uint32_t i = 0 ; i < polySize; ++i) {
986+ const auto vtx = polyFaces[offset + i];
987+ if (vtx >= activeVertices.size () || !activeVertices[vtx]) {
988+ allActive = false ;
989+ break ;
990+ }
991+ }
992+ activePolys[polyIdx] = allActive;
993+ offset += polySize;
994+ }
995+ return activePolys;
996+ }
997+
998+ std::vector<bool > polysToVertices (
999+ const std::vector<uint32_t >& polyFaces,
1000+ const std::vector<uint32_t >& polyFaceSizes,
1001+ const std::vector<bool >& activePolys,
1002+ size_t vertexCount) {
1003+ std::vector<bool > activeVertices (vertexCount, false );
1004+ uint32_t offset = 0 ;
1005+ for (size_t polyIdx = 0 ; polyIdx < polyFaceSizes.size (); ++polyIdx) {
1006+ const auto polySize = polyFaceSizes[polyIdx];
1007+ if (activePolys[polyIdx]) {
1008+ for (uint32_t i = 0 ; i < polySize; ++i) {
1009+ const auto vtx = polyFaces[offset + i];
1010+ if (vtx < vertexCount) {
1011+ activeVertices[vtx] = true ;
1012+ }
1013+ }
1014+ }
1015+ offset += polySize;
1016+ }
1017+ return activeVertices;
1018+ }
1019+
9261020// Internal mesh reduction function used by both reduceMeshComponents and
9271021// the public reduceMeshByFaces/reduceMeshByVertices for Mesh.
9281022template <typename T>
@@ -954,22 +1048,26 @@ MeshT<T> reduceMeshInternal(
9541048 newMesh.lines = remapLines (mesh.lines , reverseVertexMapping);
9551049 }
9561050
1051+ std::vector<size_t > reverseTextureVertexMapping;
9571052 if (!mesh.texcoord_faces .empty () && !mesh.texcoords .empty ()) {
9581053 std::vector<bool > activeTextureTriangles = activeFaces;
9591054 activeTextureTriangles.resize (mesh.texcoord_faces .size (), false );
9601055
9611056 const std::vector<bool > activeTextureVertices =
9621057 facesToVertices (mesh.texcoord_faces , activeTextureTriangles, mesh.texcoords .size ());
9631058
964- auto [forwardTextureVertexMapping, reverseTextureVertexMapping ] =
965- createIndexMapping (activeTextureVertices );
1059+ auto [forwardTextureVertexMapping, revTexMapping ] = createIndexMapping (activeTextureVertices);
1060+ reverseTextureVertexMapping = std::move (revTexMapping );
9661061
9671062 newMesh.texcoords = selectVertices (mesh.texcoords , forwardTextureVertexMapping);
9681063 newMesh.texcoord_faces =
9691064 remapFaces (mesh.texcoord_faces , reverseTextureVertexMapping, activeTextureTriangles);
9701065 newMesh.texcoord_lines = remapLines (mesh.texcoord_lines , reverseTextureVertexMapping);
9711066 }
9721067
1068+ // Remap polygon face data
1069+ remapPolyFaces (newMesh, mesh, activeVertices, reverseVertexMapping, reverseTextureVertexMapping);
1070+
9731071 return newMesh;
9741072}
9751073
@@ -1185,6 +1283,61 @@ std::vector<bool> facesToVertices(const MeshT<T>& mesh, const std::vector<bool>&
11851283 return facesToVertices (mesh.faces , activeFaces, mesh.vertices .size ());
11861284}
11871285
1286+ template <typename T>
1287+ std::vector<bool > verticesToPolys (const MeshT<T>& mesh, const std::vector<bool >& activeVertices) {
1288+ MT_CHECK (
1289+ activeVertices.size () == mesh.vertices .size (),
1290+ " Active vertices size ({}) does not match mesh vertex count ({})" ,
1291+ activeVertices.size (),
1292+ mesh.vertices .size ());
1293+
1294+ return verticesToPolys (mesh.polyFaces , mesh.polyFaceSizes , activeVertices);
1295+ }
1296+
1297+ template <typename T>
1298+ std::vector<bool > polysToVertices (const MeshT<T>& mesh, const std::vector<bool >& activePolys) {
1299+ MT_CHECK (
1300+ activePolys.size () == mesh.polyFaceSizes .size (),
1301+ " Active polys size ({}) does not match polygon count ({})" ,
1302+ activePolys.size (),
1303+ mesh.polyFaceSizes .size ());
1304+
1305+ return polysToVertices (mesh.polyFaces , mesh.polyFaceSizes , activePolys, mesh.vertices .size ());
1306+ }
1307+
1308+ template <typename T>
1309+ MeshT<T> reduceMeshByPolys (const MeshT<T>& mesh, const std::vector<bool >& activePolys) {
1310+ MT_CHECK (
1311+ activePolys.size () == mesh.polyFaceSizes .size (),
1312+ " Active polys size ({}) does not match polygon count ({})" ,
1313+ activePolys.size (),
1314+ mesh.polyFaceSizes .size ());
1315+
1316+ // Convert polygon selection to vertex selection, then to face selection
1317+ const auto activeVertices = polysToVertices (mesh, activePolys);
1318+ const auto activeFaces = verticesToFaces (mesh, activeVertices);
1319+
1320+ return reduceMeshInternal (mesh, activeVertices, activeFaces);
1321+ }
1322+
1323+ template <typename T>
1324+ CharacterT<T> reduceMeshByPolys (
1325+ const CharacterT<T>& character,
1326+ const std::vector<bool >& activePolys) {
1327+ MT_CHECK (character.mesh , " Cannot reduce mesh: character has no mesh" );
1328+ MT_CHECK (
1329+ activePolys.size () == character.mesh ->polyFaceSizes .size (),
1330+ " Active polys size ({}) does not match polygon count ({})" ,
1331+ activePolys.size (),
1332+ character.mesh ->polyFaceSizes .size ());
1333+
1334+ // Convert polygon selection to vertex selection, then to face selection
1335+ const auto activeVertices = polysToVertices (*character.mesh , activePolys);
1336+ const auto activeFaces = verticesToFaces (*character.mesh , activeVertices);
1337+
1338+ return reduceMeshComponents (character, activeVertices, activeFaces);
1339+ }
1340+
11881341// Explicit instantiations for commonly used types
11891342template CharacterT<float > reduceMeshByVertices<float >(
11901343 const CharacterT<float >& character,
@@ -1234,4 +1387,36 @@ template std::vector<bool> facesToVertices<double>(
12341387 const MeshT<double >& mesh,
12351388 const std::vector<bool >& activeFaces);
12361389
1390+ template std::vector<bool > verticesToPolys<float >(
1391+ const MeshT<float >& mesh,
1392+ const std::vector<bool >& activeVertices);
1393+
1394+ template std::vector<bool > verticesToPolys<double >(
1395+ const MeshT<double >& mesh,
1396+ const std::vector<bool >& activeVertices);
1397+
1398+ template std::vector<bool > polysToVertices<float >(
1399+ const MeshT<float >& mesh,
1400+ const std::vector<bool >& activePolys);
1401+
1402+ template std::vector<bool > polysToVertices<double >(
1403+ const MeshT<double >& mesh,
1404+ const std::vector<bool >& activePolys);
1405+
1406+ template MeshT<float > reduceMeshByPolys<float >(
1407+ const MeshT<float >& mesh,
1408+ const std::vector<bool >& activePolys);
1409+
1410+ template MeshT<double > reduceMeshByPolys<double >(
1411+ const MeshT<double >& mesh,
1412+ const std::vector<bool >& activePolys);
1413+
1414+ template CharacterT<float > reduceMeshByPolys<float >(
1415+ const CharacterT<float >& character,
1416+ const std::vector<bool >& activePolys);
1417+
1418+ template CharacterT<double > reduceMeshByPolys<double >(
1419+ const CharacterT<double >& character,
1420+ const std::vector<bool >& activePolys);
1421+
12371422} // namespace momentum
0 commit comments