Create an application project

QT Creator

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

App wizard QT
  • 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 and the result is a .pro file like following:

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 install_recurse
#NOTE : CONFIG as staticlib or sharedlib, DEPENDENCIESCONFIG as staticlib or sharedlib, recurse install or install_recurse (do same thing) are use to install dependencies of dependencies, QMAKE_TARGET.arch and PROJECTDEPLOYDIR MUST BE DEFINED BEFORE templatelibconfig.pri inclusion
include ($$shell_quote($$shell_path($$(REMAKEN_RULES_ROOT)/qmake/templateappconfig.pri)))
 (3)

DEFINES += BOOST_ALL_DYN_LINK
DEFINES += BOOST_AUTO_LINK_NOMANGLE
DEFINES += BOOST_LOG_DYN_LINK

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

}

DISTFILES += \
    conf_mySolARApp.xml

#NOTE : Must be placed at the end of the .pro
include ($$shell_quote($$shell_path($$(REMAKEN_RULES_ROOT)/qmake/remaken_install_target.pri))))
# Shell_quote & shell_path required for visual on windows

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.

Visual Studio

You can also simply create your application with Visual Studio by using the .pro file (see above for more details how to configure the .pro file).

Microsoft Visual Studio provides a Qt Visual Studio Tools. This enables developers to import QT project files (.pro) into Visual Studio.

Install QT Visual Studio Tools:

  • In Visual Studio, select Tools > Extensions and Updates > Online to install and update QT Visual Studio Tools.

Import the .pro. file into Visual Studio:

  • Select Qt VS Tools > Open Qt Project File (.pro) and choose your .pro file.

Right now, your project is configured.

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
SolARFramework|0.7.0|SolARFramework|github|https://github.com/SolarFramework/SolarFramework/releases/download
(1)
OtherDependency|version x.x.x|OtherDependency|Where|urlToIt
1 Add the dependency to the pipeline you want to use, with its version number.

More documentation here : Remaken is a dependencies manager. https://github.com/b-com-software-basis/remaken It manages your third parties and it creates a REMAKEN_RULES_ROOT env. variable.

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="$REMAKEN_PKG_ROOT/packages/SolARBuild/win-cl-14.1/MyPipeline/x.x.x/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="$REMAKEN_PKG_ROOT/packages/SolARBuild/win-cl-14.1/SolARModuleOpenCV/0.7.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="$REMAKEN_PKG_ROOT/packages/SolARBuild/win-cl-14.1/SolARModuleTools/0.7.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 the 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) || (returnCode == sink::SinkReturnCode::_NEW_POSE_AND_NEW_IMAGE))
                {
                    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 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).
Don’t forget to re-run qmake before building your application for QT Creator and re-import .pro file for Visual Studio.

Build and run your application.