| 206 | } |
| 207 | |
| 208 | Expected<HoleFillPlan> fillContours2DPlan( const Mesh& mesh, EdgeId holeEdgeId ) |
| 209 | { |
| 210 | auto projInput = projectHoles( mesh, { holeEdgeId } ); |
| 211 | if ( !projInput.has_value() ) |
| 212 | return unexpected( std::move( projInput.error() ) ); |
| 213 | |
| 214 | auto fillRes = fillProjected( mesh.topology, *projInput ); |
| 215 | if ( !fillRes.has_value() ) |
| 216 | return unexpected( std::move( fillRes.error() ) ); |
| 217 | |
| 218 | assert( fillRes->paths.size() == 1 ); // should be validated in fillProjected |
| 219 | |
| 220 | const auto& pTp = fillRes->mesh.topology; |
| 221 | const auto& ip = projInput->paths[0]; |
| 222 | auto& np = fillRes->paths[0]; |
| 223 | HoleFillPlan res; |
| 224 | res.numTris = pTp.numValidFaces(); |
| 225 | if ( res.numTris == 1 ) |
| 226 | return res; |
| 227 | auto size = int( np.size() ); |
| 228 | assert( size > 3 ); |
| 229 | res.items.reserve( size - 3 ); |
| 230 | |
| 231 | for ( ;;) |
| 232 | { |
| 233 | for ( int i0 = 0; i0 < np.size(); ++i0 ) |
| 234 | { |
| 235 | auto e0 = np[i0]; |
| 236 | if ( !e0 ) |
| 237 | continue; // skip unused/encoded |
| 238 | auto i1 = int( pTp.dest( np[i0] ) ); |
| 239 | if ( i1 < 0 ) |
| 240 | return unexpected( "Incorrect filling" ); // most likely due to ties in input contour |
| 241 | auto e1 = np[i1]; |
| 242 | auto ne = pTp.next( e0 ); |
| 243 | auto dest = pTp.dest( ne ); |
| 244 | if ( dest != pTp.dest( e1 ) ) |
| 245 | continue; |
| 246 | FillHoleItem fhi; |
| 247 | int i01 = ( i0 + 1 ) % size; |
| 248 | fhi.edgeCode1 = i1 == i01 ? ip[i0] : int( np[i01] ); |
| 249 | i1 = dest; |
| 250 | e1 = np[i1]; |
| 251 | if ( !e1 ) |
| 252 | return unexpected( "Incorrect filling" ); // most likely due to ties in input contour |
| 253 | int i11 = ( i1 + 1 ) % size; |
| 254 | fhi.edgeCode2 = ( pTp.dest( e1 ) == i11 ) ? ip[i1] : int( np[i11] ); |
| 255 | res.items.push_back( std::move( fhi ) ); |
| 256 | if ( res.items.size() == size - 3 ) |
| 257 | return res; |
| 258 | np[i0] = ne; |
| 259 | np[i01] = EdgeId( -int( res.items.size() ) ); // encode newly created plan edge in free slot |
| 260 | } |
| 261 | } |
| 262 | } |
| 263 | |
| 264 | Expected<void> fillPlanarHole( ObjectMeshData& data, std::vector<EdgeLoop>& holeContours ) |
| 265 | { |
no test coverage detected