diff --git a/CMakeLists.txt b/CMakeLists.txt
index a844f5ec..6064f23e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,6 +5,7 @@
cmake_minimum_required (VERSION 3.20)
PROJECT(DGtalTools)
+cmake_minimum_required (VERSION 3.11)
cmake_policy(SET CMP0057 NEW) # the new interpretation of IN_LIST is by default not set (at least until 3.21.1).
LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
diff --git a/volumetric/CMakeLists.txt b/volumetric/CMakeLists.txt
index 8548bd36..6387fb8f 100644
--- a/volumetric/CMakeLists.txt
+++ b/volumetric/CMakeLists.txt
@@ -16,6 +16,7 @@ SET(DGTAL_TOOLS_SRC
volFillInterior
volInfo
volMask
+ volEuclideanDT
)
diff --git a/volumetric/volEuclideanDT.cpp b/volumetric/volEuclideanDT.cpp
new file mode 100644
index 00000000..1a7b9cea
--- /dev/null
+++ b/volumetric/volEuclideanDT.cpp
@@ -0,0 +1,203 @@
+/**
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ **/
+
+/**
+ * @file volEuclideanDT.cpp
+ * @author David Coeurjolly (\c david.coeurjolly@liris.cnrs.fr )
+ * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
+ *
+ * @date 2021/01/25
+ *
+ *
+ * This file is part of the DGtal library.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "DGtal/geometry/volumes/distance/PowerMap.h"
+#include "DGtal/geometry/volumes/distance/ReducedMedialAxis.h"
+#include "DGtal/geometry/volumes/distance/ExactPredicateLpPowerSeparableMetric.h"
+
+#include
+
+
+using namespace std;
+using namespace DGtal;
+using namespace Z3i;
+
+
+/**
+ @page volEuclideanDT volEuclideanDT
+
+ @brief Tool to compute and output Euclidean distance related quantitites (the distance transform, the Voronoi map, the RDMA...).
+
+
+ @b Usage: ./volumetric/volEuclideanDT [OPTIONS] 1 [2]
+
+
+ @b Allowed @b options @b are :
+ @code
+
+ @endcode
+
+ @b Example:
+
+ @see
+ @ref volEuclideanDT.cpp
+
+ */
+
+template
+struct functorCast{
+
+ unsigned char operator()(const T &v) {return v%256;}
+};
+
+
+/**
+ * Missing parameter error message.
+ *
+ * @param param
+ */
+void missingParam ( std::string param )
+{
+ trace.error() <<" Parameter: "< --o ");
+
+ std::string inputFileName;
+ app.add_option("-i,--input,1", inputFileName, "Input vol file." )->required()->check(CLI::ExistingFile);
+ std::string outputFileName;
+ app.add_option("-o,--output,2", outputFileName, "Output filename.",true);
+
+ std::string mode="edt";
+ app.add_option("-m,--mode", mode, "Export mode for the distance: {edt (remappred distances to the [0:255] range),sedt (exact square of distances as longvol),voronoi (Voronoi map using hash value per cell), rdma (centre of maximal balls)} (default:edt)", true)-> check(CLI::IsMember({"edt", "sedt", "voronoi", "rdma"}));
+
+ app.get_formatter()->column_width(40);
+ CLI11_PARSE(app, argc, argv);
+
+
+ trace.beginBlock("Loading file");
+ typedef ImageContainerBySTLVector Image;
+ Image image = VolReader< Image >::importVol ( inputFileName );
+ trace.info()< Predicate;
+ Predicate aPredicate(image,0);
+ DistanceTransformation dt(image.domain(), aPredicate, Z3i::l2Metric);
+ trace.info()<::max();
+ for(auto v: dt.constRange())
+ {
+ valMax=std::max(valMax,v);
+ valMin=std::min(valMin,v);
+ }
+
+ if (mode == "edt")
+ {
+ Image output(image.domain());
+ for(auto &voxel: image.domain())
+ {
+ auto val = dt(voxel);
+ unsigned char valC = static_cast( 255*(val+valMin)/(valMax-valMin) );
+ output.setValue(voxel, valC);
+ }
+ VolWriter::exportVol(outputFileName, output);
+ }
+ else
+ if (mode == "sedt")
+ {
+ ImageContainerBySTLVector output(image.domain());
+ for(auto &voxel: image.domain())
+ {
+ auto val = l2Metric.rawDistance(voxel, dt.getVoronoiVector(voxel));
+ output.setValue(voxel, val);
+ }
+ size_t lastindex = outputFileName.find_last_of(".");
+ std::string rawname = outputFileName.substr(0, lastindex);
+ LongvolWriter< ImageContainerBySTLVector>::exportLongvol(rawname+".longvol", output);
+ }
+ else
+ if (mode == "voronoi")
+ {
+ auto myhash=[](const Z3i::Point &p){return (((p[0])*43 + p[1]*1777)*123 + p[2]) % 256;};
+ Image output(image.domain());
+ for(auto &voxel: image.domain())
+ {
+ auto site = dt.getVoronoiVector(voxel);
+ unsigned char v=0;
+ if (site == voxel)
+ v = 0;
+ else
+ v = myhash(site);
+ output.setValue(voxel, v);
+ }
+ VolWriter::exportVol(outputFileName, output);
+ }
+ else
+ if (mode == "rdma")
+ {
+ typedef ImageContainerBySTLVector ImageLong;
+ ImageLong rawDT(image.domain());
+ for(auto &voxel: image.domain())
+ {
+ auto val = l2Metric.rawDistance(voxel, dt.getVoronoiVector(voxel));
+ rawDT.setValue(voxel, val);
+ }
+ PowerMap powermap(rawDT.domain(), rawDT, l2PowerMetric);
+ ReducedMedialAxis >::Type rdma = ReducedMedialAxis< PowerMap >::getReducedMedialAxisFromPowerMap(powermap);
+ auto cpt2=0;
+ for(auto v: dt.constRange())
+ if (v!=0) cpt2++;
+ auto cpt=0;
+
+ Image out(image.domain());
+ std::vector> ma;
+ for(auto &voxel: rdma.domain())
+ {
+ out.setValue(voxel, rdma(voxel) % 256);
+ if (rdma(voxel) != 0)
+ ma.push_back( std::pair(voxel ,std::sqrt(rdma(voxel))) );
+ }
+ VolWriter::exportVol(outputFileName, out);
+ }
+ return 0;
+}