| 121 | } |
| 122 | |
| 123 | std::optional<VertBitSet> verticesGridSampling( const MeshPart & mp, float voxelSize, const ProgressCallback & cb ) |
| 124 | { |
| 125 | MR_TIMER; |
| 126 | if (voxelSize <= 0.f) |
| 127 | { |
| 128 | if ( mp.region ) |
| 129 | return getIncidentVerts( mp.mesh.topology, *mp.region ); |
| 130 | |
| 131 | return mp.mesh.topology.getValidVerts(); |
| 132 | } |
| 133 | |
| 134 | const auto bbox = mp.mesh.computeBoundingBox( mp.region ); |
| 135 | const auto bboxSz = bbox.max - bbox.min; |
| 136 | constexpr float maxVoxelsInOneDim = 1 << 10; |
| 137 | const Vector3i dims |
| 138 | { |
| 139 | (int) std::min( std::ceil( bboxSz.x / voxelSize ), maxVoxelsInOneDim ), |
| 140 | (int) std::min( std::ceil( bboxSz.y / voxelSize ), maxVoxelsInOneDim ), |
| 141 | (int) std::min( std::ceil( bboxSz.z / voxelSize ), maxVoxelsInOneDim ) |
| 142 | }; |
| 143 | |
| 144 | Grid grid( bbox, dims ); |
| 145 | if ( cb && !cb( 0.1f ) ) |
| 146 | return {}; |
| 147 | |
| 148 | VertBitSet store; |
| 149 | const auto& regionVerts = getIncidentVerts( mp.mesh.topology, mp.region, store ); |
| 150 | int counter = 0; |
| 151 | int size = int( regionVerts.count() ); |
| 152 | for ( auto v : regionVerts ) |
| 153 | { |
| 154 | grid.addVertex( mp.mesh.points[v], v ); |
| 155 | if ( !reportProgress( cb, [&]{ return 0.1f + 0.8f * float( counter ) / float( size ); }, counter++, 1024 ) ) |
| 156 | return {}; |
| 157 | } |
| 158 | |
| 159 | const auto res = grid.getSamples(); |
| 160 | if ( cb && !cb( 1.0f ) ) |
| 161 | return {}; |
| 162 | |
| 163 | return res; |
| 164 | } |
| 165 | |
| 166 | std::optional<VertBitSet> pointGridSampling( const PointCloudPart& pcp, float voxelSize, const ProgressCallback & cb ) |
| 167 | { |