| 12 | { |
| 13 | |
| 14 | Expected<Mesh> makeRegularGridMesh( size_t width, size_t height, |
| 15 | const RegularGridLatticeValidator& validator, |
| 16 | const RegularGridLatticePositioner& positioner, |
| 17 | const RegularGridMeshFaceValidator& faceValidator, |
| 18 | ProgressCallback cb ) |
| 19 | { |
| 20 | MR_TIMER; |
| 21 | Mesh res; |
| 22 | |
| 23 | GridSettings gs = |
| 24 | { |
| 25 | .dim = Vector2i( (int)width - 1, (int)height - 1 ) |
| 26 | }; |
| 27 | |
| 28 | BitSet validGridVerts( width * height ); |
| 29 | gs.vertIds.b.resize( width * height ); |
| 30 | auto result = BitSetParallelForAll( validGridVerts, [&]( size_t p ) |
| 31 | { |
| 32 | auto y = p / width; |
| 33 | auto x = p - y * width; |
| 34 | if ( validator( x, y ) ) |
| 35 | validGridVerts.set( p ); |
| 36 | else |
| 37 | gs.vertIds.b[p] = VertId{}; |
| 38 | }, subprogress( cb, 0.0f, 0.1f ) ); |
| 39 | |
| 40 | if ( !result ) |
| 41 | return unexpectedOperationCanceled(); |
| 42 | |
| 43 | VertId nextVertId{ 0 }; |
| 44 | for ( auto p : validGridVerts ) |
| 45 | gs.vertIds.b[p] = nextVertId++; |
| 46 | |
| 47 | const auto vertSize = size_t( nextVertId ); |
| 48 | gs.vertIds.tsize = vertSize; |
| 49 | res.points.resize( vertSize ); |
| 50 | result = BitSetParallelFor( validGridVerts, [&]( size_t p ) |
| 51 | { |
| 52 | auto y = p / width; |
| 53 | auto x = p - y * width; |
| 54 | res.points[gs.vertIds.b[p]] = positioner( x, y ); |
| 55 | }, subprogress( cb, 0.1f, 0.2f ) ); |
| 56 | |
| 57 | if ( !result ) |
| 58 | return unexpectedOperationCanceled(); |
| 59 | |
| 60 | BitSet validLoUpTris( 2 * ( width - 1 ) * ( height - 1 ) ); |
| 61 | BitSet diagonalA( ( width - 1 ) * ( height - 1 ) ); // if one of triangles is valid |
| 62 | |
| 63 | auto getVertId = [&]( Vector2i pos ) -> VertId |
| 64 | { |
| 65 | if ( pos.x < 0 || pos.x >= width || pos.y < 0 || pos.y >= height ) |
| 66 | return VertId(); |
| 67 | return gs.vertIds.b[pos.x + pos.y * width]; |
| 68 | }; |
| 69 | |
| 70 | gs.faceIds.b.resize( validLoUpTris.size() ); |
| 71 | result = BitSetParallelForAll( diagonalA, [&]( size_t p ) |