Create a application project

QT Creator

Open QTCreator and create a new project (in File menu).

Select Non-Qt project and Plain C++ Application and click on Choose button.

create a Plain C++ application in QT
Figure 1. Plain C++ application creation

Then, set the name of your application (e.g. MySolARApp) that will use a SolAR pipeline, and its location.

Next, define your build system with qmake. For the next step, choose your development kits. We recommend to use MSVC 2017 64bit on Windows or Clang on Linux.

Your project is now created, but as SolAR provides a smart and easy way to build and deploy you pipeline, you will need to update the .pro file. Select it in your project tree, and replace its script by the following one:

MySolARApp.pro
## remove Qt dependencies
QT -= core gui
TARGET = MySolARApp (1)
VERSION=x.x.x (2)

CONFIG += c++1z
CONFIG -= qt
CONFIG += console

DEFINES += MYVERSION=$${VERSION}

CONFIG(debug,debug|release) {
    DEFINES += _DEBUG=1
    DEFINES += DEBUG=1
}

CONFIG(release,debug|release) {
    DEFINES += NDEBUG=1
}

win32:CONFIG -= static
win32:CONFIG += shared

DEPENDENCIESCONFIG = sharedlib recurse
#NOTE : CONFIG as staticlib or sharedlib, DEPENDENCIESCONFIG as staticlib or sharedlib, QMAKE_TARGET.arch and PROJECTDEPLOYDIR MUST BE DEFINED BEFORE templatelibconfig.pri inclusion
include (../../builddefs/qmake/templateappconfig.pri) (3)

SOURCES += \
    main.cpp

unix {
    LIBS += -ldl
    QMAKE_CXXFLAGS += -DBOOST_LOG_DYN_LINK
}

macx {
    QMAKE_MAC_SDK= macosx
    QMAKE_CXXFLAGS += -fasm-blocks -x objective-c++
}

win32 {
    QMAKE_LFLAGS += /MACHINE:X64
    DEFINES += WIN64 UNICODE _UNICODE
    QMAKE_COMPILER_DEFINES += _WIN64
    QMAKE_CXXFLAGS += -wd4250 -wd4251 -wd4244 -wd4275

    # Windows Kit (msvc2013 64)
    LIBS += -L$$(WINDOWSSDKDIR)lib/winv6.3/um/x64 -lshell32 -lgdi32 -lComdlg32
    INCLUDEPATH += $$(WINDOWSSDKDIR)lib/winv6.3/um/x64

}

Now, just update the .pro file:

1 set the TARGET with the name of your application,
2 set the version number of your application,
3 check if the builddefs folder used to define the building pipeline is well referenced

Finally, click on Projects in the left menu of QTcreator, click on Run, set your working directory to the root directory of your project, and check Add build library search path to LD_LIBRARY_PATH if not already done.

 — Using Cmake instead of .pro QT file — 

Create a CMakeLists.txt file and copy the following code to it. This file use temporarily BCOMDEVROOT environment variable link to your SoLAR sources.

CMakeLists.txt
cmake_minimum_required(VERSION 3.7.2)

##################################################
project("MySolARApp") (1)
set (VERSION_NUMBER "x.x.x") (2)
set (SOURCES main.cpp)
##################################################

# various macros
include("$ENV{REMAKENDEVROOT}/SolARFramework/0.6.0/solarmacros.cmake") (3)
# config setup
setup()
# process packagedependencies.txt
processPackagedependencies()

# define the list of files to copy to build directory

set(FILES_TO_COPY
  # Copy framework and its dependencies binaries in your working folder (4)
	$ENV{BCOMDEVROOT}/thirdParties/boost/${BOOST_VERSION}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}boost_filesystem.${LIBEXTENSION}
	$ENV{BCOMDEVROOT}/thirdParties/boost/${BOOST_VERSION}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}boost_system.${LIBEXTENSION}
	$ENV{BCOMDEVROOT}/thirdParties/boost/${BOOST_VERSION}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}boost_timer.${LIBEXTENSION}
	$ENV{BCOMDEVROOT}/thirdParties/boost/${BOOST_VERSION}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}boost_log.${LIBEXTENSION}
	$ENV{BCOMDEVROOT}/thirdParties/boost/${BOOST_VERSION}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}boost_chrono.${LIBEXTENSION}
	$ENV{BCOMDEVROOT}/thirdParties/boost/${BOOST_VERSION}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}boost_thread.${LIBEXTENSION}
	$ENV{BCOMDEVROOT}/thirdParties/boost/${BOOST_VERSION}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}boost_date_time.${LIBEXTENSION}
	$ENV{BCOMDEVROOT}/thirdParties/xpcf/${XPCF_VERSION}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}xpcf.${LIBEXTENSION}
  $ENV{BCOMDEVROOT}/bcomBuild/SolARFramework/${SOLARFRAMEWORK_VERSION}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}SolARFramework.${LIBEXTENSION}

  # Copy module binaries in your working folder (5)
  $ENV{BCOMDEVROOT}/bcomBuild/"Module1"/${"MODULE1_VERSION"}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}"Module1".${LIBEXTENSION}
  $ENV{BCOMDEVROOT}/bcomBuild/"Module2"/${"MODULE2_VERSION"}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}"Module2".${LIBEXTENSION}

  # Copy binaries of the third parties of the modules in your working folder (6)
  $ENV{BCOMDEVROOT}/thirdParties/"Module1_Dependency"/${"MODULE1_DEPENDECY_VERSION"}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}"Module1_Dependency"${MODULE1_DEPENDECYVERSIONSUFFIX}.${LIBEXTENSION}
  $ENV{BCOMDEVROOT}/thirdParties/"Module2_Dependency"/${"MODULE2_DEPENDECY_VERSION"}/lib/x86_64/shared/${BUILDCONFIG}/${LIBPREFIX}"Module2_Dependency"${MODULE2_DEPENDECYVERSIONSUFFIX}.${LIBEXTENSION}
	)
# define targets (library, install and uninstall)
defineTargets("executable" "${FILES_TO_COPY}")

now, just update the CMakeLists.txt file:

1 replace the name of the project with the name of your application,
2 set the version number of your application,
3 check if the solarmacros.cmake file exists. This file must have been installed when you launched the installer. If you have decided to build the framework by yourself, this file must have been copied in your ${BCOMDEVROOT} folder when you have built and installed the SolARFramework project.
4 Change nothing here, the binaries required for the SolAR framework will be copied in your working directory.
5 Add the commands to copy the SolAR modules used by your application in you working directory. If they have been well installed, they should be stored in ${BCOMDEVROOT}/bcomBuild/$
6 Add the commands to copy the dependencies of the SolAR modules used by your application in you working directory. If they have been well installed, they should be stored in ${BCOMDEVROOT}/thirdParties/$
We recommend to maintain both a QT project file and a CMake file for any SolAR application.

Select your dependencies

Copy in your project folder the packagedependencies.txt file of the pipeline you want to use, and add a dependency to the pipeline:

packagedependecies.txt
xpcf|2.2.0|xpcf|artifactory|https://repository.b-com.com/amc-generic
spdlog|0.14.0|spdlog|thirdParties|https://github.com/SolarFramework/binaries/releases/download
eigen|3.3.5|eigen|thirdParties|https://github.com/SolarFramework/binaries/releases/download
SolARFramework|0.6.0|SolARFramework|github|https://github.com/SolarFramework/SolarFramework/releases/download
SolARModuleTools|0.6.0|SolARModuleTools|github|https://github.com/SolarFramework/SolARModuleTools/releases/download
SolARModuleOpenCV|0.6.0|SolARModuleOpenCV|github|https://github.com/SolarFramework/SolARModuleOpenCV/releases/download
opencv|3.4.3|opencv|thirdParties|https://github.com/SolarFramework/binaries/releases/download
(1)
MyPipeline|x.x.x|MyPipeline|artifactory|https://repository.b-com.com/amc-generic
1 Add the dependency to the pipeline you want to use, with its version number. artifactory refers to .remaken/packages/<yourCompiler>/ folder. You can create a REMAKENROOT variable. All process are made in this folder.

Configure your pipeline

Copy the configuration file provided with your pipeline in your project folder:

MyPipelineConfiguration.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<xpcf-registry autoAlias ="true">

<module uuid="94b21be9-703b-4a00-86a9-0db1bf70ef89" name="MyPipelineModule" path="$REMAKENROOT/MyPipeline/0.0.1/lib/x86_64/shared" description="MyPipelineModule">
  <component uuid="855c83b7-f4ec-48ab-8e89-56018ea9e169" name="MyPipeline" description="MyPipeline">
    <interface uuid="125f2007-1bf9-421d-9367-fbdc1210d006" name="IComponentIntrospect" description="IComponentIntrospect"/>
    <interface uuid="b5a6225e-6a91-4050-b298-886f4c17d9d2" name="IPipeline" description="IPipeline"/>
  </component>
</module>
<module uuid="15e1990b-86b2-445c-8194-0cbe80ede970" name="SolARModuleOpenCV" path="$REMAKENROOT/SolARModuleOpenCV/0.6.0/lib/x86_64/shared" description="OpenCV">
  <component uuid="5B7396F4-A804-4F3C-A0EB-FB1D56042BB4" name="SolARCameraOpencv" description="SolARCameraOpencv">
    <interface uuid="125f2007-1bf9-421d-9367-fbdc1210d006" name="IComponentIntrospect" description="IComponentIntrospect"/>
    <interface uuid="5DDC7DF0-8377-437F-9C81-3643F7676A5B" name="ICamera" description="ICamera"/>
  </component>
</module>
<module uuid="28b89d39-41bd-451d-b19e-d25a3d7c5797" name="SolARModuleTools" path="$REMAKENROOT/SolARModuleTools/0.6.0/lib/x86_64/shared" description="Module Tools">
  <component uuid="85db2f25-4f1c-4e06-9011-e020284bfc4f" name="SolARBasicSink" description="A Sink component for a synchronized pose and image pair">
    <interface uuid="125f2007-1bf9-421d-9367-fbdc1210d006" name="IComponentIntrospect" description="IComponentIntrospect" />
    <interface uuid="c0d9fee4-d7d7-4866-a6cd-3bacac23316a" name="ISinkPoseImage" description="An interface allowing to store a synchronized pose and image from the pipeline to make it available to a third party application" />
  </component>
  <component uuid="1e43cda9-7850-4a8a-a32b-f3f31ea94902" name="SolARBasicSource" description="A source component for feeding the pipeline with external images">
    <interface uuid="125f2007-1bf9-421d-9367-fbdc1210d006" name="IComponentIntrospect" description="IComponentIntrospect" />
    <interface uuid="06e2fc5d-39da-4486-b2a6-1d8bd788fa13" name="ISourceImage" description="An interface allowing to store an image from extern source to make it available to the pipeline" />
  </component>
</module>

<properties>
  <configuration component="SolARCameraOpencv">
    <property name="calibrationFile" type="string" value="camera_calibration.yml"/>
    <property name="deviceID" type="UnsignedInteger" value="0"/>
  </configuration>
</properties>

</xpcf-registry>

main.cpp

Copy yhe following code in your main.cpp file for testing your SolAR pipeline:

main.cpp
/**
 * information concerning the copyright and license of your SolAR application
 */

#include <boost/log/core.hpp>
#include "core/Log.h"
#include "xpcf/xpcf.h"


// ADD COMPONENTS HEADERS HERE, e.g #include "SolarComponent.h"
#include "PipelineManager.h"

using namespace SolAR;
using namespace SolAR::PIPELINE;

namespace xpcf  = org::bcom::xpcf;

#include "SolARModuleOpencv_traits.h"
#include "SolARImageViewerOpencv.h"
#include "SolAR3DOverlayBoxOpencv.h"

using namespace SolAR;
using namespace SolAR::MODULES::OPENCV;
using namespace SolAR::api;

int main(){

#if NDEBUG
    boost::log::core::get()->set_logging_enabled(false);
#endif

    LOG_ADD_LOG_TO_CONSOLE();
    SRef<xpcf::IComponentManager> componentMgr = xpcf::getComponentManagerInstance();
    componentMgr->load("MyPipelineConfiguration.xml");
    auto pipeline = componentMgr->resolve<pipeline::IPipeline>();

    (1)
    if (pipeline->init(componentMgr) == FrameworkReturnCode::_SUCCESS)
    {
        auto imageViewerResult = componentMgr->resolve<display::IImageViewer>();
        auto overlay3DComponent = componentMgr->resolve<display::I3DOverlay>();

        // Set camera parameters
        CameraParameters camParam = pipeline->getCameraParameters();
        overlay3DComponent->setCameraParameters(camParam.intrinsic, camParam.distorsion);

        unsigned char* r_imageData=new unsigned char[camParam.resolution.width * camParam.resolution.height * 3];
        SRef<Image> camImage=xpcf::utils::make_shared<Image>(r_imageData,camParam.resolution.width,camParam.resolution.height,SolAR::Image::LAYOUT_BGR,SolAR::Image::INTERLEAVED,SolAR::Image::TYPE_8U);

        Transform3Df s_pose;

        if (pipeline->start(camImage->data()) == FrameworkReturnCode::_SUCCESS)
        {
            while (true)
            {
                Transform3Df pose;

                sink::SinkReturnCode returnCode = pipeline->udpate(pose);
                if(returnCode==sink::SinkReturnCode::_ERROR)
                    break;

                if ((returnCode == sink::SinkReturnCode::_NEW_POSE))
                {
                    for(int i=0;i<3;i++)
                         for(int j=0;j<3;j++)
                             s_pose(i,j)=pose(i,j);
                    for(int i=0;i<3;i++)
                             s_pose(i,3)=pose(i,3);
                    for(int j=0;j<3;j++)
                        s_pose(3,j)=0;
                    s_pose(3,3)=1;
                    overlay3DComponent->draw(s_pose, camImage);
                }

                if (imageViewerResult->display(camImage) == SolAR::FrameworkReturnCode::_STOP){
                    pipeline.stop();
                    break;
                }
             }
        }
        delete[] r_imageData;
    }
}
1 [white]#when you will load your pipeline, fill in the path to its configuration file and its UUID (the UUID of the component representing the pipeline available in the configuration file).
On QT Creator, do not forget to run qmake before building your application.

Build and run your application.