@@ -845,6 +845,47 @@ 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+ uint32_t offset = 0 ;
860+ for (const auto polySize : mesh.polyFaceSizes ) {
861+ // Check if all vertices of this polygon are active
862+ bool allActive = true ;
863+ for (uint32_t i = 0 ; i < polySize; ++i) {
864+ const auto vtx = mesh.polyFaces [offset + i];
865+ if (vtx >= activeVertices.size () || !activeVertices[vtx]) {
866+ allActive = false ;
867+ break ;
868+ }
869+ }
870+
871+ if (allActive) {
872+ newMesh.polyFaceSizes .push_back (polySize);
873+ for (uint32_t i = 0 ; i < polySize; ++i) {
874+ newMesh.polyFaces .push_back (
875+ static_cast <uint32_t >(reverseVertexMapping[mesh.polyFaces [offset + i]]));
876+ }
877+ if (!mesh.polyTexcoordFaces .empty ()) {
878+ for (uint32_t i = 0 ; i < polySize; ++i) {
879+ newMesh.polyTexcoordFaces .push_back (
880+ static_cast <uint32_t >(reverseTexcoordMapping[mesh.polyTexcoordFaces [offset + i]]));
881+ }
882+ }
883+ }
884+
885+ offset += polySize;
886+ }
887+ }
888+
848889std::vector<std::vector<int32_t >> remapLines (
849890 const std::vector<std::vector<int32_t >>& lines,
850891 const std::vector<size_t >& mapping) {
@@ -923,6 +964,50 @@ std::vector<bool> facesToVertices(
923964 return activeVertices;
924965}
925966
967+ std::vector<bool > verticesToPolys (
968+ const std::vector<uint32_t >& polyFaces,
969+ const std::vector<uint32_t >& polyFaceSizes,
970+ const std::vector<bool >& activeVertices) {
971+ std::vector<bool > activePolys (polyFaceSizes.size (), false );
972+ uint32_t offset = 0 ;
973+ for (size_t polyIdx = 0 ; polyIdx < polyFaceSizes.size (); ++polyIdx) {
974+ const auto polySize = polyFaceSizes[polyIdx];
975+ bool allActive = true ;
976+ for (uint32_t i = 0 ; i < polySize; ++i) {
977+ const auto vtx = polyFaces[offset + i];
978+ if (vtx >= activeVertices.size () || !activeVertices[vtx]) {
979+ allActive = false ;
980+ break ;
981+ }
982+ }
983+ activePolys[polyIdx] = allActive;
984+ offset += polySize;
985+ }
986+ return activePolys;
987+ }
988+
989+ std::vector<bool > polysToVertices (
990+ const std::vector<uint32_t >& polyFaces,
991+ const std::vector<uint32_t >& polyFaceSizes,
992+ const std::vector<bool >& activePolys,
993+ size_t vertexCount) {
994+ std::vector<bool > activeVertices (vertexCount, false );
995+ uint32_t offset = 0 ;
996+ for (size_t polyIdx = 0 ; polyIdx < polyFaceSizes.size (); ++polyIdx) {
997+ const auto polySize = polyFaceSizes[polyIdx];
998+ if (activePolys[polyIdx]) {
999+ for (uint32_t i = 0 ; i < polySize; ++i) {
1000+ const auto vtx = polyFaces[offset + i];
1001+ if (vtx < vertexCount) {
1002+ activeVertices[vtx] = true ;
1003+ }
1004+ }
1005+ }
1006+ offset += polySize;
1007+ }
1008+ return activeVertices;
1009+ }
1010+
9261011// Internal mesh reduction function used by both reduceMeshComponents and
9271012// the public reduceMeshByFaces/reduceMeshByVertices for Mesh.
9281013template <typename T>
@@ -954,22 +1039,26 @@ MeshT<T> reduceMeshInternal(
9541039 newMesh.lines = remapLines (mesh.lines , reverseVertexMapping);
9551040 }
9561041
1042+ std::vector<size_t > reverseTextureVertexMapping;
9571043 if (!mesh.texcoord_faces .empty () && !mesh.texcoords .empty ()) {
9581044 std::vector<bool > activeTextureTriangles = activeFaces;
9591045 activeTextureTriangles.resize (mesh.texcoord_faces .size (), false );
9601046
9611047 const std::vector<bool > activeTextureVertices =
9621048 facesToVertices (mesh.texcoord_faces , activeTextureTriangles, mesh.texcoords .size ());
9631049
964- auto [forwardTextureVertexMapping, reverseTextureVertexMapping ] =
965- createIndexMapping (activeTextureVertices );
1050+ auto [forwardTextureVertexMapping, revTexMapping ] = createIndexMapping (activeTextureVertices);
1051+ reverseTextureVertexMapping = std::move (revTexMapping );
9661052
9671053 newMesh.texcoords = selectVertices (mesh.texcoords , forwardTextureVertexMapping);
9681054 newMesh.texcoord_faces =
9691055 remapFaces (mesh.texcoord_faces , reverseTextureVertexMapping, activeTextureTriangles);
9701056 newMesh.texcoord_lines = remapLines (mesh.texcoord_lines , reverseTextureVertexMapping);
9711057 }
9721058
1059+ // Remap polygon face data
1060+ remapPolyFaces (newMesh, mesh, activeVertices, reverseVertexMapping, reverseTextureVertexMapping);
1061+
9731062 return newMesh;
9741063}
9751064
@@ -1185,6 +1274,61 @@ std::vector<bool> facesToVertices(const MeshT<T>& mesh, const std::vector<bool>&
11851274 return facesToVertices (mesh.faces , activeFaces, mesh.vertices .size ());
11861275}
11871276
1277+ template <typename T>
1278+ std::vector<bool > verticesToPolys (const MeshT<T>& mesh, const std::vector<bool >& activeVertices) {
1279+ MT_CHECK (
1280+ activeVertices.size () == mesh.vertices .size (),
1281+ " Active vertices size ({}) does not match mesh vertex count ({})" ,
1282+ activeVertices.size (),
1283+ mesh.vertices .size ());
1284+
1285+ return verticesToPolys (mesh.polyFaces , mesh.polyFaceSizes , activeVertices);
1286+ }
1287+
1288+ template <typename T>
1289+ std::vector<bool > polysToVertices (const MeshT<T>& mesh, const std::vector<bool >& activePolys) {
1290+ MT_CHECK (
1291+ activePolys.size () == mesh.polyFaceSizes .size (),
1292+ " Active polys size ({}) does not match polygon count ({})" ,
1293+ activePolys.size (),
1294+ mesh.polyFaceSizes .size ());
1295+
1296+ return polysToVertices (mesh.polyFaces , mesh.polyFaceSizes , activePolys, mesh.vertices .size ());
1297+ }
1298+
1299+ template <typename T>
1300+ MeshT<T> reduceMeshByPolys (const MeshT<T>& mesh, const std::vector<bool >& activePolys) {
1301+ MT_CHECK (
1302+ activePolys.size () == mesh.polyFaceSizes .size (),
1303+ " Active polys size ({}) does not match polygon count ({})" ,
1304+ activePolys.size (),
1305+ mesh.polyFaceSizes .size ());
1306+
1307+ // Convert polygon selection to vertex selection, then to face selection
1308+ const auto activeVertices = polysToVertices (mesh, activePolys);
1309+ const auto activeFaces = verticesToFaces (mesh, activeVertices);
1310+
1311+ return reduceMeshInternal (mesh, activeVertices, activeFaces);
1312+ }
1313+
1314+ template <typename T>
1315+ CharacterT<T> reduceMeshByPolys (
1316+ const CharacterT<T>& character,
1317+ const std::vector<bool >& activePolys) {
1318+ MT_CHECK (character.mesh , " Cannot reduce mesh: character has no mesh" );
1319+ MT_CHECK (
1320+ activePolys.size () == character.mesh ->polyFaceSizes .size (),
1321+ " Active polys size ({}) does not match polygon count ({})" ,
1322+ activePolys.size (),
1323+ character.mesh ->polyFaceSizes .size ());
1324+
1325+ // Convert polygon selection to vertex selection, then to face selection
1326+ const auto activeVertices = polysToVertices (*character.mesh , activePolys);
1327+ const auto activeFaces = verticesToFaces (*character.mesh , activeVertices);
1328+
1329+ return reduceMeshComponents (character, activeVertices, activeFaces);
1330+ }
1331+
11881332// Explicit instantiations for commonly used types
11891333template CharacterT<float > reduceMeshByVertices<float >(
11901334 const CharacterT<float >& character,
@@ -1234,4 +1378,36 @@ template std::vector<bool> facesToVertices<double>(
12341378 const MeshT<double >& mesh,
12351379 const std::vector<bool >& activeFaces);
12361380
1381+ template std::vector<bool > verticesToPolys<float >(
1382+ const MeshT<float >& mesh,
1383+ const std::vector<bool >& activeVertices);
1384+
1385+ template std::vector<bool > verticesToPolys<double >(
1386+ const MeshT<double >& mesh,
1387+ const std::vector<bool >& activeVertices);
1388+
1389+ template std::vector<bool > polysToVertices<float >(
1390+ const MeshT<float >& mesh,
1391+ const std::vector<bool >& activePolys);
1392+
1393+ template std::vector<bool > polysToVertices<double >(
1394+ const MeshT<double >& mesh,
1395+ const std::vector<bool >& activePolys);
1396+
1397+ template MeshT<float > reduceMeshByPolys<float >(
1398+ const MeshT<float >& mesh,
1399+ const std::vector<bool >& activePolys);
1400+
1401+ template MeshT<double > reduceMeshByPolys<double >(
1402+ const MeshT<double >& mesh,
1403+ const std::vector<bool >& activePolys);
1404+
1405+ template CharacterT<float > reduceMeshByPolys<float >(
1406+ const CharacterT<float >& character,
1407+ const std::vector<bool >& activePolys);
1408+
1409+ template CharacterT<double > reduceMeshByPolys<double >(
1410+ const CharacterT<double >& character,
1411+ const std::vector<bool >& activePolys);
1412+
12371413} // namespace momentum
0 commit comments