| 15 | { |
| 16 | |
| 17 | Expected<SimpleVolumeMinMax> meshToDistanceVolume( const MeshPart& mp, const MeshToDistanceVolumeParams& cParams /*= {} */ ) |
| 18 | { |
| 19 | MR_TIMER; |
| 20 | if ( cParams.dist.signMode == SignDetectionMode::OpenVDB ) |
| 21 | { |
| 22 | MeshToVolumeParams m2vPrams |
| 23 | { |
| 24 | .type = MeshToVolumeParams::Type::Signed, |
| 25 | .voxelSize = cParams.vol.voxelSize, |
| 26 | // SimpleVolume and VdbVolume are shifted on half voxel relative one another, see also VoxelsVolumeAccessor::shift() |
| 27 | .worldXf = AffineXf3f::translation( -cParams.vol.origin - 0.5f * cParams.vol.voxelSize ), |
| 28 | .cb = subprogress( cParams.vol.cb, 0.0f, 0.8f ) |
| 29 | }; |
| 30 | assert( cParams.dist.maxDistSq < FLT_MAX ); // the amount of work is proportional to maximal distance |
| 31 | if ( cParams.dist.maxDistSq < FLT_MAX ) |
| 32 | { |
| 33 | m2vPrams.surfaceOffset = std::sqrt( cParams.dist.maxDistSq ) |
| 34 | / std::min( { cParams.vol.voxelSize.x, cParams.vol.voxelSize.y, cParams.vol.voxelSize.z } ); |
| 35 | } |
| 36 | return meshToDistanceVdbVolume( mp, m2vPrams ).and_then( |
| 37 | [&cParams]( VdbVolume && vdbVolume ) |
| 38 | { |
| 39 | return vdbVolumeToSimpleVolume( vdbVolume, Box3i{ Vector3i( 0, 0, 0 ), cParams.vol.dimensions }, subprogress( cParams.vol.cb, 0.8f, 1.0f ) ); |
| 40 | } ); |
| 41 | } |
| 42 | |
| 43 | auto params = cParams; |
| 44 | if ( params.dist.signMode == SignDetectionMode::HoleWindingRule ) |
| 45 | { |
| 46 | SimpleVolumeMinMax res; |
| 47 | res.voxelSize = params.vol.voxelSize; |
| 48 | res.dims = params.vol.dimensions; |
| 49 | VolumeIndexer indexer( res.dims ); |
| 50 | res.data.resize( indexer.size() ); |
| 51 | |
| 52 | if ( !params.fwn ) |
| 53 | params.fwn = std::make_shared<FastWindingNumber>( mp.mesh ); |
| 54 | assert( !mp.region ); // only whole mesh is supported for now |
| 55 | auto basis = AffineXf3f( Matrix3f::scale( params.vol.voxelSize ), params.vol.origin + 0.5f * params.vol.voxelSize ); |
| 56 | if ( auto d = params.fwn->calcFromGridWithDistances( res.data.vec_, res.dims, basis, params.dist, params.vol.cb ); !d ) |
| 57 | { |
| 58 | return unexpected( std::move( d.error() ) ); |
| 59 | } |
| 60 | std::tie( res.min, res.max ) = parallelMinMax( res.data ); |
| 61 | return res; |
| 62 | } |
| 63 | |
| 64 | const auto func = meshToDistanceFunctionVolume( mp, params ); |
| 65 | return functionVolumeToSimpleVolume( func, params.vol.cb ); |
| 66 | |
| 67 | } |
| 68 | |
| 69 | FunctionVolume meshToDistanceFunctionVolume( const MeshPart& mp, const MeshToDistanceVolumeParams& params ) |
| 70 | { |
nothing calls this directly
no test coverage detected