| 157 | } |
| 158 | |
| 159 | PreCutResult doPreCutMesh( Mesh& mesh, const OneMeshContours& contours ) |
| 160 | { |
| 161 | MR_TIMER; |
| 162 | |
| 163 | int numVerts = 0; |
| 164 | int numEdges = 0; |
| 165 | int intersectedEdges = 0; |
| 166 | for ( const auto& cont : contours ) |
| 167 | { |
| 168 | auto size = int( cont.intersections.size() ); |
| 169 | numVerts += size; |
| 170 | numEdges += 2 * size; |
| 171 | for ( const auto& in : cont.intersections ) |
| 172 | if ( std::holds_alternative<EdgeId>( in.primitiveId ) ) |
| 173 | ++intersectedEdges; |
| 174 | numEdges += 2 * intersectedEdges; |
| 175 | if ( cont.closed ) |
| 176 | --numVerts; |
| 177 | } |
| 178 | const auto totalExpectedVerts = mesh.topology.vertSize() + numVerts; |
| 179 | const auto totalExpectedEdges = mesh.topology.edgeSize() + numEdges; |
| 180 | |
| 181 | mesh.topology.vertReserve( totalExpectedVerts ); |
| 182 | mesh.topology.edgeReserve( totalExpectedEdges ); |
| 183 | |
| 184 | PreCutResult res; |
| 185 | res.paths.resize( contours.size() ); |
| 186 | res.oldEdgesInfo.resize( contours.size() ); |
| 187 | res.removedFaces.resize( contours.size() ); |
| 188 | res.edgeData.reserve( size_t( intersectedEdges ) ); |
| 189 | auto oldEdgesSize = mesh.topology.edgeSize(); |
| 190 | for ( int contourId = 0; contourId < contours.size(); ++contourId ) |
| 191 | { |
| 192 | auto& removedFacesInfo = res.removedFaces[contourId]; |
| 193 | auto& oldEdgesInfo = res.oldEdgesInfo[contourId]; |
| 194 | auto& path = res.paths[contourId]; |
| 195 | const auto& inContour = contours[contourId].intersections; |
| 196 | if ( inContour.size() < 2 ) |
| 197 | continue; |
| 198 | bool closed = contours[contourId].closed; |
| 199 | path.resize( inContour.size() - 1 ); |
| 200 | removedFacesInfo.resize( inContour.size() ); |
| 201 | oldEdgesInfo.resize( inContour.size() - 1 ); |
| 202 | VertId newVertId{}; |
| 203 | EdgeId newEdgeId{}; |
| 204 | for ( int intersectionId = 0; intersectionId < inContour.size(); ++intersectionId ) |
| 205 | { |
| 206 | newVertId = {}; newEdgeId = {}; |
| 207 | |
| 208 | const auto& inter = inContour[intersectionId]; |
| 209 | bool isVert = std::holds_alternative<VertId>( inter.primitiveId ); |
| 210 | bool isNextVert{false}; |
| 211 | if ( intersectionId + 1 < inContour.size() || !closed ) |
| 212 | { |
| 213 | if ( isVert ) |
| 214 | newVertId = std::get<VertId>( inter.primitiveId ); |
| 215 | else |
| 216 | { |
no test coverage detected