SCENE C++ API  2.1.0
Frequently Asked Questions

Table of Contents

What is the required knowledge for API development?

  • You must have a solid understanding of object-oriented programming, especially:
    • how to read and write C++ 14 (or later), and
    • how memory management in modern C++ works.
  • You must understand native application development for Microsoft Windows.
    • We only support the Visual Studio C++ compiler.
    • You must know how to link/include precompiled third-party libraries.
    • You must understand the concepts of writing DLLs and how runtime dependencies are resolved.
  • If your project requires custom user interfaces, you need the knowledge how to implement and integrate those.
    • This is not part of the SCENE API.
  • You need an understanding of data workflows with SCENE, e.g. data model, data structures and processing concepts.

Where can I find the API documentation?

There is a web site with this documentation: http://developer.faro.com/

An offline version of this documentation is included with the API developer packages.

Part of that documentation is also available in the header files of the API itself. All methods and parameters are documented briefly.

Where can I download the API runtime or developer packages?

There is no dedicated download page for the API because you need to sign the NDA before you get access. Please contact customer service to get the download link for the latest version.

How do I report bugs/problems with the API?

Please, provide an up-to-date, minimal, complete, and working example project including source code together with any required additional files, information, or instructions.

Include the following information:

  1. Up-To-Date: We can only support the latest released SCENE and API versions. Make sure to reproduce your problem in the latest released versions of API and, if applicable, in the latest version of SCENE before contacting us.
  2. Minimal: Prepare an example reproducing your problem with a minimum required source code. We have to reject requests which would require us to debug through larger applications.
  3. Complete: We need all files to compile and run your example, and to reproduce the problem and help you. We have to reject requests if the provided example fails to fulfill this requirement.
  4. Working: Your example has to work in general, to reproduce the problem. We have to reject requests which are based on general C++ mistakes. We have to assume you are proficient in the C++ programming language
  5. Additional files/data: If your issue is only reproducible by specific data sets, please provide the minimal required set of those as well.
  6. Used Tools and Environment:
    • Which API developer package did you use? Make sure you reproduced the issue in the newest version available.
    • What compiler/IDE did you use?
    • What operating system and which system language?
    • Did you install all required runtimes?
  7. Instructions: Describe the process required to reproduce the problem with your example application. Be precise and do not skip any steps.

Upload it to some file hoster that does not require an account and send us the link together with the description. You can take one of the examples in the developer packages, strip away everything that is not needed and add the code that reproduces your problem or the bug.

You can contact the FARO support here: https://www.faro.com/about-faro/contact/request-support/

I tried to use the registration or processing functions but get an Unauthorized error! How can I use restricted API features (for example point cloud rendering or registration)?

Some functions are restricted and are only available for plugin apps running in a licensed version of SCENE. This means they are not available when running your app in SCENE LT!

The same applies to Standalone apps. However, for licensed partners of FARO, it is possible to unlock the restricted features in the Standalone API. Please contact your official API support channels for the licensing conditions of an API key that will unlock one or more restricted features.

An API key can unlock one, multiple, or all of the restricted features. Once you have received an API key you, have to use it as an argument in the constructor of the Standalone API context.

Please keep in mind that the API key is different from the license key used for the old FARO LS SDK.

How do I get an API key?

API keys need to be approved by the SCENE product management and the SCENE product owner. To get approval please submit a list of required features and a description of the use case to them for review. Once they have approved the request, your API key will be generated and send to you.

You need to provide the following information:

  • List of the included features
  • Full name of your company/institution
  • Contact person (full name and valid email address)

Is there a 32bit version of the API?

Our Software only supports 64bit operating systems. We do not plan to reintroduce 32bit support.

Is there a Linux version of the API?

No Linux version is available. For some simple Standalone API use cases, it might be possible to use Wine.

My program crashes in Debug builds

The API development libraries and runtime are only designed for 64bit Release builds. If you mix them with Debug builds we can not guarantee correct behavior.

How do I deploy an app based on the Standalone API?

There are two options:

  1. You can include all the required runtime DLLs and deploy them directly with your application. This means that your application will always the version of the API runtime that you bundled with it. This is easy to deploy but inflexible because your users cannot switch easily to a newer runtime without redeploying your application. This is for example a problem because when you are unable to load project files from newer SCENE versions with your application (without redeploying it).
  2. The second option is to use the WinSxS/Side-by-Side mechanism. To achieve this, you must instrument your application with a manifest that tells it to look for the runtime DLLs in a special Windows folder. If the runtime is not installed, your application will not start and display an error message. But if one or more versions of the runtime are installed, your application will automatically load and use the latest available API runtime. This means you can just install the latest API runtime and your standalone application will be automatically compatible with the latest SCENE file format without the need for redeployment.

We suggest using Side-by-Side, but also include a silent install of an API runtime in your installer. Your program will work without the need for explicitly installing runtimes, and it has the option to use any newer runtime that. Such runtime updates can be installed at any time, even before your installer runs. FARO also included the corresponding API runtime installer in SCENE installers starting with version 2019.0. This means every standalone app using Side-by-Side will be made automatically compatible with newer SCENE versions just by installing the latest SCENE version.

If you choose to deploy the DLLs bundled together with your application, please keep in mind that the DLLs alone are not enough. To properly work, they also require Visual Studio runtimes. All the required VC++ runtimes are included in the bin folder of your Standalone API developer package installation. The Standalone API contains third-party code which requires different runtime versions, which is not under our control.

Also, keep in mind that the correct way of getting all required DLLs is to copy all of them directly from the WinSxS folder after you installed the runtime. Do not try to extract them from the MSI installer archive directly. This will not work since the MSI archives do not use the final DLL file names.

How can users of standalone apps update the API runtime? Is an installation of SCENE required?

Since version 2019.0 the SCENE installer contains the runtime for the C++ Standalone API, so if the user installs the latest SCENE version he automatically also installs the new runtime. To update the API runtime without installing SCENE you have to install the "SCENE Redistributable Package" on your clients system. This MSI installer is currently only distributed as part of our Standalone API developer package. You can redistribute this MSI to your users. Please keep also in mind that a newer version does not update/replace/modify the existing runtime. It will just install it as an additional version side by side. Your application should then automatically use the latest installed version on the next start.

What about project compatibility between different Standalone API and SCENE versions?

Every SCENE and Standalone API version is able to load projects from older SCENE versions

SCENE projects saved with different patch version of the same SCENE or API version are compatible

SCENE 2019.2 / Standalone API 2.0.21 and newer will be able to open projects saved by future versions of SCENE. Some limitations will apply. We cannot guarantee all data objects will stay compatible, or that there will be no data loss when saving revisions in older versions of SCENE / Standalone API.

My Standalone app behaves weird/crashes/does not work when creating multiple API contexts

We do not support multiple contexts in parallel. We also do not recommend creating contexts one after the other. Internal data objects might fall into invalid states. Create one context per application instance and keep it until the application is closed.

If you want a new fresh and clean context for each task without worrying about side effects you should think about moving your SCENE API tasks into a separate process. This introduces some overhead but is also more robust and can protect your application from API issues and side effects, including crashes.

Can I load and work with multiple projects at the same time in one API context?

The SCENE API does not support working with multiple parallel projects.

It may work for some simple use cases, but many features will probably cause problems and side effects. Since this is an unsupported scenario, we will not support you on any problems, if your application does load multiple projects.

Is the SCENE C++ API multi-threaded?

No. All API function calls should originate from one, main thread.

Internally, both SCENE and the standalone runtime are implemented with multi-threading. For example, the colorization of scans during processing, some parts of the registration, or the creation of project point clouds are multi-threaded. Callbacks from events might therefore be triggered from other threads. Within callback functions, we advise you to sync with your main thread, or, even better, queue your actions and execute any API calls later from the main thread.

What units are returned by the API?

We use the metric system, so distances are always in meters.

Where can I find a list of attributes available in the API?

The attributes are not considered to be part of the stable API. They might change between different SCENE versions. As such, we do not maintain documentation of the attributes.

If you work with attributes, make sure your code contains robust error handling.

How can I get the 3D position of an object?

Eigen::Vector4d posLocal = {0, 0, 0, 1};
Eigen::Matrix4d localToGlobal = object->getTransformationToGlobal();
Eigen::Vector4d posGlobal = localToGlobal * posLocal;

Note that you need to work in 4D homogeneous coordinates, even though you are only interested in 3D coordinates.

What is the difference between global coordinates and local coordinates?

The object hierarchy in SCENE and the API models also a hierarchy of relative coordinates. The coordinates of each object, if not stated otherwise, are considered local coordinates, i.e. coordinates relative to the coordinate system frame of that specific object.

In order to compute global coordinates, local coordinates must be multiplied with the transformation matrices of all objects from the current object to the root of the object hierarchy. The function getTransformationToGlobal provides the combined transformation matrix for this purpose. In the context of computer graphics, this can be seen as a "model matrix".

In contrast, accessing the Transformation attribute (not recommended) would only provide you with a matrix transforming local coordinates of this object into local coordinates in the coordinate system reference frame of the direct parent object.

Example:

Assuming an object, e.g. a scan, obj, which is placed in the default cluster scans, which is directly located under the project root.

ref_ptr<LSObject> obj = /* got from somewhere*/;
ref_ptr<LSObject> scans = obj->getParent();
ref_ptr<LSObject> root = scans->getParent();
// ref_ptr<LSObject> root = workspace->getRootObject(); accesses the same object
// root->getParent() should return nullptr

The following two matrices will be identical:

Eigen::Matrix4d objMat = obj->getTransformationToGlobal();
Eigen::Matrix4d objMat2
= root->getAttribute(L"Transformation").getValue<Eigen::Matrix4d>()
* scans->getAttribute(L"Transformation").getValue<Eigen::Matrix4d>()
* obj->getAttribute(L"Transformation").getValue<Eigen::Matrix4d>();

Note, the order and direction of matrix multiplications is important in linear algebra.

I have a problem when using workspaces

Workspaces are a deprecated feature, which was replaced in SCENE with projects. The API provides some workspace features to not break binary compatibility with older app versions. Newer programs built on the API should use only projects.

I want to write a new program that uses only projects and no workspace. What is the corresponding equivalent to getSceneWorkspace()? The examples only show how to load projects. How can I access an already loaded project?

See LSSceneContext::getSceneWorkspace(). The resulting point may be cast to an LSProject pointer using dynamic_pointer_cast.

ref_ptr<LSWorkspace> workspace = context->getSceneWorkspace();
if (!workspace) handleNoWorkspace();
ref_ptr<LSProject> project = dynamic_pointer_cast<LSProject>(workspace);
if (!project) handleNoProject();

My Standalone API based software does not start on Windows Server installations

We do not officially support Windows Server, only the Windows versions that are also supported by SCENE.

Windows server installations do not include the wlanapi.dll by default, which is needed by our Standalone API runtime. Please install and start the "Wireless LAN Service" manually to get this DLL.

Windows server installations do not include the mf.dll by default, which is needed by our Standalone API runtime. Please install the "Desktop Experience" manually to get this DLL.

How can I get the currently selected scan(s)?

auto selectedObjects = project->getSelectedObjects().get();
for (auto& obj : selectedObjects)
{
LSString type = obj->getTypeName();
if (type == L"LSScan")
doSomething();
}

Which steps are required to create and process a SCENE project programmatically?

  1. Create a SCENE context with your API key - LSStandaloneContext context(apiKey)
  2. Create new empty project - LSProject::createProject()
  3. Open the new project - LSProject::loadProject()
  4. Set current project - context.setCurrentWorkspace(project)
  5. Import the scans - LSProject::importData()
  6. Trigger first load processing by saving – LSProject::saveRevision()
  7. Trigger processing for each scan, requires an API key - processScan()
  8. Get the project root object – LSProject::getRootObject()
  9. Get the top level cluster over the root object - LSObject::getChild(L"Scans")
  10. Trigger registration on the cluster object, requires an API key - registerCluster()
  11. Save the project again – LSProject::saveRevision()
  12. Create a project point cloud – LSProject::createPointCloud()

How can I start a (C2C, TopView, Target) registration?

The registration functions are protected and can only be used with a licensed SCENE or Standalone API with a valid API key. They are briefly documented in the header file lsprocessing.h. Here is an example to register a typical SCENE project with Top View registration:

ref_ptr<LSObject> root = project->getRootObject();
ref_ptr<LSObject> cluster = root->getChild(L"Scans");
bool topViewResult = false;
registerCluster(*cluster, RegistrationMethod::RM_TopViewBased, topViewResult);

If that finished successfully you should have a coarse registration and can then run registerCluster() again with Cloud-To-Cloud settings to get a proper fine registration.

Please keep in mind, that this works for most scenarios. People may rename/delete the default cluster or use additional clusters. Then this code must be extended to include those as well.

I have problems loading/saving/exported imported (E57) scans!

If you import non-FARO scans into SCENE, they will be loaded during import and cannot be unloaded until the project was saved and the scans were persisted on disk. In the API such scans can cause problems (of which many are fixed in newer versions of the API). The best workaround is to save the project before you interact with such scans in any way over the API.

I tried to load the API dynamically during runtime but it does not work on some systems!

We have heard of some instances where there is a conflict caused by the "OpenCL Runtimes for Intel Processors" or the “Intel Xeon CPU OpenCL platform". If you don't want to link against the API or load it only when needed you should consider using a separate process for the API-related code.