This comprehensive code sample includes the essential scanning and processing steps to produce a complete 3D model.The code initializes the scanner and captures a series of frames, registers and processes, then combines them into a single 3D mesh. Functions in the artec::sdk::algorithms namespace handle the processing. Using this sample you can store models, both textured and untextured as well as raw frames into OBJ file. The final step is to display a model in a 3D viewer by calling meshContainer directly.
#include <iomanip>
#include <iostream>
#include "ScenePresenter.h"
namespace asdk {
};
using asdk::TRef;
const int NumberOfFramesToCapture = 100;
#define ENABLE_TEXTURE_MAPPING
#define OUTPUT_DIR L"scans"
#define SDK_STRINGIFY(x) #x
#define SDK_STRING(x) SDK_STRINGIFY(x)
#define SAFE_SDK_CALL(x)                                                 \
{                                                                        \
    asdk::ErrorCode ec = (x);                                            \
    if ( ec != asdk::ErrorCode_OK )                                      \
    {                                                                    \
        reportError( ec, __FILE__ " [ line " SDK_STRING(__LINE__) " ]"); \
        return ec;                                                       \
    }                                                                    \
}
{
    const wchar_t* msg = L"No error";
    switch( ec ){
        msg = L"Not enough storage is available to process the operation";
        break;
        msg = L"Provided argument is invalid";
        break;
        msg = L"Requested operation is invalid";
        break;
        msg = L"Data format is unsupported or invalid";
        break;
        msg = L"Requested scanner is not connected";
        break;
        msg = L"Requested scanner is not licensed";
        break;
        msg = L"Requested scanner is already used by someone else";
        break;
        msg = L"Scanner initialization failed";
        break;
        msg = L"Frame is corrupted";
        break;
        msg = L"Frame reconstruction failed";
        break;
        msg = L"Frame registration failed";
        break;
        msg = L"Requested operation is unsupported. Check versions";
        break;
        msg = L"Requested operation is denied. Check your license(s)";
        break;
        msg = L"Requested operation has failed";
        break;
        msg = L"Requested operation was canceled from client's side";
        break;
        msg = L"Unable to start algorithm because input data turned out to be invalid. Please rescan the object.";
        break;
    default:
        msg = L"Unexplained error";
        break;
    }
    std::wcerr << msg << " [error " << std::hex << ec << "] " << "at " << place << std::endl;
}
class SimpleScannerObserver : public asdk::ScannerObserverBase
{
public:
    
    {
        switch(button)
        {
            std::wcout << L"ScannerEvent: trigger button was pressed" << std::endl;
            break;
            std::wcout << L"ScannerEvent: stop button was pressed" << std::endl;
            break;
            std::wcout << L"ScannerEvent: record button was pressed" << std::endl;
            break;
        default:
            std::wcout << L"ScannerEvent: unknown button was pressed" << std::endl;
            break;
        }
    }
    virtual void deviceOverheated()
    {
        std::wcout << L"ScannerEvent: device is overheated" << std::endl;
    }
    virtual void deviceTemperatureBackToNormal()
    {
        std::wcout << L"ScannerEvent: device temperature is back to normal" << std::endl;
    }
    virtual void deviceDisconnected()
    {
        std::wcout << L"ScannerEvent : device was disconnected" << std::endl;
    }
};
asdk::ErrorCode createSimpleScannerObserver( asdk::IScannerObserver** observer )
 
{
    *observer = new SimpleScannerObserver();
}
{
    std::wcout << L"Looking for scanner..." << std::endl;
    {
        std::wcout << L"No scanners found" << std::endl;
        return errorCode;
    }
    std::wcout << L"OK" << std::endl;
    std::wcout << L"Found scanner with serial number " << scanner->getId()->serial  << std::endl;
    std::wcout << L"Setting the scanner event handler..." << std::endl;
    createSimpleScannerObserver( &observer );
    SAFE_SDK_CALL( scanner->setObserver( observer ) );
    std::wcout << L"OK" << std::endl;
    std::wcout << L"Scanner is ready, press ENTER to start" << std::endl;
    std::wcin.setf( ~std::ios::skipws, std::ios::skipws );
    std::wcin.get();
    std::wcout << L"Creating scanning procedure..." << std::endl;
    asdk::ScanningProcedureSettings desc = { 0 };
    desc.maxFrameCount = NumberOfFramesToCapture;
    desc.pipelineConfiguration =
    ;
    desc.captureTextureFrequency = 10;
    desc.ignoreRegistrationErrors = false;
    std::wcout << L"OK" << std::endl;
    std::wcout << L"Launching scanning procedure in a fully automatic mode..." << std::endl;
    SAFE_SDK_CALL( 
executeJob( scanning, &workset ) );
    std::wcout << L"OK" << std::endl;
    std::wcout << L"Preparing workset for further processing..." << std::endl;
    std::swap( workset.in, workset.out );
    workset.out->clear();
    std::wcout << L"OK" << std::endl;
}
asdk::ErrorCode AlgorithmProcessingSample( asdk::AlgorithmWorkset& workset  )
 
{
    
    
    {
        std::wcout << L"Creating serial registration procedure..." << std::endl;
        asdk::SerialRegistrationSettings serialDesc = {
        };
        std::wcout << L"OK" << std::endl;
        std::wcout << L"Launching the serial registration algorithm..." << std::endl;
        std::wcout << L"OK" << std::endl;
    }
    
    std::swap( workset.in, workset.out );
    workset.out->clear();
    
    {
        std::wcout << L"Creating global registration procedure..." << std::endl;
        asdk::GlobalRegistrationSettings globalDesc = {
        };
        std::wcout << L"OK" << std::endl;
        std::wcout << L"Launching the global registration algorithm..." << std::endl;
        std::wcout << L"OK" << std::endl;
    }
    
    std::swap( workset.in, workset.out );
    workset.out->clear();
    
    {
        std::wcout << L"Creating outliers removal procedure..." << std::endl;
        asdk::OutliersRemovalSettings outliersDesc;
        
        std::wcout << L"OK" << std::endl;
        std::wcout << L"Launching the outliers removal algorithm..." << std::endl;
        std::wcout << L"OK" << std::endl;
    }
    
    std::swap( workset.in, workset.out );
    workset.out->clear();
    
    {
        std::wcout << L"Creating fast fusion procedure..." << std::endl;
        asdk::FastFusionSettings fusionDesc;
        
        fusionDesc.resolution = 2.f;
        std::wcout << L"OK" << std::endl;
        std::wcout << L"Launching the fast fusion algorithm..." << std::endl;
        std::wcout << L"OK" << std::endl;
    }
    std::wcout << L"Preparing workset for further processing..." << std::endl;
    std::swap( workset.in, workset.out );
    workset.out->clear();
    std::wcout << L"OK" << std::endl;
}
#ifdef ENABLE_TEXTURE_MAPPING
{
    
    
    {
        std::wcout << L"Creating texture mapping procedure..." << std::endl;
        asdk::TexturizationSettings textureDesc;
        
        std::wcout << L"OK" << std::endl;
        std::wcout << L"Launching the texture mapping algorithm..." << std::endl;
        std::wcout << L"OK" << std::endl;
    }
    std::wcout << L"Preparing workset for further processing..." << std::endl;
    std::swap( workset.in, workset.out );
    workset.out->clear();
    std::wcout << L"OK" << std::endl;
}
#endif
int main( int argc, char **argv )
{
    
    
    
    
    
    
    
    asdk::AlgorithmWorkset workset = { inputContainer, outputContainer, 0, ctSource->getToken(), 0 };
    {
        std::wcout << L"Finishing work on errors when scanning..." << std::endl;
        return (int)errorCode;
    }
    errorCode = AlgorithmProcessingSample( workset );
    {
        std::wcout << L"Finishing work on errors when processing..." << std::endl;
        return (int)errorCode;
    }
    #ifdef SAVE_FUSION_MESH_ON
    
    {
        asdk::ICompositeContainer* meshContainer = workset.in->getCompositeContainer();
        if( meshContainer && meshContainer->getSize() > 0 )
        {
            asdk::ICompositeMesh* resultMesh = meshContainer->getElement( 0 );
            std::wcout << L"Saving the resulting mesh to an OBJ file..." << std::endl;
            const wchar_t* filename = OUTPUT_DIR L"\\untextured-mesh.obj";
            {
                std::wcout << L"Cannot open file '" << filename << L"'" << std::endl;
                std::wcout << L"skipped" << std::endl;
            }
            else
            {
                std::wcout << L"OK" << std::endl;
            }
        }
    }
    
    {
        std::wcout << L"Saving all the reconstructed frames to separate OBJ files..." << std::endl;
        for( int ix = 0;  ix < workset.in->getSize(); ix++ )
        {
            for( int jx = 0; jx < scan->getSize(); jx++ )
            {
                std::wstring pathFormat( OUTPUT_DIR L"\\frame-S%02dF%02d.obj" );
                std::vector<wchar_t> pathBuffer( pathFormat.size() +1 );
                std::swprintf( pathBuffer.data(), pathBuffer.size(), pathFormat.c_str(), ix, jx );
                {
                    std::wcout << L"Cannot open file '" << pathBuffer.data() << "'" << std::endl;
                    std::wcout << L"skipped" << std::endl;
                    break;
                }
            }
        }
        {
            std::wcout << L"OK" << std::endl;
        }
    }
    #endif
    #ifdef ENABLE_TEXTURE_MAPPING
    errorCode = TextureProcessingSample( workset );
    {
        std::wcout << L"failed" << std::endl;
        std::wcout << L"Continue to work withstanding errors when texturing..." << std::endl;
    }
    else
    {
        #ifdef SAVE_TEXTURED_MESH_ON
        
        {
            asdk::ICompositeContainer* meshContainer = workset.in->getCompositeContainer();
            if( meshContainer && meshContainer->getSize() > 0 )
            {
                asdk::ICompositeMesh* resultMesh = meshContainer->getElement( 0 );
                std::wcout << L"Saving the resulting textured mesh to an OBJ file..." << std::endl;
                const wchar_t* filename = OUTPUT_DIR L"\\textured-mesh.obj";
                {
                    std::wcout << L"Cannot open file '" << filename << "'" << std::endl;
                    std::wcout << L"skipped" << std::endl;
                }
                else
                {
                    std::wcout << L"OK" << std::endl;
                }
            }
        }
        #endif
    }
    #endif
    
    {
        asdk::ICompositeContainer* meshContainer = workset.in->getCompositeContainer();
        if( meshContainer && meshContainer->getSize() > 0 )
        {
            asdk::ICompositeMesh* resultMesh = meshContainer->getElement( 0 );
            std::wcout << L"Showing the resulting mesh..." << std::endl;
            SAFE_SDK_CALL( DisplayScene( *resultMesh ) );
            std::wcout << L"OK" << std::endl;
        }
    }
    std::wcout << L"Finishing work with capturing library..." << std::endl;
    return (int)errorCode;
}