| 102 | } |
| 103 | |
| 104 | Expected<TeethMaskToDirectionVolumeConvertor::ProcessResult> TeethMaskToDirectionVolumeConvertor::convertObject( int id ) const |
| 105 | { |
| 106 | Box3i box; |
| 107 | |
| 108 | if ( auto it = presentObjects_.find( id ); it == presentObjects_.end() ) |
| 109 | return unexpected( fmt::format( "The mask does not contain specified object: {}", id ) ); |
| 110 | else |
| 111 | box = it->second; |
| 112 | |
| 113 | |
| 114 | const VolumeIndexer maskIndexer( mask_.dims ); |
| 115 | |
| 116 | SimpleVolumeMinMax toothMask; |
| 117 | toothMask.dims = box.size(); |
| 118 | toothMask.voxelSize = mask_.voxelSize; |
| 119 | toothMask.data.resize( box.volume() ); |
| 120 | |
| 121 | forEachInSimpleVolume( toothMask, [&box, &fullMask = mask_, &maskIndexer, &id] ( const auto& pt, float& v ) |
| 122 | { |
| 123 | const auto fullPt = pt + box.min; |
| 124 | if ( fullMask.data[maskIndexer.toVoxelId( fullPt )] == id ) |
| 125 | v = ( float )id; |
| 126 | else |
| 127 | v = 0; |
| 128 | } ); |
| 129 | |
| 130 | std::tie( toothMask.min, toothMask.max ) = parallelMinMax( toothMask.data ); |
| 131 | |
| 132 | auto toothMaskVdb = simpleVolumeToVdbVolume( toothMask ); |
| 133 | |
| 134 | return |
| 135 | gridToMesh( toothMaskVdb.data, GridToMeshSettings{ |
| 136 | .voxelSize = toothMask.voxelSize, |
| 137 | .isoValue = static_cast<float>( id ) - 0.001f |
| 138 | } ) |
| 139 | .and_then( [voxelSize = toothMask.voxelSize, boxV = box] ( Mesh&& mesh ) |
| 140 | { |
| 141 | Box3f box( mult( Vector3f( boxV.min ), voxelSize ), mult( Vector3f( boxV.max ), voxelSize ) ); |
| 142 | const auto xf = AffineXf3f::translation( box.min + voxelSize ); |
| 143 | |
| 144 | MeshToDirectionVolumeParams p; |
| 145 | p.vol.origin = box.min; |
| 146 | p.vol.voxelSize = voxelSize; |
| 147 | p.vol.dimensions = boxV.size(); |
| 148 | p.dist.maxDistSq = 1; |
| 149 | p.dist.minDistSq = 0; |
| 150 | p.projector = std::make_shared<PointsToMeshProjector>(); |
| 151 | |
| 152 | mesh.transform( xf ); |
| 153 | |
| 154 | p.projector->updateMeshData( &mesh ); |
| 155 | return meshToDirectionVolume( p ) |
| 156 | .transform( [&xf] ( DirectionVolume&& volumes ) |
| 157 | { |
| 158 | return ProcessResult{ |
| 159 | .volume = std::move( volumes ), |
| 160 | .xf = xf |
| 161 | }; |
nothing calls this directly
no test coverage detected