Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 58 additions & 21 deletions apps/mm-viewer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <mrpt/config.h>
#include <mrpt/config/CConfigFile.h>
#include <mrpt/core/round.h>
#include <mrpt/io/CCompressedInputStream.h>
#include <mrpt/math/TObject3D.h>
#include <mrpt/math/geometry.h>
#include <mrpt/opengl/CArrow.h>
Expand All @@ -30,6 +31,7 @@
#include <mrpt/opengl/CPointCloudColoured.h>
#include <mrpt/opengl/stock_objects.h>
#include <mrpt/poses/CPose3DInterpolator.h>
#include <mrpt/serialization/CArchive.h>
#include <mrpt/system/filesystem.h>
#include <mrpt/system/os.h> // loadPluginModules()
#include <mrpt/system/string_utils.h> // unitsFormat()
Expand Down Expand Up @@ -158,42 +160,75 @@ bool loadMapFile(const std::string& mapFile)
// Load one single file:
std::cout << "Loading map file: " << mapFile << std::endl;

std::string loadErrorMsg;
theMap = mp2p_icp::metric_map_t(); // reset

if (!theMap.load_from_file(mapFile, loadErrorMsg))
if (mrpt::system::extractFileExtension(mapFile) == "bin")
{
bool retry_was_successful = false;

// If it fails and it's because of a missing plugin, try to load plugins to make life of
// users easier:
if (loadErrorMsg.find("which is not registered") != std::string::npos &&
!arg_plugins.isSet())
// Load as externally-stored CGenericPointsMap via CCompressedInputStream
try
{
std::cout << "The map file requires plugins for missing C++ classes.\n"
"Trying to load 'libmola_metric_maps.so' and retrying.\n"
"Note that you can directly use '-l libmola_metric_maps.so' or any other "
"custom plugin next time.\n";

if (!load_plugins("libmola_metric_maps.so"))
mrpt::io::CCompressedInputStream f(mapFile);
auto arch = mrpt::serialization::archiveFrom(f);
mrpt::serialization::CSerializable::Ptr obj = arch.ReadObject();
auto pts = std::dynamic_pointer_cast<mrpt::maps::CPointsMap>(obj);
if (!pts)
{
std::cerr << "Error: .bin file did not deserialize to a CPointsMap-derived object"
<< (obj ? std::string(" (got: ") + obj->GetRuntimeClass()->className + ")"
: std::string(" (null object)"))
<< std::endl;
return false;
}
// Retry:
retry_was_successful = theMap.load_from_file(mapFile, loadErrorMsg);
const std::string layerName = mrpt::system::extractFileName(mapFile);
theMap.layers[layerName] = pts;
}

if (!retry_was_successful)
catch (const std::exception& e)
{
std::cerr << "Error loading metric map from file!:\n" << loadErrorMsg << std::endl;
std::cerr << "Error loading .bin file: " << e.what() << std::endl;
return false;
}
}
else
{
std::string loadErrorMsg;

if (!theMap.load_from_file(mapFile, loadErrorMsg))
{
bool retry_was_successful = false;

// If it fails and it's because of a missing plugin, try to load plugins to make life of
// users easier:
if (loadErrorMsg.find("which is not registered") != std::string::npos &&
!arg_plugins.isSet())
{
std::cout
<< "The map file requires plugins for missing C++ classes.\n"
"Trying to load 'libmola_metric_maps.so' and retrying.\n"
"Note that you can directly use '-l libmola_metric_maps.so' or any other "
"custom plugin next time.\n";

if (!load_plugins("libmola_metric_maps.so"))
{
return false;
}
// Retry:
retry_was_successful = theMap.load_from_file(mapFile, loadErrorMsg);
}

if (!retry_was_successful)
{
std::cerr << "Error loading metric map from file!:\n" << loadErrorMsg << std::endl;
return false;
}
}
}

theMapFileName = mapFile;

// Obtain layer info:
std::cout << "Loaded map: " << theMap.contents_summary() << std::endl;

layerNames.clear();
for (const auto& [name, map] : theMap.layers)
{
layerNames.push_back(name);
Expand Down Expand Up @@ -777,8 +812,10 @@ void main_show_gui()
{
try
{
const auto fil =
nanogui::file_dialog({{"mm", "Metric maps (*.mm)"}}, false);
const auto fil = nanogui::file_dialog(
{{"mm", "Metric maps (*.mm)"},
{"bin", "Serialized CGenericPointsMap (*.bin)"}},
false);
if (fil.empty())
{
return;
Expand Down
22 changes: 18 additions & 4 deletions docs/source/app_mm-viewer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,31 @@
Application: ``mm-viewer``
===============================

Write me!
GUI application to visualize metric map files (``.mm``).

Supported input file types
--------------------------

- **Metric map files** (``.mm``): the native mp2p_icp format, containing one or
more named layers of arbitrary map types.

- **Binary point cloud files** (``.bin``): files containing an externally-stored
``mrpt::maps::CGenericPointsMap``-derived object, serialized with MRPT's
``CCompressedInputStream`` (supports uncompressed, gzip, and zstandard formats).
The deserialized cloud is loaded as a single layer named after the file stem.

Usage
-----

.. code-block:: bash

USAGE:
USAGE:

mm-viewer [-s <scene.3dscene>] ... [-t <trajectory.tum>] [-l
<foobar.so>] [--] [--version] [-h] <myMap.mm>


Where:
Where:

-s <scene.3dscene>, --add-3d-scene <scene.3dscene> (accepted multiple
times)
Expand All @@ -36,6 +50,6 @@ Write me!
Displays usage information and exits.

<myMap.mm>
Load this metric map file (*.mm)
Load this metric map file (``*.mm``) or binary point cloud (``*.bin``)


Loading