MeshLib
 
Loading...
Searching...
No Matches
Global registration

Example of global registration usage:

#include <MRMeshC/MRBox.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// print progress every 10%
int gProgress = -1;
bool onProgress( float v )
{
int progress = (int)( 10.f * v );
if ( progress != gProgress )
{
gProgress = progress;
printf( "%d%%...\n", progress * 10 );
}
return true;
}
void resetProgress( void )
{
gProgress = -1;
}
void printStats( const MRMultiwayICP* icp )
{
size_t numSamples = mrMultiWayICPGetNumSamples( icp );
size_t numActivePairs = mrMultiWayICPGetNumActivePairs( icp );
printf( "Samples: %zu\n", numSamples );
printf( "Active point pairs: %zu\n", numActivePairs );
if ( numActivePairs > 0 )
{
double p2ptMetric = mrMultiWayICPGetMeanSqDistToPoint( icp, NULL );
double p2ptInaccuracy = mrMultiWayICPGetMeanSqDistToPoint( icp, &p2ptMetric );
printf( "RMS point-to-point distance: %f ± %f\n", p2ptMetric, p2ptInaccuracy );
double p2plMetric = mrMultiWayICPGetMeanSqDistToPlane( icp, NULL );
double p2plInaccuracy = mrMultiWayICPGetMeanSqDistToPlane( icp, &p2plMetric );
printf( "RMS point-to-plane distance: %f ± %f\n", p2plMetric, p2plInaccuracy );
}
}
int main( int argc, char* argv[] )
{
int rc = EXIT_FAILURE;
if ( argc < 4 )
{
fprintf( stderr, "Usage: %s INPUT1 INPUT2 [INPUTS...] OUTPUT\n", argv[0] );
goto out;
}
// error messages will be stored here
MRString* errorString = NULL;
// the global registration can be applied to meshes and point clouds
// to simplify the sample app, we will work with point clouds only
const int inputNum = argc - 2;
MRPointCloud** inputs = malloc( sizeof( MRPointCloud* ) * inputNum );
memset( inputs, 0, sizeof( MRPointCloud* ) * inputNum );
// as ICP and MultiwayICP classes accept both meshes and point clouds,
// the input data must be converted to special wrapper objects
// NB: the wrapper objects hold *references* to the source data, NOT their copies
MRMeshOrPointsXf** inputXfs = malloc( sizeof( MRMeshOrPointsXf* ) * inputNum );
memset( inputXfs, 0, sizeof( MRMeshOrPointsXf* ) * inputNum );
MRBox3f maxBBox = mrBox3fNew();
for ( int i = 0; i < inputNum; ++i )
{
inputs[i] = mrPointsLoadFromAnySupportedFormat( argv[1 + i], &errorString );
if ( errorString )
{
fprintf( stderr, "Failed to load point cloud: %s\n", mrStringData( errorString ) );
mrStringFree( errorString );
goto out_inputs;
}
// you may also set an affine transformation for each input as a second argument
inputXfs[i] = mrMeshOrPointsXfFromPointCloud( inputs[i], NULL ); // or mrMeshOrPointsXfFromMesh for meshes
MRBox3f bbox = mrPointCloudComputeBoundingBox( inputs[i], NULL );
if ( !mrBox3fValid( &maxBBox ) || mrBox3fVolume( &bbox ) > mrBox3fVolume( &maxBBox ) )
maxBBox = bbox;
}
// you can set various parameters for the global registration; see the documentation for more info
// set sampling voxel size
samplingParams.samplingVoxelSize = mrBox3fDiagonal( &maxBBox ) * 0.03f;
// set progress callback
samplingParams.cb = onProgress;
MRMultiwayICP* icp = mrMultiwayICPNew( *inputXfs, inputNum, &samplingParams );
mrMultiwayICPSetParams( icp, &params );
// gather statistics
printStats( icp );
printf( "Calculating transformations...\n" );
resetProgress();
printStats( icp );
for ( int i = 0; i < inputNum; i++ )
{
const MRAffineXf3f* xf = mrVectorAffineXf3fData( xfs ) + i;
for ( int j = 0; j < mrPointCloudPointsNum( inputs[i] ); j++ )
{
MRVector3f* point = mrPointCloudPointsRef( inputs[i] ) + j;
mrAffineXf3fApply( xf, point );
mrPointCloudAddPoint( output, point );
}
}
mrPointsSaveToAnySupportedFormat( output, argv[argc - 1], &errorString );
if ( errorString )
{
fprintf( stderr, "Failed to save point cloud: %s\n", mrStringData( errorString ) );
mrStringFree( errorString );
goto out_output;
}
rc = EXIT_SUCCESS;
out_output:
mrPointCloudFree( output );
out_xfs:
out_icp:
out_inputs:
for ( int i = 0; i < inputNum; i++ )
{
mrMeshOrPointsXfFree( inputXfs[i] );
mrPointCloudFree( inputs[i] );
}
free( inputXfs );
free( inputs );
out:
return rc;
}
MRMESHC_API MRVector3f mrAffineXf3fApply(const MRAffineXf3f *xf, const MRVector3f *v)
application of the transformation to a point
MRMESHC_API MRBox3f mrBox3fNew(void)
creates invalid box by default
MRMESHC_API float mrBox3fDiagonal(const MRBox3f *box)
computes length from min to max
MRMESHC_API bool mrBox3fValid(const MRBox3f *box)
true if the box contains at least one point
MRMESHC_API float mrBox3fVolume(const MRBox3f *box)
computes the volume of this box
MRMESHC_API MRICPProperties mrICPPropertiesNew(void)
initializes a default instance
struct MRPointCloud MRPointCloud
Definition MRMeshC/MRMeshFwd.h:49
typedefMR_EXTERN_C_BEGIN struct MRString MRString
Definition MRMeshC/MRMeshFwd.h:32
struct MRMeshOrPointsXf MRMeshOrPointsXf
an object and its transformation to global space with other objects
Definition MRMeshC/MRMeshOrPoints.h:20
MRMESHC_API void mrMeshOrPointsXfFree(MRMeshOrPointsXf *mp)
destructs a MeshOrPointsXf object
MRMESHC_API MRMeshOrPointsXf * mrMeshOrPointsXfFromPointCloud(const MRPointCloud *pc, const MRAffineXf3f *xf)
struct MRMultiwayICP MRMultiwayICP
Definition MRMeshC/MRMultiwayICP.h:37
MRMESHC_API MRMultiwayICPSamplingParameters mrMultiwayIcpSamplingParametersNew(void)
initializes a default instance
MRMESHC_API size_t mrMultiWayICPGetNumSamples(const MRMultiwayICP *mwicp)
computes the number of samples able to form pairs
MRMESHC_API float mrMultiWayICPGetMeanSqDistToPoint(const MRMultiwayICP *mwicp, double *value)
MRMESHC_API void mrMultiwayICPFree(MRMultiwayICP *mwicp)
deallocates a MultiwayICP object
MRMESHC_API bool mrMultiwayICPUpdateAllPointPairs(MRMultiwayICP *mwicp, MRProgressCallback cb)
MRMESHC_API size_t mrMultiWayICPGetNumActivePairs(const MRMultiwayICP *mwicp)
computes the number of active point pairs
MRMESHC_API float mrMultiWayICPGetMeanSqDistToPlane(const MRMultiwayICP *mwicp, double *value)
MRMESHC_API size_t mrPointCloudPointsNum(const MRPointCloud *pc)
MR_EXTERN_C_BEGIN MRMESHC_API MRPointCloud * mrPointCloudNew(void)
creates a new PointCloud object
MRMESHC_API MRBox3f mrPointCloudComputeBoundingBox(const MRPointCloud *pc, const MRAffineXf3f *toWorld)
MRMESHC_API void mrPointCloudFree(MRPointCloud *pc)
deallocates a PointCloud object
MRMESHC_API MRVector3f * mrPointCloudPointsRef(MRPointCloud *pc)
MRMESHC_API MRVertId mrPointCloudAddPoint(MRPointCloud *pc, const MRVector3f *point_)
appends a point and returns its VertId
MRMESHC_API void mrStringFree(MRString *str)
deallocates the string object
MR_EXTERN_C_BEGIN MRMESHC_API const char * mrStringData(const MRString *str)
gets read-only access to the string data
MRMESHC_API void mrVectorAffineXf3fFree(MRVectorAffineXf3f *vec)
MRMESHC_API const MRAffineXf3f * mrVectorAffineXf3fData(const MRVectorAffineXf3f *vec)
typedefMR_EXTERN_C_BEGIN struct MRVectorAffineXf3f MRVectorAffineXf3f
Definition MRMeshC/MRVector.h:8
MRMESHC_API MRMultiwayICP * mrMultiwayICPNew(const MRMeshOrPointsXf *objects, size_t objectsNum, const MRMultiwayICPSamplingParameters *samplingParams)
MRMESHC_API MRPointCloud * mrPointsLoadFromAnySupportedFormat(const char *filename, MRString **errorString)
detects the format from file extension and loads points from it
MRMESHC_API void mrPointsSaveToAnySupportedFormat(const MRPointCloud *pc, const char *file, MRString **errorString)
detects the format from file extension and save points to it
MRMESHC_API void mrMultiwayICPSetParams(MRMultiwayICP *mwicp, const MRICPProperties *prop)
tune algorithm params before run calculateTransformations()
MRMESHC_API MRVectorAffineXf3f * mrMultiwayICPCalculateTransformations(MRMultiwayICP *mwicp, MRProgressCallback cb)
MRVIEWER_API void point(Element elem, float menuScaling, const Params &params, ImVec2 point)
affine transformation: y = A*x + b, where A in VxV, and b in V
Definition MRMeshC/MRAffineXf.h:10
Definition MRMeshC/MRBox.h:9
Definition MRMeshC/MRICP.h:95
Parameters that are used for sampling of the MultiwayICP objects.
Definition MRMeshC/MRMultiwayICP.h:20
MRProgressCallback cb
callback for progress reports
Definition MRMeshC/MRMultiwayICP.h:28
float samplingVoxelSize
sampling size of each object
Definition MRMeshC/MRMultiwayICP.h:22
three-dimensional vector
Definition MRMeshC/MRVector3.h:9