| 1019 | } |
| 1020 | |
| 1021 | static DecimateResult decimateMeshParallelInplace( MR::Mesh & mesh, const DecimateSettings & settings ) |
| 1022 | { |
| 1023 | MR_TIMER; |
| 1024 | assert( settings.subdivideParts > 1 ); |
| 1025 | const auto sz = settings.subdivideParts; |
| 1026 | const auto numIniVerts = mesh.topology.numValidVerts(); |
| 1027 | assert( !settings.partFaces || settings.partFaces->size() == sz ); |
| 1028 | |
| 1029 | DecimateResult res; |
| 1030 | if ( mesh.topology.getFaceIds( settings.region ).none() ) |
| 1031 | { |
| 1032 | // nothing to decimate |
| 1033 | res.cancelled = false; |
| 1034 | return res; |
| 1035 | } |
| 1036 | |
| 1037 | if ( settings.progressCallback && !settings.progressCallback( 0 ) ) |
| 1038 | return res; |
| 1039 | |
| 1040 | struct alignas(64) Parts |
| 1041 | { |
| 1042 | /// region faces of the subdivision part |
| 1043 | FaceBitSet region; |
| 1044 | |
| 1045 | /// vertices to be fixed during subdivision of individual parts |
| 1046 | VertBitSet bdVerts; |
| 1047 | |
| 1048 | /// these are inner vertices of this part that can be easily deleted during part decimation; |
| 1049 | /// filled only if limitedDeletion |
| 1050 | VertBitSet removableVerts; |
| 1051 | |
| 1052 | DecimateResult decimRes; |
| 1053 | }; |
| 1054 | std::vector<Parts> parts( sz ); |
| 1055 | |
| 1056 | // determine faces for each part |
| 1057 | ParallelFor( parts, [&]( size_t i ) |
| 1058 | { |
| 1059 | if ( settings.partFaces ) |
| 1060 | parts[i].region = std::move( (*settings.partFaces)[i] ); |
| 1061 | else |
| 1062 | parts[i].region = getSubdividePart( mesh.topology.getValidFaces(), settings.subdivideParts, i ); |
| 1063 | } ); |
| 1064 | if ( settings.progressCallback && !settings.progressCallback( 0.03f ) ) |
| 1065 | return res; |
| 1066 | |
| 1067 | // determine edges in between the parts |
| 1068 | UndirectedEdgeBitSet stableEdges( mesh.topology.undirectedEdgeSize() ); |
| 1069 | BitSetParallelForAll( stableEdges, [&]( UndirectedEdgeId ue ) |
| 1070 | { |
| 1071 | FaceId l = mesh.topology.left( ue ); |
| 1072 | FaceId r = mesh.topology.right( ue ); |
| 1073 | if ( !l || !r ) |
| 1074 | return; |
| 1075 | for ( size_t i = 0; i < sz; ++i ) |
| 1076 | { |
| 1077 | if ( parts[i].region.test( l ) != parts[i].region.test( r ) ) |
| 1078 | { |
no test coverage detected