What is FlowEngine?

FlowEngine is the perfect photogrammetry Software Development Kit: a powerful, fully customizable photogrammetry reconstruction engine written in C++ for Microsoft Windows and GNU/Linux platforms. FlowEngine is also 100% compatible and tested in VFX Reference Platform environments.With FlowEngine, you are free to develop your own 3D reconstruction application, powered by our world class, powerful state of the art technology. Our own flagship product, 3DF Zephyr, runs the exact same technology that powers FlowEngine.

With FlowEngine, 3Dflow’s SDK, capturing reality using photogrammetry has never been easier.

How does it work?

FlowEngine comes as a dynamic link library. All the necessary interfaces are written in C++ and are very easy to use.

You can control the full reconstruction pipeline, from the structure from motion phase to the mesh and texturing. Settings can be passed directly or can be read and written using XML files, which are also 100% compatible with 3DF Zephyr.

Just download the free version below – no registration required – or contact us for a quotation in case you need commercial licensing.

 

Windows & Linux
Full photogrammetry pipeline
Photos in input
Export capabilities
Licensing

FlowEngine Free

Windows & Linux
Full photogrammetry pipeline
Photos in input : limited to 50 images per project
Export capabilities : export in .3DK for 3DF Zephyr
Licensing: personal, non commercial
Windows & Linux
Full photogrammetry pipeline
Photos in input : no input limitations
Export capabilities : .3DK and direct memory access
Licensing: commercial licensing available

You can find the most recent FlowEngine SDK documentation at the following URL: https://www.3dflow.net/flowengine/documentation/

Below, a quick start example that covers the full 3D reconstruction

using namespace FlowEngine;
// Setup settings
UniqueSettingsPtr settings(CreateSettings());
if (argc > 1) // Try to load the xml from file
settings->load(argv[1]);
// Prepare the progress bar
FlowEngine::ProgressBarEmpty progressBar;
// Prepare the log listener to let the application write the log to file
FlowEngine::LogListenerOStream logListener;
std::ofstream myfile(“log.txt”);
if (myfile.good())
logListener.mFileStream = &myfile;
// Prepare data to be filled
std::vector< UniqueCameraPtr > cameras;
UniqueSparsePointCloudPtr sparsePointCloud(CreateSparsePointCloud());
UniqueStereoPointCloudPtr stereoPointCloud(CreateStereoPointCloud());
UniqueStereoMeshPtr stereoMesh(CreateStereoMesh());
UniqueStereoTexturedMeshPtr stereoTexturedMesh(CreateStereoTexturedMesh());
// Load all the cameras in the folder
std::string imagesPath;
imagesPath.resize(settings->getValueLength(“Workspace”, “ImagesPath”));
settings->getValue(“Workspace”, “ImagesPath”, imagesPath);
UniqueCamerasLoaderPtr camerasLoader(CreateCamerasLoader());
for (Size i = 0; i < camerasLoader->getImageCount(imagesPath); ++i)
cameras.emplace_back(CreateCamera());
CheckResult(camerasLoader->loadImages(imagesPath, true, cameras), logListener);
// Main flowengine object
FlowEnginePtr flowengine(CreateFlowEngineObject());
// Compute Structure from motion
CheckResult(flowengine->computeStructureAndMotion(*settings, progressBar, logListener, cameras, *sparsePointCloud), logListener);
// Compute the bounding box
UniqueBoundingBoxPtr boundingBox(CreateBoundingBox());
CheckResult(boundingBox->computeFromPoints(*sparsePointCloud, true), logListener);
// Compute Dense point cloud with Multiview Stereo procedure
CheckResult(flowengine->computeDensePointCloud(*settings, progressBar, logListener, *boundingBox, cameras, *sparsePointCloud, *stereoPointCloud), logListener);
// Compute Mesh
CheckResult(flowengine->computeMesh(*settings, progressBar, logListener, *boundingBox, cameras, *stereoPointCloud, *stereoMesh), logListener);
// Finally compute the textured mesh
CheckResult(flowengine->computeTexturedMesh(*settings, progressBar, logListener, cameras, *stereoMesh, *stereoTexturedMesh), logListener);
// Export output as .obj
UniqueWorkspaceSaverPtr workspaceSaver(CreateWorkspaceSaver());
CheckResult(stereoTexturedMesh->saveToObj(“test.obj”), logListener);