| 199 | } |
| 200 | |
| 201 | Expected<void> meshDenoiseViaNormals( Mesh & mesh, const DenoiseViaNormalsSettings & settings ) |
| 202 | { |
| 203 | MR_TIMER; |
| 204 | if ( settings.normalIters <= 0 || settings.pointIters <= 0 ) |
| 205 | { |
| 206 | assert( false ); |
| 207 | return unexpected( "Bad parameters" ); |
| 208 | } |
| 209 | |
| 210 | if ( !reportProgress( settings.cb, 0.0f ) ) |
| 211 | return unexpectedOperationCanceled(); |
| 212 | |
| 213 | auto fnormals0 = computePerFaceNormals( mesh ); |
| 214 | Vector<float, UndirectedEdgeId> v( mesh.topology.undirectedEdgeSize(), 1 ); |
| 215 | |
| 216 | if ( !reportProgress( settings.cb, 0.05f ) ) |
| 217 | return unexpectedOperationCanceled(); |
| 218 | |
| 219 | auto sp = subprogress( settings.cb, 0.05f, 0.95f ); |
| 220 | FaceNormals fnormals; |
| 221 | for ( int i = 0; i < settings.normalIters; ++i ) |
| 222 | { |
| 223 | fnormals = fnormals0; |
| 224 | denoiseNormals( mesh, fnormals, v, settings.gamma ); |
| 225 | if ( !reportProgress( sp, float( 2 * i ) / ( 2 * settings.normalIters ) ) ) |
| 226 | return unexpectedOperationCanceled(); |
| 227 | |
| 228 | if ( settings.fastIndicatorComputation ) |
| 229 | updateIndicatorFast( mesh.topology, v, fnormals, settings.beta, settings.gamma ); |
| 230 | else |
| 231 | updateIndicator( mesh, v, fnormals, settings.beta, settings.gamma ); |
| 232 | if ( !reportProgress( sp, float( 2 * i + 1 ) / ( 2 * settings.normalIters ) ) ) |
| 233 | return unexpectedOperationCanceled(); |
| 234 | } |
| 235 | |
| 236 | if ( settings.outCreases ) |
| 237 | { |
| 238 | settings.outCreases->clear(); |
| 239 | settings.outCreases->resize( mesh.topology.undirectedEdgeSize() ); |
| 240 | BitSetParallelForAll( *settings.outCreases, [&]( UndirectedEdgeId ue ) |
| 241 | { |
| 242 | if ( v[ue] < 0.5f ) |
| 243 | settings.outCreases->set( ue ); |
| 244 | } ); |
| 245 | } |
| 246 | |
| 247 | if ( !reportProgress( settings.cb, 0.95f ) ) |
| 248 | return unexpectedOperationCanceled(); |
| 249 | |
| 250 | const auto guide = mesh.points; |
| 251 | NormalsToPoints n2p; |
| 252 | n2p.prepare( mesh.topology, settings.guideWeight ); |
| 253 | auto maxInitialDistSq = settings.limitNearInitial ? sqr( settings.maxInitialDist ) |
| 254 | : std::numeric_limits<float>::infinity(); |
| 255 | for ( int i = 0; i < settings.pointIters; ++i ) |
| 256 | n2p.run( guide, fnormals, mesh.points, maxInitialDistSq ); |
| 257 | |
| 258 | reportProgress( settings.cb, 1.0f ); |
no test coverage detected