| 20 | } |
| 21 | |
| 22 | int main( int argc, char* argv[] ) |
| 23 | { |
| 24 | if ( argc < 4 ) |
| 25 | { |
| 26 | std::cerr << "Usage: " << argv[0] << " INPUT1 INPUT2 [INPUTS...] OUTPUT" << std::endl; |
| 27 | return EXIT_FAILURE; |
| 28 | } |
| 29 | |
| 30 | // the global registration can be applied to meshes and point clouds |
| 31 | // to simplify the sample app, we will work with point clouds only |
| 32 | std::vector<MR::PointCloud> inputs; |
| 33 | // as ICP and MultiwayICP classes accept both meshes and point clouds, |
| 34 | // the input data must be converted to special wrapper objects |
| 35 | // NB: the wrapper objects hold *references* to the source data, NOT their copies |
| 36 | MR::ICPObjects objects; |
| 37 | MR::Box3f maxBBox; |
| 38 | for ( auto i = 1; i < argc - 1; ++i ) |
| 39 | { |
| 40 | auto pointCloud = MR::PointsLoad::fromAnySupportedFormat( argv[i] ); |
| 41 | if ( !pointCloud ) |
| 42 | { |
| 43 | std::cerr << "Failed to load point cloud: " << pointCloud.error() << std::endl; |
| 44 | return EXIT_FAILURE; |
| 45 | } |
| 46 | |
| 47 | auto bbox = pointCloud->computeBoundingBox(); |
| 48 | if ( !maxBBox.valid() || bbox.volume() > maxBBox.volume() ) |
| 49 | maxBBox = bbox; |
| 50 | |
| 51 | inputs.emplace_back( std::move( *pointCloud ) ); |
| 52 | // you may also set an affine transformation for each input as a second argument |
| 53 | objects.push_back( { inputs.back(), {} } ); |
| 54 | } |
| 55 | |
| 56 | // you can set various parameters for the global registration; see the documentation for more info |
| 57 | MR::MultiwayICP icp( objects, { |
| 58 | // set sampling voxel size |
| 59 | .samplingVoxelSize = maxBBox.diagonal() * 0.03f, |
| 60 | } ); |
| 61 | |
| 62 | icp.setParams( {} ); |
| 63 | |
| 64 | // gather statistics |
| 65 | icp.updateAllPointPairs(); |
| 66 | printStats( icp ); |
| 67 | |
| 68 | std::cout << "Calculating transformations..." << std::endl; |
| 69 | auto xfs = icp.calculateTransformations(); |
| 70 | printStats( icp ); |
| 71 | |
| 72 | MR::PointCloud output; |
| 73 | for ( auto i = MR::ObjId( 0 ); i < inputs.size(); ++i ) |
| 74 | { |
| 75 | const auto& input = inputs[i]; |
| 76 | const auto& xf = xfs[i]; |
| 77 | for ( const auto& point : input.points ) |
| 78 | output.points.emplace_back( xf( point ) ); |
| 79 | } |
nothing calls this directly
no test coverage detected